CHECKDB و خرابی صفحه: وقتی دیتابیس بی‌صدا خراب می‌شود

CHECKDB و خرابی صفحه: وقتی دیتابیس بی‌صدا خراب می‌شود
در این مقاله می‌خوانید
  1. تنها راه دیدنش
  2. حالا که خرابی پیدا شد
  3. دربارهٔ REPAIR_ALLOW_DATA_LOSS
  4. پیشگیری

خرابی داده در SQL Server معمولاً با سر و صدا نمی‌آید. یک صفحه روی دیسک خراب می‌شود — از یک کنترلر معیوب، یک قطع برق در لحظهٔ بد، یا درایوی که در حال مردن است — و تا وقتی کسی دقیقاً همان صفحه را نخواند، هیچ اتفاقی نمی‌افتد. ممکن است ماه‌ها آنجا بماند و شما ماه‌ها از آن بکاپ بگیرید.

تنها راه دیدنش

DBCC CHECKDB([Sales]) WITH NO_INFOMSGS, ALL_ERRORMSGS;

NO_INFOMSGS پیام‌های عادی را حذف می‌کند تا فقط خطاها بمانند. ALL_ERRORMSGS همهٔ خطاها را نشان می‌دهد، نه فقط دویست تای اول. خروجی خالی، یعنی سالم.

یک منبع دوم هم هست که گاهی زودتر خبر می‌دهد:

SELECT * FROM msdb.dbo.suspect_pages;

هر بار که SQL Server در خواندن صفحه‌ای به مشکل می‌خورد، اینجا ثبت می‌کند. اگر این جدول ردیف دارد، همین امروز رسیدگی کنید؛ این یعنی خرابی نه احتمالی، بلکه دیده‌شده است.

حالا که خرابی پیدا شد

ترتیب کار، و ترتیبش مهم است:

  1. عجله نکنید و اول چیزی را تعمیر نکنید. خروجی CHECKDB را کامل ذخیره کنید. در آن نوشته شده کدام شیء، کدام صفحه، و چه نوع خرابی.
  2. بلافاصله یک بکاپ بگیرید. بله، از دیتابیس خراب. این وضعیت فعلی است و ممکن است بعداً لازم شود.
  3. ببینید خرابی کجاست. اگر در یک ایندکس غیرخوشه‌ای است، خوش‌شانسید: ایندکس را حذف و دوباره بسازید، تمام. داده در آن نیست.
  4. اگر در داده است، از بکاپ برگردانید. اگر بکاپ سالم دارید، همین است. اگر خرابی چند صفحه است و نسخهٔ Enterprise دارید، بازیابی در سطح صفحه ممکن است:
    RESTORE DATABASE [Sales] PAGE = '1:57854'
    FROM DISK = N'E:\backup\Sales_full.bak' WITH NORECOVERY;
    -- سپس همهٔ بکاپ‌های لاگ بعد از آن، و در پایان WITH RECOVERY
  5. علت را پیدا کنید. خرابی صفحه علامت است، نه بیماری. لاگ رویدادهای ویندوز و لاگ کنترلر ذخیره‌سازی را ببینید. اگر دیسک در حال مردن است، بازگرداندن فقط زمان می‌خرد.

دربارهٔ REPAIR_ALLOW_DATA_LOSS

این گزینه دقیقاً همان کاری را می‌کند که اسمش می‌گوید: برای درست کردن ساختار، داده حذف می‌کند. شما نمی‌دانید کدام داده، و بعدش هیچ گزارشی از آنچه رفته ندارید.

این آخرین راه است، نه اولین. ترتیب درست: بکاپ سالم ← بازیابی صفحه‌ای ← بازسازی ایندکس آسیب‌دیده ← و فقط اگر هیچ‌کدام ممکن نبود، تعمیر با پذیرش از دست رفتن داده. و اگر به اینجا رسیدید، خودِ این وضعیت یعنی سیاست بکاپ شما شکست خورده و آن مسئلهٔ بزرگ‌تری است که باید بعدش حل شود.

پیشگیری

  • همیشه با CHECKSUM بکاپ بگیرید. بی آن، خرابی در خود فایل بکاپ هم دیده نمی‌شود.
  • PAGE_VERIFY هر دیتابیس را روی CHECKSUM بگذارید. دیتابیس‌هایی که از نسخه‌های قدیمی مهاجرت کرده‌اند، گاهی هنوز روی TORN_PAGE_DETECTION یا NONE مانده‌اند:
    SELECT name, page_verify_option_desc FROM sys.databases;
  • CHECKDB منظم. هفتگی روی دیتابیس‌های مهم. اگر سنگین است، روی نسخهٔ بازگردانده‌شده انجامش دهید — که هم‌زمان آزمون بازیابی هم هست.
  • بکاپ‌ها را به‌اندازهٔ کافی نگه دارید. اگر خرابی دو هفته پیش شروع شده و شما فقط یک هفته بکاپ دارید، همهٔ نسخه‌هایتان خراب‌اند. این تنها دلیلی است که نگه‌داری بلندمدت واقعاً به کارتان می‌آید.

بند آخر ظریف‌ترین است و اغلب نادیده می‌ماند: سیاست نگه‌داری معمولاً بر اساس فضای دیسک تصمیم‌گیری می‌شود، نه بر اساس اینکه «چقدر طول می‌کشد تا بفهمیم چیزی خراب شده». اگر CHECKDB ماهانه می‌زنید، بکاپ کم‌تر از یک ماه یعنی ممکن است روزی هیچ نسخهٔ سالمی نداشته باشید.

یک هفته DBMug را روی سرور خودتان امتحان کنید

لاگ پرشده، دیسک در حال تمام شدن و بکاپ عقب‌افتاده را پیامک می‌کند — و هر بکاپ را با بازگرداندن واقعی می‌آزماید.

درخواست دمو