Entschlësselt Schlëssel a Page WaitResource an Deadlocks a Spären

Wann Dir de blockéierte Prozessbericht benotzt oder d'Deadlock Grafike sammelt, déi vum SQL Server periodesch zur Verfügung gestallt gëtt, stitt Dir op Saachen wéi dëst:

waitresource="PAGE: 6:3:70133"

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

Heiansdo gëtt et méi Informatioun an deem riesegen XML deen Dir studéiert (Deadlock Grafike enthalen eng Lëscht vu Ressourcen déi Iech hëllefen den Objet an den Indexnamen erauszefannen), awer net ëmmer.

Dësen Text hëlleft Iech se ze entzifferen.

All d'Informatiounen, déi hei ass, ass op verschiddene Plazen um Internet, et ass just ganz verdeelt! Ech wëll alles zesummen setzen - vun DBCC PAGE bis hobt_id an op déi ondokumentéiert %%physloc%% an %%lockres%% Funktiounen.

Éischt, loosse mer iwwer waarden op PAGE Spären schwätzen, an dann wäerte mir weider op KEY Spären.

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

Wann Är Ufro op engem PAGE-Spär waart, gëtt SQL Server Iech d'Adress vun där Säit.

Ofbriechen "PAGE: 6:3:70133" kréien mir:

  • database_id = 6
  • data_file_id = 3
  • page_numer = 70133

1.1) Decrypt database_id

Loosst eis den Datebanknumm fannen mat der Ufro:

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

Dëst ass ëffentlech DB WideWorldImporters op mengem SQL Server.

1.2) Sich no den Numm vun der Datedatei - wann Dir interesséiert sidd

Mir benotze data_file_id am nächste Schrëtt fir den Dëschnumm ze fannen. Dir kënnt einfach op de nächste Schrëtt sprangen, awer wann Dir un den Dateinumm interesséiert sidd, kënnt Dir et fannen andeems Dir eng Ufro am Kontext vun der fonnter Datebank leeft, an ersetzt dat_file_id an dëser Ufro:

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

An der WideWorldImporters Datebank ass dëst e Fichier mam Numm WWI_UserData an ech hunn et op C:MSSQLDATAWideWorldImporters_UserData.ndf restauréiert. (Oops, du hues mech gefaangen Dateien op de Systemdiskette ze setzen! Nee! Dat war schweier).

1.3) Kritt den Objektnumm vun der DBCC PAGE

Elo wësse mer datt d'Säit #70133 an der Datedatei 3 zu der WorldWideImporters Datebank gehéiert. Mir kënnen den Inhalt vun dëser Säit kucken mat der ondokumentéierter DBCC PAGE an Trace Fändel 3604.
Notiz: Ech léiwer DBCC PAGE op enger restauréierter Kopie vun engem Backup iergendwou op engem anere Server ze benotzen, well et eng ondokumentéiert Saach ass. An e puer Fäll, si kann zu engem Dump entstoen (ca. Iwwersetzer - de Link féiert leider néierens, awer no der URL beurteelen, schwätze mir vu gefilterten Indexen).

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

Scrollen duerch d'Resultater, fannt Dir object_id an index_id.
Entschlësselt Schlëssel a Page WaitResource an Deadlocks a Spären
Bal fäerdeg! Elo kënnt Dir d'Tabell an d'Indexnimm fannen mat der Ufro:

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

An elo gesi mer datt d'Spärwait um PK_Sales_OrderLines Index vun der Sales.OrderLines Dësch war.

Bemierkung: Am SQL Server 2014 a spéider kann den Objektnumm och mat der ondokumentéierter DMO sys.dm_db_database_page_allocations fonnt ginn. Awer Dir musst all Säit an der Datebank ufroen, wat fir grouss Datenbanken net ganz cool ausgesäit, also hunn ech DBCC PAGE benotzt.

1.4) Ass et méiglech d'Donnéeën op der Säit ze gesinn déi gespaart gouf?

