فك تشفير المفتاح والصفحة WaitResource في حالات الجمود والأقفال

إذا كنت تستخدم تقرير العملية المحظورة أو جمعت الرسوم البيانية التي توفرها SQL Server بشكل دوري ، فستواجه أشياء مثل هذا:

waitresource = "PAGE: 6: 3: 70133"

waitresource=“KEY: 6:72057594041991168 (ce52f92a058c)“

في بعض الأحيان ، سيكون هناك المزيد من المعلومات في XML العملاق الذي تقوم بدراسته (تحتوي الرسوم البيانية المأجورة على قائمة بالموارد التي تساعدك في معرفة أسماء الكائن والفهرس) ، ولكن ليس دائمًا.

سيساعدك هذا النص في فك شفرتها.

كل المعلومات الموجودة هنا موجودة على الإنترنت في أماكن مختلفة ، إنها ببساطة منتشرة للغاية! أريد أن أجمعها معًا ، من DBCC PAGE إلى hobt_id إلى وظائف ٪٪ physloc ٪٪ و ٪٪ lockres ٪٪ غير المسجلين.

أولاً ، دعنا نتحدث عن فترات الانتظار على أقفال PAGE ، ثم ننتقل إلى أقفال KEY.

1) waitresource = "PAGE: 6: 3: 70133" = Database_Id: FileId: PageNumber

إذا كان طلبك ينتظر قفل PAGE ، فسيمنحك SQL Server عنوان تلك الصفحة.

تفصيل "PAGE: 6: 3: 70133" نحصل على:

  • معرّف قاعدة البيانات = 6
  • data_file_id = 3
  • page_number = 70133

1.1) فك تشفير database_id

ابحث عن اسم قاعدة البيانات باستخدام الاستعلام:

SELECT 
    name 
FROM sys.databases 
WHERE database_id=6;
GO

إنه عام DB WideWorldImporters على خادم SQL الخاص بي.

1.2) البحث عن اسم ملف البيانات - إذا كنت مهتمًا

سنستخدم data_file_id في الخطوة التالية للعثور على اسم الجدول. يمكنك فقط التخطي إلى الخطوة التالية ، ولكن إذا كنت مهتمًا باسم الملف ، فيمكنك العثور عليه عن طريق تشغيل استعلام في سياق قاعدة البيانات التي تم العثور عليها ، واستبدال data_file_id في هذا الاستعلام:

USE WideWorldImporters;
GO
SELECT 
    name, 
    physical_name
FROM sys.database_files
WHERE file_id = 3;
GO

في قاعدة بيانات WideWorldImporters ، يوجد هذا ملف يسمى WWI_UserData وقد استعادته إلى C: MSSQLDATAWideWorldImporters_UserData.ndf. (عفوًا ، لقد ضبطتني أضع ملفات على محرك أقراص النظام! لا! إنه أمر محرج).

1.3) الحصول على اسم الكائن من DBCC PAGE

نحن نعلم الآن أن الصفحة # 70133 في ملف البيانات 3 تنتمي إلى قاعدة بيانات WorldWideImporters. يمكننا إلقاء نظرة على محتويات هذه الصفحة باستخدام صفحة DBCC PAGE غير الموثقة وعلامة التتبع 3604.
ملاحظة: أفضل استخدام DBCC PAGE على نسخة مستعادة في مكان ما على خادم آخر ، لأنها أشياء غير مسجلة. في بعض الحالات ، هي قد يؤدي إلى تفريغ (تقريبا. مترجم - الرابط ، للأسف ، لا يقود إلى أي مكان ، ولكن بالحكم على عنوان url ، فإننا نتحدث عن الفهارس التي تمت تصفيتها).

/* This trace flag makes DBCC PAGE output go to our Messages tab
instead of the SQL Server Error Log file */
DBCC TRACEON (3604);
GO
/* DBCC PAGE (DatabaseName, FileNumber, PageNumber, DumpStyle)*/
DBCC PAGE ('WideWorldImporters',3,70133,2);
GO

بالتمرير إلى النتائج ، يمكنك العثور على object_id و index_id.
فك تشفير المفتاح والصفحة WaitResource في حالات الجمود والأقفال
يكاد ينتهي! يمكنك الآن العثور على أسماء الجدول والفهرس باستخدام الاستعلام:

USE WideWorldImporters;
GO
SELECT 
    sc.name as schema_name, 
    so.name as object_name, 
    si.name as index_name
FROM sys.objects as so 
JOIN sys.indexes as si on 
    so.object_id=si.object_id
JOIN sys.schemas AS sc on 
    so.schema_id=sc.schema_id
WHERE 
    so.object_id = 94623380
    and si.index_id = 1;
GO

وهنا نرى أن الانتظار على القفل كان في فهرس PK_Sales_OrderLines لجدول Sales.OrderLines.

ملاحظة: في SQL Server 2014 وما بعده ، يمكن أيضًا العثور على اسم الكائن باستخدام DMO sys.dm_db_database_page_allocations غير الموثق. ولكن عليك الاستعلام عن كل صفحة في قاعدة البيانات ، والتي لا تبدو رائعة بالنسبة لقواعد البيانات الكبيرة ، لذلك استخدمت DBCC PAGE.

1.4) هل من الممكن رؤية البيانات على الصفحة التي تم حظرها؟

