AtÅ”ifrējiet atslēgu un Page WaitResource strupceļos un slēdzenes

Ja izmantojat bloķētā procesa pārskatu vai periodiski apkopojat strupceļa diagrammas, ko nodroÅ”ina SQL Server, jÅ«s saskarsities ar Ŕādām lietām:

waitresource="PAGE: 6:3:70133"

waitresource=ā€œKEY: 6:72057594041991168 (ce52f92a058c)ā€œ

Dažreiz jūsu pētītajā milzīgajā XML būs vairāk informācijas (strupcijas grafikos ir resursu saraksts, kas palīdz noskaidrot objekta un indeksa nosaukumus), bet ne vienmēr.

Å is teksts palÄ«dzēs jums tos atÅ”ifrēt.

Visa informācija, kas Å”eit ir, ir internetā dažādās vietās, tā vienkārÅ”i ir ļoti izplatÄ«ta! Es vēlos to visu apvienot, sākot no DBCC PAGE lÄ«dz hobt_id un beidzot ar nedokumentētajām %%physloc%% un %%lockres%% funkcijām.

Vispirms parunāsim par gaidÄ«Å”anu PAGE slēdzenēs un pēc tam pārejiet uz KEY slēdzenēm.

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

Ja jÅ«su pieprasÄ«jums gaida LAPAS bloÄ·Ä“Å”anu, SQL Server jums norādÄ«s Ŕīs lapas adresi.

Sadalot "PAGE: 6:3:70133", mēs iegūstam:

  • datu bāzes_id = 6
  • datu_faila_id = 3
  • lapas_numurs = 70133

1.1) AtÅ”ifrēt datu bāzes_id

Atrodiet datu bāzes nosaukumu, izmantojot vaicājumu:

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

Tas ir publisks DB WideWorldImporters manā SQL serverī.

1.2) Meklēju datu faila nosaukumu - ja jūs interesē

Nākamajā darbÄ«bā mēs izmantosim data_file_id, lai atrastu tabulas nosaukumu. Varat vienkārÅ”i pāriet uz nākamo soli, bet, ja jÅ«s interesē faila nosaukums, varat to atrast, izpildot vaicājumu atrastās datu bāzes kontekstā, aizstājot ar Å”o vaicājumu data_file_id:

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

Datubāzē WideWorldImporters Å”is ir fails ar nosaukumu WWI_UserData, un es to atjaunoju uz C:MSSQLDATAWideWorldImporters_UserData.ndf. (Hmm, jÅ«s pieķērāt mani, ievietojot failus sistēmas diskā! Nē! Tas ir neērti).

1.3) Iegūstiet objekta nosaukumu no DBCC PAGE

Tagad mēs zinām, ka 70133. datu faila lapa #3 pieder WorldWideImporters datubāzei. Mēs varam apskatÄ«t Ŕīs lapas saturu, izmantojot nedokumentētu DBCC PAGE un izsekoÅ”anas karogu 3604.
Piezīme. Man labāk patīk izmantot DBCC PAGE atjaunotā kopijā kaut kur citā serverī, jo tā ir nedokumentēta lieta. Dažos gadījumos viņa var izraisīt izgāztuvi (apm. tulkotājs - saite diemžēl nekur neved, bet, spriežot pēc url, mēs runājam par filtrētiem indeksiem).

/* 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

Ritinot līdz rezultātiem, varat atrast objektu_id un index_id.
AtÅ”ifrējiet atslēgu un Page WaitResource strupceļos un slēdzenes
Gandrīz pabeigts! Tagad jūs varat atrast tabulu un indeksu nosaukumus ar vaicājumu:

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

Un Å”eit mēs redzam, ka bloÄ·Ä“Å”anas gaidÄ«Å”ana bija tabulas Sales.OrderLines indeksā PK_Sales_OrderLines.

PiezÄ«me. Operētājsistēmā SQL Server 2014 un jaunākās versijās objekta nosaukumu var atrast arÄ«, izmantojot nedokumentētu DMO sys.dm_db_database_page_allocations. Bet ir jāvaicā katra datubāzes lapa, kas lielām datu bāzēm neizskatās Ä«paÅ”i forÅ”i, tāpēc izmantoju DBCC PAGE.

1.4) Vai ir iespējams redzēt datus lapā, kas tika bloķēta?

Nuuu, jā. Bet... vai esat pārliecināts, ka jums tas tieŔām ir vajadzīgs?
Tas ir lēns pat uz maziem galdiem. Bet tas ir forÅ”i, tāpēc, tā kā esat izlasÄ«jis tik tālu, parunāsim par %%physloc%%!

%%physloc%% ir nedokumentēta maģija, kas katram ierakstam atgriež fizisko ID. tu vari izmantot %%physloc%% kopā ar sys.fn_PhysLocFormatter SQL Server 2008 un jaunākās versijās.

Tagad, kad mēs zinām, ka vēlējāmies bloķēt lapu Sales.OrderLines, mēs varam apskatÄ«t visus datus Å”ajā tabulā, kas ir saglabāta datu failā Nr. 3 70133. lappusē ar Ŕādu vaicājumu:

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

Kā jau teicu, tas ir lēns pat uz maziem galdiņiem. PieprasÄ«jumam pievienoju NOLOCK, jo mums joprojām nav garantiju, ka dati, kurus vēlamies apskatÄ«t, ir tieÅ”i tādi paÅ”i, kādi tie bija slēdzenes atklāŔanas brÄ«dÄ«, tāpēc varam droÅ”i veikt netÄ«rās nolasÄ«Å”anas.
Bet, urrā, vaicājums man atgriež tās paŔas 25 rindas, par kurām cīnījās mūsu vaicājums.
AtÅ”ifrējiet atslēgu un Page WaitResource strupceļos un slēdzenes
Pietiek ar PAGE slēdzenēm. Ko darīt, ja mēs gaidām KEY slēdzeni?

2) waitresource="KEY: 6:72057594041991168 (ce52f92a058c)" = Database_Id, HOBT_Id (maÄ£isks jaukums, ko var atÅ”ifrēt ar %%lockres%%, ja ļoti vēlaties)

Ja jūsu vaicājums mēģina bloķēt indeksa ierakstu un tiek bloķēts pats par sevi, jūs saņemat pilnīgi cita veida adresi.
Sadalot ā€œ6:72057594041991168 (ce52f92a058c)ā€ daļās, mēs iegÅ«stam:

  • datu bāzes_id = 6
  • hobt_id = 72057594041991168
  • burvju hash = (ce52f92a058c)

2.1) AtÅ”ifrēt datu bāzes_id

Tas darbojas tieÅ”i tāpat kā iepriekÅ” minētajā piemērā! Mēs atrodam datu bāzes nosaukumu, izmantojot vaicājumu:

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

Manā gadījumā tas ir tas pats DB WideWorldImporters.

2.2) AtÅ”ifrēt hobt_id

Atrastās datu bāzes kontekstā jums ir jāvaicā sys.partitions ar pāris savienojumiem, kas palīdzēs noteikt tabulas un indeksa nosaukumus ...

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

Tas man saka, ka pieprasījums gaidīja Application.Countries bloķēŔanu, izmantojot indeksu PK_Application_Countries.

2.3) Tagad dažas %%lockres%% burvÄ«bas ā€” ja vēlaties uzzināt, kurÅ” ieraksts tika bloķēts

Ja tieŔām gribu zināt, kurā rindā bija vajadzÄ«ga slēdzene, to varu noskaidrot, vaicājot paÅ”u tabulu. Mēs varam izmantot nedokumentētu funkciju %%lockres%%, lai atrastu ierakstu, kas atbilst maÄ£iskajam hash.
Ņemiet vērā, ka Å”is vaicājums pārbaudÄ«s visu tabulu, un lielās tabulās tas var nebÅ«t jautri:

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

Es pievienoju NOLOCK (pēc Klausa AÅ”enbrenera ieteikuma Twitter), jo slēdzenes var radÄ«t problēmas. Mēs tikai vēlamies aplÅ«kot to, kas tur ir tagad, nevis to, kas bija darÄ«juma sākumā ā€” es nedomāju, ka datu konsekvence mums ir svarÄ«ga.
Voila, rekords, par kuru mēs cīnījāmies!
AtÅ”ifrējiet atslēgu un Page WaitResource strupceļos un slēdzenes

Pateicības un tālāka lasīŔana

Es neatceros, kurÅ” pirmais aprakstÄ«ja daudzas no Ŕīm lietām, taču Å”eit ir divas ziņas par vismazāk dokumentētajām lietām, kas jums varētu patikt:

Avots: www.habr.com

Pievieno komentāru