Gutt, jo. Awer ... sidd Dir sécher datt Dir et wierklech braucht?
Et ass lues och op kleng Dëscher. Awer et ass zimmlech cool, also well Dir esou wäit gelies hutt ... schwätze mer iwwer %%physloc%%!

%%physloc%% ass en ondokumentéiert Stéck Magie dat e kierperlechen Identifizéierer fir all Entrée zréckginn. Dir kënnt benotzen %%physloc%% zesumme mat sys.fn_PhysLocFormatter am SQL Server 2008 a méi héich.

Elo wou mir wëssen datt mir d'Säit an Sales.OrderLines wollten spären, kënne mir all d'Donnéeën an dëser Tabell kucken, déi an der Datedatei #3 op der Säit #70133 gespäichert ass, mat dëser Ufro:

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

Wéi gesot, et ass lues och op klengen Dëscher. Ech hunn NOLOCK op d'Ufro bäigefüügt, well mir nach ëmmer keng Garantie hunn datt d'Donnéeën, déi mir kucke wëllen, genee d'selwecht sinn wéi et war wéi d'Spär entdeckt gouf - also kënne mir sécher dreckeg Liesen maachen.
Awer, hurra, d'Ufro bréngt mir déiselwecht 25 Reihen zréck fir déi eis Ufro gekämpft huet
Entschlësselt Schlëssel a Page WaitResource an Deadlocks a Spären
Genuch iwwer PAGE Spären. Wat wa mir op e KEY Spär waarden?

2) waitresource = "KEY: 6: 72057594041991168 (ce52f92a058c)" = Database_Id, HOBT_Id (Magie Hash, dee mat %%lockres%% entschlësselt ka ginn, wann Dir dat wierklech wëllt)

Wann Är Ufro probéiert e Rekord am Index ze spären a sech selwer gespaart gëtt, kënnt Dir mat enger komplett anerer Aart Adress.
Mir briechen "6: 72057594041991168 (ce52f92a058c)" an Deeler, mir kréien:

  • database_id = 6
  • hobt_id = 72057594041991168
  • magesch Hash = (ce52f92a058c)

2.1) Decrypt database_id

Dëst funktionnéiert genau d'selwecht wéi d'Beispill hei uewen! Fannt den Numm vun der Datebank mat der Ufro:

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

A mengem Fall ass et nach ëmmer d'selwecht DB WideWorldImporters.

2.2) Decrypt hobt_id

Am Kontext vun der fonnter Datebank, musst Dir eng Ufro op sys.partitions mat engem Paar Joint ausféieren, déi hëllefen, d'Nimm vun der Tabell an den Index ze bestëmmen ...

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

Et seet mir, datt d'Ufro war op der Application.Countries Spär benotzt den Index PK_Application_Countries.

2.3) Elo e bësse Magie %%lockres%% - wann Dir wëllt erausfannen wéi eng Entrée gespaart gouf

Wann ech wierklech wëlle wëssen op wéi eng Rei d'Spär war, kann ech erausfannen andeems ech den Dësch selwer ufroen. Mir kënnen déi ondokumentéiert %%lockres%% Funktioun benotzen fir eng Entrée ze fannen déi mam Magie Hash passt.
Notéiert w.e.g. datt dës Ufro de ganzen Dësch scannt, a bei groussen Dëscher kann dëst guer net lëschteg sinn:

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

Ech hunn NOLOCK bäigefüügt (op Avis vum Klaus Aschenbrenner op Twitter) well Blockade kënnen e Problem ginn. Mir wëlle just kucken wat elo do ass, an net wat do war wéi d'Transaktioun ugefaang huet - ech denken net datt d'Datekonsistenz fir eis wichteg ass.
Voila, de Rekord fir dee mir gekämpft hunn!
Entschlësselt Schlëssel a Page WaitResource an Deadlocks a Spären

Unerkennung a weider Liesung

Ech erënnere mech net wien fir d'éischt vill vun dëse Saachen beschriwwen huet, awer hei sinn zwee Posts iwwer déi mannst dokumentéiert Saachen déi Dir gär hätt:

Source: will.com

Setzt e Commentaire