چند روزی بود که یکی از مشتریان ما از سرعت پایین انجام عملیات ها در نرم افزار شکایت میکرد. طبق روال گذشته احتمال می دادیم که مشکلی در شبکه باعث کندی نرم افزار شده است و امیدوار بودیم که به زودی حل شود. انتظار ما این بار اما، بیهوده بود و به زودی به روزی رسیدیم که دیگر هیچ عملیات موفقی در نرم افزار انجام نمیشد. در واقع بررسی ما نشان داد که هرگونه عملیات درج و بروزرسانی در پایگاه داده با شکست مواجه میشود. با توجه به حساسیت نرم افزار مجال اتلاف وقت نبود و باید خیلی سریع کاری میکردیم. میدانستیم که حجم دیتابیس و لاگ آن خیلی بالاست اما دلیلی نداشتیم که آن را علت مشکل بدانیم. در ابتدا به علت فشاری که برای راه اندازی مجدد نرم افزار و بازگرداندن آن به حالت عادی داشتیم راه حلهای مختلف اما ناکارایی را برنامه ریزی کردیم، اما خیلی زود به این نتیجه رسیدیم که تقریبا همه آنها علاج بدتر از بیماری هستند. لذا با کمی جسارت یک راه دستی برای انجام بخشی از امور نرم افزار را پیشنهاد کردیم و سپس با فراغ بال به رفع مشکل پرداختیم.
اولین قدم برای رفع مشکل شناسایی آن بود و بهترین راه شناسایی مشکل رجوع به لاگهای خطا بود. در قدم اول لاگهای پایگاه داده را بررسی کردیم و در بررسی آنها متوجه شدیم که خطایی اخیراً به طور مکرر در سیستم ثبت شده است.
SQL SERVER – ERROR: AUTOGROW OF FILE ‘DB_LOG’ IN DATABASE ‘DB’ WAS CANCELLED BY USER OR TIMED OUT AFTER 30121 MILLISECONDS
جستجو در مورد خطای پایگاه داده ما را به روش درست حل مشکل راهنمایی کرد و مشکلی که انتظار داشتیم با زحمت فراوان و احتمالا مدت زمان زیادی قابل حل شدن باشد به سرعت و با انجام تغییرات کوچکی در پایگاه داده مرتفع شد. اما مشکل از کجا بود و سرانجام چگونه آن را حل کردیم؟
همانطور که میدانید پایگاه داده SQL Server برای هر دیتابیس یک فایل دیتا با پسوند mdf و یک فایل لاگ با پسوند ldf ایجاد میکند. در صورتی که از مکانیزم پشتیبانگیری لاگ استفاده نکنید (که ما در این مورد استفاده نمیکردیم و بعد از این قضیه آن را انجام دادیم) حجم فایل لاگ به طور صعودی افزایش پیدا میکند. این فایلها با اندازه مشخص اولیه ای در زمان ساختن دیتابیس ایجاد میشوند و سپس براساس نرخ رشد معینی افزایش حجم میدهند. این نرخ رشد به طور پیشفرض برای فایل دیتا 1MB و برای فایل لاگ به صورت درصدی و برابر 10% است که معمولاً توسط مدیران دیتابیس به صورت پیشفرض و بدون تغییر پذیرفته میشوند (مقادیر پیشفرض به ندرت مقادیر بهینه هستند). در واقع نرم افزار پایگاه داده هرگاه که نیاز به افزایش حجم داشته باشد درخواست خود را به سیستم عامل میدهد و سپس برای دریافت فضای درخواستی منتظر می ماند در صورتی که در مدت زمان مشخصی که به طور پیشفرض حدود 30 ثانیه است فضای درخواست شده را از سیستم عامل دریافت نکند درخواست را پایان میدهد و عملیات درخواستی کلاینت را نیز با شکست مواجه میکند. زمانی که سیستم عامل نیاز دارد تا فضای درخواستی SQL Server را تامین نماید به فاکتورهای زیادی از جمله توان پردازشی سرور، میزان و چگونگی فضای در دسترس هارد، میزان حافظه رم و برخی فاکتورهای دیگر است. اتفاقی که در مورد نرم افزار ما افتاده بود دقیقا همین بود و علت کندی عملیاتها در روزهای اخیر و نهایتا شکست عملیاتها را توجیه میکرد.
از آنجایی که میزان نرخ رشد فایل لاگ ما همان 10% پیشفرض بود به مرور و با افزایش حجم لاگ میزان افزایش نیز رشد میکرد و هر بار به مدت زمان بیشتری برای تامین آن از طرف سیستم عامل نیاز بود و نهایتا به حدی رسیده بود که در مدت زمان تایم آوت سرور یعنی 30 ثانیه سیستم عامل قادر به تحویل فضای درخواستی SQL Server نبود و لذا عملیات با شکست مواجه میشد. راه حل سریع اما موقتی رفع مشکل هم تغییر میزان افزایش از 10 درصد به مقدار ثابتی بود که در زمان قابل قبولی قابل تامین باشد. البته این کاری است که باید توسط مدیران پایگاه داده و برای همه دیتابیسها انجام شود. یعنی مقدار افزایش حجم فایلهای دیتابیس باید از حالت درصدی خارج شده و حتما به صورت مقدار ثابت و قابل پیش بینی مقداردهی شود. میزان افزایش هم بسته به فرکانس تراکنشها و حجم هر تراکنش می تواند تعیین شود. در صورتی که مقدار خیلی کوچکی برای آن ست شود پایگاه داده به طور متناوب مجبور به درخواست فضا از سیستم عامل میشود و در صورتی که مقدار آن زیاد باشد تامین آن زمانبر خواهد شد. ما میانگینی از حجم داده هایی که در تراکنشهای یک روز کاری در پایگاه داده انجام میشود را به عنوان نرخ رشد فایل لاگ تنظیم کردیم و بلافاصله مشکل رفع شده و عملکرد نرم افزار به حالت عادی برگشت.
البته همانطور که گفتم این یک راه حل موقتی بود و راه حل بهتر تنظیم نرم افزار پایگاه داده برای پشتیبانگیری از لاگها بود که دیگر شاهد افزایش حجم فایل لاگ نباشیم. لذا شبانه و در زمان عدم فعالیت کاربران پلنی برای پشتیانگیری از پایگاه داده در قالب بکاپهای Full، Differential و Transaction Log به همراه یک زمانبندی برای حذف فایلهای پشتیبان تاریخ گذشته ایجاد کردیم که مشکل پرفرمنس پایگاه داده را به طور کامل رفع نمود.