Ontsyfer sleutel en Page WaitResource in dooiepunte en slotte
As jy die geblokkeerde prosesverslag gebruik of die dooiepuntgrafieke wat van tyd tot tyd deur SQL Server verskaf word versamel, sal jy dinge soos hierdie teëkom:
Soms sal daar meer inligting in daardie reuse-XML wees wat jy bestudeer (dooiepuntgrafieke bevat 'n lys hulpbronne wat jou help om die voorwerp- en indeksname uit te vind), maar nie altyd nie.
Hierdie teks sal jou help om hulle te ontsyfer.
Al die inligting wat hier is, is op verskeie plekke op die internet, dit is net baie versprei! Ek wil alles bymekaar sit - van DBCC PAGE tot hobt_id en tot die ongedokumenteerde %%physloc%% en %%lockres%% funksies.
Kom ons praat eers oor wagte op PAGE-slotte, en dan gaan ons aan na SLEUTEL-slotte.
1.2) Soek die naam van die datalêer - as jy belangstel
Ons gaan data_file_id in die volgende stap gebruik om die tabelnaam te vind. Jy kan eenvoudig oorslaan na die volgende stap, maar as jy belangstel in die lêernaam, kan jy dit vind deur 'n navraag in die konteks van die gevind databasis uit te voer, deur data_file_id in hierdie navraag te vervang:
USE WideWorldImporters;
GO
SELECT
name,
physical_name
FROM sys.database_files
WHERE file_id = 3;
GO
In die WideWorldImporters-databasis is dit 'n lêer genaamd WWI_UserData en ek het dit herstel na C:MSSQLDATAWideWorldImporters_UserData.ndf. (Oeps, jy het my gevang dat ek lêers op die stelselskyf sit! Nee! Dit was ongemaklik).
1.3) Kry die voorwerp naam van DBCC PAGE
Nou weet ons dat bladsy #70133 in datalêer 3 aan die WorldWideImporters-databasis behoort. Ons kan na die inhoud van hierdie bladsy kyk deur die ongedokumenteerde DBCC BLADSY en spoorvlag 3604 te gebruik.
Let wel: Ek verkies om DBCC PAGE te gebruik op 'n herstelde kopie vanaf 'n rugsteun iewers op 'n ander bediener, want dit is 'n ongedokumenteerde ding. In sommige gevalle het sy kan daartoe lei dat 'n stortingsterrein geskep word (ongeveer. vertaler - die skakel lei ongelukkig nêrens nie, maar te oordeel aan die url, praat ons van gefiltreerde indekse).
/* 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
Deur deur die resultate te blaai, kan jy object_id en index_id vind.
Amper klaar! Nou kan jy die tabel- en indeksname vind deur die navraag te gebruik:
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
En nou sien ons dat die slotwag op die PK_Sales_OrderLines-indeks van die Sales.OrderLines-tabel was.
Let wel: In SQL Server 2014 en later kan die objeknaam ook gevind word deur die ongedokumenteerde DMO sys.dm_db_database_page_allocations te gebruik. Maar jy moet elke bladsy in die databasis navraag doen, wat nie baie cool lyk vir groot databasisse nie, so ek het DBCC PAGE gebruik.
1.4) Is dit moontlik om die data te sien op die bladsy wat geblokkeer is?
Wel ja. Maar ... is jy seker dat jy dit regtig nodig het?
Dit is stadig, selfs op klein tafeltjies. Maar dit is nogal cool, so aangesien jy tot hier gelees het... kom ons praat oor %%physloc%%!
Noudat ons weet dat ons die bladsy in Sales.OrderLines wou sluit, kan ons kyk na al die data in hierdie tabel, wat in datalêer #3 op bladsy #70133 gestoor word, deur hierdie navraag te gebruik:
Use WideWorldImporters;
GO
SELECT
sys.fn_PhysLocFormatter (%%physloc%%),
*
FROM Sales.OrderLines (NOLOCK)
WHERE sys.fn_PhysLocFormatter (%%physloc%%) like '(3:70133%'
GO
Soos ek gesê het, dit is stadig, selfs op klein tafeltjies. Ek het NOLOCK by die versoek gevoeg, want ons het steeds geen waarborg dat die data waarna ons wil kyk presies dieselfde is as wat dit was toe die slot opgespoor is nie – ons kan dus veilig vuil leeswerk doen.
Maar hoera, die navraag gee vir my dieselfde 25 rye terug waarvoor ons navraag baklei het
Genoeg oor PAGE-slotte. Wat as ons wag vir 'n SLEUTEL-slot?
2) waitresource=“SLEUTEL: 6:72057594041991168 (ce52f92a058c)” = Database_Id, HOBT_Id (magiese hash wat gedekripteer kan word met %%lockres%% as jy dit regtig wil hê)
As jou navraag probeer om 'n rekord in die indeks te sluit en self gesluit word, eindig jy met 'n heeltemal ander tipe adres.
Deur “6:72057594041991168 (ce52f92a058c)” in dele te breek, kry ons:
databasis_id = 6
hobt_id = 72057594041991168
magiese hash = (ce52f92a058c)
2.1) Dekripteer databasis_id
Dit werk presies dieselfde as die voorbeeld hierbo! Vind die databasisnaam deur die navraag te gebruik:
SELECT
name
FROM sys.databases
WHERE database_id=6;
GO
In die konteks van die databasis wat gevind is, moet jy 'n navraag na sys.partitions uitvoer met 'n paar verbindings wat sal help om die name van die tabel en indeks te bepaal...
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
Dit sê vir my dat die versoek op die Application.Countries-slot gewag het deur die PK_Application_Countries-indeks te gebruik.
2.3) Nou 'n bietjie magie %%lockres%% - as jy wil uitvind watter inskrywing gesluit is
As ek regtig wil weet op watter ry die slot was, kan ek uitvind deur die tabel self te bevraagteken. Ons kan die ongedokumenteerde %%lockres%%-funksie gebruik om 'n inskrywing te vind wat by die magiese hash pas.
Neem asseblief kennis dat hierdie navraag die hele tabel sal skandeer, en op groot tafels sal dit dalk glad nie pret wees nie:
SELECT
*
FROM Application.Countries (NOLOCK)
WHERE %%lockres%% = '(ce52f92a058c)';
GO
Ek het NOLOCK bygevoeg (op advies van Klaus Aschenbrenner op Twitter) omdat blokkasies ’n probleem kan word. Ons wil net kyk na wat nou daar is, en nie wat daar was toe die transaksie begin het nie - ek dink nie dat datakonsekwentheid vir ons belangrik is nie.
Voila, die rekord waarvoor ons baklei het!
Dankbetuigings en verdere leeswerk
Ek kan nie onthou wie die eerste keer baie van hierdie dinge beskryf het nie, maar hier is twee plasings oor die mins gedokumenteerde dinge waarvan jy dalk sal hou: