في أحد هذه الأيام تحولت إحدى قواعد بيانات MS SQL Server إلى Suspect ، كانت هناك رسالة خطأ في السجل:
رسالة 7105 ، المستوى 22 ، الحالة 9 ، السطر 14
معرف قاعدة البيانات 6 ، الصفحة (1: 386499) ، الفتحة 0 لعقدة نوع بيانات LOB غير موجودة. يحدث هذا عادةً بسبب المعاملات التي يمكنها قراءة البيانات غير الملتزم بها على صفحة البيانات. تشغيل CHECKTABLE DBCC.
تم نقل قاعدة البيانات إلى الطوارئ وحاولت تنفيذ CHECKDB DBCC ، ولكن تم قطع التنفيذ على الفور:
مس 8989 ، المستوى 16 ، الحالة 1 ، السطر 13
تم إنهاء الشيك. تم الكشف عن فشل أثناء جمع الحقائق. من المحتمل أن يكون tempdb خارج المساحة أو جدول النظام غير متناسق. تحقق من الأخطاء السابقة.
رسالة 7105 ، المستوى 22 ، الحالة 9 ، السطر 13
معرف قاعدة البيانات 6 ، الصفحة (1: 386499) ، الفتحة 0 لعقدة نوع بيانات LOB غير موجودة. يحدث هذا عادةً بسبب المعاملات التي يمكنها قراءة البيانات غير الملتزم بها على صفحة البيانات. تشغيل CHECKTABLE DBCC.
تمت مقاطعة الأمر DBCC CHECKALLOC مع خطأ مشابه. كل شيء كان معقدًا بسبب حقيقة أن SQL Server كان الإصدار 9.0.1399 ، أي RTM ، بدون أي تحديثات.
لم تؤد محاولات استخدام تلميح TABLOCK وزيادة مستوى عزل المعاملة بشكل صريح إلى أي شيء (كان هناك مساحة قرص كافية مع tempdb و DBCC CHECKALLOC مع تقدير مع فشل نفس الخطأ). لم أكن أرغب حقًا في نقل SP إلى خادم مزود بقاعدة بيانات تالفة ، وكان غير مفهوم تمامًا مع الكائن المحدد الذي كانت المشكلة. بالإضافة إلى ذلك ، يبدو أن رسالة DBCC CHECKDB لا علاقة لها بالواقع ، حيث كان هناك سجل واحد في msdb.dbo.suspect_pages ، لكن رقم الصفحة كان مختلفًا عن الرقم الذي طبعته DBCC CHECKDB.
من أجل اتباع تعليمات DBCC CHECKDB وتنفيذ DBCC CHECKTABLE ، تحتاج إلى معرفة الجدول. وبعد بحث طويل ،
تم العثور على تعليمات واحدة.
ملاحظةأعتذر عن عدم تطابق أرقام الجدول في رسائل الخطأ وفي الرمز. أخذت أخطاء من السجلات ، وبعد ذلك نفذت التعليمات البرمجية في بيئة اختبار على قاعدة حية أخرى.
استخدمنا الخوارزمية أدناه لتحديد object_id للصفحتين - من صفحة DBCC CHECKDB والصفحة المشكوك فيها. كانت المشكلة في الصفحة من الصفحات المشبوهة
أول شيء يجب القيام به هو التنفيذ (في سياق قاعدة البيانات التالفة) هو
DBCC PAGE (database_id، file_id، page_id، printopt):
DBCC TRACEON (3604); DBCC PAGE(5, 1, 3242342, 0) DBCC TRACEOFF (3604);
إما:
DBCC PAGE(5, 1, 3242342, 0) WITH TABLERESULTS.
إذا كنت محظوظًا (أو كنت تلعب على قاعدة مباشرة) ، فسترى نتيجة لذلك البيانات الوصفية: حقل ObjectId ، وفي الواقع ، الكائن المطلوب:

ومع ذلك ، إذا كنت غير محظوظ ، مثلنا ، سترى ما يلي:
البيانات الوصفية: = غير متوفر في DB غير متصل
في حالة عدم توفر البيانات الوصفية ، لن يتم فقدان كل شيء ، في هذه الحالة ، نحتاج إلى حقل m_objId (AllocUnitId.idObj). إذا كان m_objId = 255 ، فإن المشكلة هي ، أغلق المقالة وابحث عن شيء آخر (حاول كتابة كل شيء يمكنك كتابته وإزالة البيانات ، وقم بتنفيذ DBCC CHECKDB باستخدام معلمات "الاسترداد" بشكل أعمى ، وما إلى ذلك).
تُظهر لقطة الشاشة أن لدي m_objId = 9931 ، أي يمكن أن تستمر.
تحتاج الآن إلى إجراء بعض العمليات الحسابية لحساب معرف وحدة التخصيص (يمكن العثور على المزيد حول وحدات التخصيص
هنا ):
معرف وحدة التخصيص = m_objid * 65536 + (2 ^ 56)
في حالتنا:
معرف وحدة التخصيص = 9931 * 65536 + (2 ^ 56) = 72057594688765952
لذا ، عند معرفة معرف وحدة التخصيص ، يمكنك رؤية ما لدينا في عرض النظام
sys.allocation_units :
SELECT * FROM sys.allocation_units WHERE allocation_unit_id = 72057594688765952

وهناك ، في حالة النوع = 1 أو 3 (IN_ROW_DATA ، ROW_OVERFLOW_DATA) ، فإن العمود container_id = sys.partitions.hobt_id ("Heap-Or-B-Tree ID") ، أي يمكنك تشغيل الطلب:
SELECT * FROM sys.partitions WHERE hobt_id = 72057594661437440

وهنا يوجد بالفعل object_id و index_id الصحيحان. يمكنك الآن رؤية ما لدينا في sys.objects و sys.indexes ، وتنفيذ ما يلي:
SELECT OBJECT_NAME(object_id)
لحسن الحظ ، في كل من الوضع الحقيقي وهنا ، تبين أن المؤشر غير العنقودي تم تأكيده ، بعد إعادة الهيكلة التي عاد كل شيء إلى طبيعتها (في الواقع ، لا ، ولكن هذه قصة أخرى).
المراجع :
كيفية استخدام صفحة DBCCاستكشاف الأخطاء وإصلاحها وإصلاح تلف مستوى صفحة خادم SQLما هي وحدات التخصيص؟البحث عن اسم جدول من معرف الصفحةsys.allocation_units