Վերծանել բանալին և էջի սպասման ռեսուրսը փակուղիներում և կողպեքներում

Եթե ​​դուք օգտագործում եք արգելափակված գործընթացի հաշվետվությունը կամ պարբերաբար հավաքում եք SQL Server-ի կողմից տրամադրված փակուղային գրաֆիկները, դուք կհանդիպեք նման բաների.

waitresource = "ԷՋ: 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: Page Number

Եթե ​​ձեր հարցումը սպասում է PAGE կողպեքի վրա, SQL Server-ը ձեզ կտա այդ էջի հասցեն:

Կոտրելով «ԷՋ՝ 6:3:70133»՝ մենք ստանում ենք.

  • տվյալների բազա_id = 6
  • data_file_id = 3
  • էջի_համար = 70133

1.1) Decrypt 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:
Վերծանել բանալին և էջի սպասման ռեսուրսը փակուղիներում և կողպեքներում
Գրեթե արված է! Այժմ դուք կարող եք գտնել աղյուսակների և ինդեքսների անունները հարցումով.

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

Եվ այստեղ մենք տեսնում ենք, որ կողպեքի վրա սպասելը եղել է Sales.OrderLines աղյուսակի PK_Sales_OrderLines ինդեքսում:

Նշում. SQL Server 2014-ում և ավելի բարձր, օբյեկտի անունը կարելի է գտնել նաև՝ օգտագործելով չփաստաթղթավորված DMO sys.dm_db_database_page_allocations: Բայց դուք պետք է հարցումներ կատարեք տվյալների բազայի յուրաքանչյուր էջին, որը մեծ տվյալների բազաների համար այնքան էլ հիանալի տեսք չունի, ուստի ես օգտագործեցի DBCC PAGE-ը:

1.4) Հնարավո՞ր է արդյոք տեսնել արգելափակված էջի տվյալները:

Նուու, այո։ Բայց... վստա՞հ եք, որ դրա կարիքն իսկապես ունեք:
Այն դանդաղ է նույնիսկ փոքր սեղանների վրա: Բայց դա մի տեսակ հիանալի է, այնպես որ, քանի որ դուք այսքան հեռու եք կարդացել ... եկեք խոսենք %%physloc%%-ի մասին:

%%physloc%%-ը չփաստաթղթավորված մոգություն է, որը վերադարձնում է ֆիզիկական ID յուրաքանչյուր մուտքի համար: դուք կարող եք օգտագործել %%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 տողերը, որոնց համար պայքարում էր մեր հարցումը:
Վերծանել բանալին և էջի սպասման ռեսուրսը փակուղիներում և կողպեքներում
Բավական է PAGE կողպեքների մասին: Իսկ եթե մենք սպասում ենք KEY կողպեքի:

2) waitresource="KEY: 6:72057594041991168 (ce52f92a058c)" = Database_Id, HOBT_Id (կախարդական հեշ, որը կարող է վերծանվել %%lockres%%-ով, եթե իսկապես ցանկանում եք)

Եթե ​​ձեր հարցումը փորձում է կողպել ինդեքսի մուտքի վրա և ինքն իրեն արգելափակվում է, դուք ստանում եք բոլորովին այլ տեսակի հասցե:
«6:72057594041991168 (ce52f92a058c)» մասերի բաժանելով՝ մենք ստանում ենք.

  • տվյալների բազա_id = 6
  • hobt_id = 72057594041991168
  • կախարդական հեշ = (ce52f92a058c)

2.1) Decrypt database_id

Այն աշխատում է ճիշտ այնպես, ինչպես վերը նշված օրինակով: Մենք գտնում ենք տվյալների բազայի անունը՝ օգտագործելով հարցումը.

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

Իմ դեպքում նույնն է DB WideWorldImporters.

2.2) Decrypt 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 (Twitter-ում Կլաուս Աշենբրենների խորհրդով) քանի որ կողպեքները կարող են խնդիր լինել: Մենք պարզապես ուզում ենք տեսնել, թե ինչ կա հիմա, և ոչ թե այն, ինչ կար գործարքի մեկնարկի ժամանակ, ես չեմ կարծում, որ տվյալների հետևողականությունը մեզ համար կարևոր է:
Voila, ռեկորդ, որի համար մենք պայքարում էինք:
Վերծանել բանալին և էջի սպասման ռեսուրսը փակուղիներում և կողպեքներում

Երախտագիտություն և հետագա ընթերցում

Ես չեմ հիշում, թե ով է առաջինը նկարագրել այս բաներից շատերը, բայց ահա երկու գրառում ամենաքիչ փաստագրված բաների մասին, որոնք ձեզ կարող են դուր գալ.

Source: www.habr.com

Добавить комментарий