Nuuu ، نعم. لكن ... هل أنت متأكد أنك في حاجة إليها حقًا؟
إنها بطيئة حتى على الطاولات الصغيرة. لكنه رائع نوعًا ما ، لذا بما أنك قرأت هذا الآن ... فلنتحدث عن ٪٪ physloc ٪٪!

٪٪ physloc ٪٪ هي قطعة سحرية غير موثقة تقوم بإرجاع معرف مادي لكل إدخال. يمكنك استخدام ٪٪ physloc ٪٪ مع sys.fn_PhysLocFormatter في SQL Server 2008 وما فوق.

الآن بعد أن علمنا أننا أردنا حظر الصفحة في Sales.OrderLines ، يمكننا إلقاء نظرة على جميع البيانات الموجودة في هذا الجدول المخزنة في ملف البيانات رقم 3 في الصفحة # 70133 ، مع الاستعلام التالي:

Use WideWorldImporters;
GO
SELECT 
    sys.fn_PhysLocFormatter (%%physloc%%),
    *
FROM Sales.OrderLines (NOLOCK)
WHERE sys.fn_PhysLocFormatter (%%physloc%%) like '(3:70133%'
GO

كما قلت ، إنها بطيئة حتى على الطاولات الصغيرة. لقد أضفت NOLOCK إلى الطلب لأننا ما زلنا لا نملك ضمانات بأن البيانات التي نريد أن ننظر إليها هي نفسها تمامًا كما كانت في وقت اكتشاف القفل - حتى نتمكن من إجراء قراءات قذرة بأمان.
ولكن ، حسنًا ، يعيدني الاستعلام 25 صفاً تم من أجلها حارب الاستعلام.
فك تشفير المفتاح والصفحة WaitResource في حالات الجمود والأقفال
يكفي حول أقفال PAGE. ماذا لو كنا ننتظر قفل KEY؟

2) waitresource = "KEY: 6: 72057594041991168 (ce52f92a058c)" = Database_Id، HOBT_Id (تجزئة سحرية يمكن فك تشفيرها باستخدام ٪٪ lockres ٪٪ إذا كنت تريد ذلك حقًا)

إذا حاول استعلامك قفل إدخال فهرس وتم قفله من تلقاء نفسه ، فستحصل على نوع مختلف تمامًا من العنوان.
بتقسيم "6: 72057594041991168 (ce52f92a058c)" إلى أجزاء ، نحصل على:

  • معرّف قاعدة البيانات = 6
  • hobt_id = 72057594041991168
  • تجزئة السحر = (ce52f92a058c)

2.1) فك تشفير database_id

إنه يعمل تمامًا كما هو الحال مع المثال أعلاه! نجد اسم قاعدة البيانات باستخدام الاستعلام:

SELECT 
    name 
FROM sys.databases 
WHERE database_id=6;
GO

في حالتي ، الأمر نفسه DB WideWorldImporters.

2.2) فك تشفير hobt_id

في سياق قاعدة البيانات التي تم العثور عليها ، تحتاج إلى الاستعلام عن sys.partitions مع بعض الصلات التي ستساعد في تحديد أسماء الجدول والفهرس ...

USE WideWorldImporters;
GO
SELECT 
    sc.name as schema_name, 
    so.name as object_name, 
    si.name as index_name
FROM sys.partitions AS p
JOIN sys.objects as so on 
    p.object_id=so.object_id
JOIN sys.indexes as si on 
    p.index_id=si.index_id and 
    p.object_id=si.object_id
JOIN sys.schemas AS sc on 
    so.schema_id=sc.schema_id
WHERE hobt_id = 72057594041991168;
GO

يخبرني أن الطلب كان ينتظر على قفل Application.Countries باستخدام فهرس PK_Application_Countries.

2.3) الآن لبعض السحر ٪٪ lockres ٪٪ - إذا كنت تريد معرفة أي دخول تم قفله

إذا كنت أريد حقًا معرفة الصف الذي كان يلزم فيه القفل ، فيمكنني معرفة ذلك من خلال الاستعلام عن الجدول نفسه. يمكننا استخدام وظيفة ٪٪ lockres ٪٪ غير الموثقة للعثور على إدخال يطابق التجزئة السحرية.
لاحظ أن هذا الاستعلام سيفحص الجدول بأكمله ، وقد لا يكون هذا ممتعًا على الطاولات الكبيرة على الإطلاق:

SELECT
    *
FROM Application.Countries (NOLOCK)
WHERE %%lockres%% = '(ce52f92a058c)';
GO

لقد أضفت NOLOCK (بناء على نصيحة كلاوس أشينبرينر على تويتر) لأن الأقفال يمكن أن تكون مشكلة. نريد فقط أن ننظر إلى ما هو موجود الآن ، وليس ما كان موجودًا عندما بدأت المعاملة - لا أعتقد أن اتساق البيانات مهم بالنسبة لنا.
فويلا ، الرقم القياسي الذي ناضلنا من أجله!
فك تشفير المفتاح والصفحة WaitResource في حالات الجمود والأقفال

شكر وتقدير ومزيد من القراءة

لا أتذكر من الذي وصف العديد من هذه الأشياء لأول مرة ، ولكن إليك منشورتان حول الأشياء الأقل توثيقًا التي قد تعجبك:

المصدر: www.habr.com

إضافة تعليق