Untsiferje Key en Page WaitResource yn deadlocks en slûzen

As jo ​​​​it blokkearre prosesrapport brûke of de deadlock-grafiken sammelje dy't periodyk troch SQL Server levere wurde, sille jo dingen lykas dit tsjinkomme:

waitresource="PAGE: 6:3:70133"

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

Soms sil d'r mear ynformaasje wêze yn dy gigantyske XML dy't jo studearje (deadlock-grafiken befetsje in list mei boarnen dy't jo helpt om it objekt- en yndeksnammen út te finen), mar net altyd.

Dizze tekst sil jo helpe om se te ûntsiferjen.

Alle ynformaasje dy't hjir is is op it ynternet op ferskate plakken, it is gewoan heul ferspraat! Ik wol alles byinoar sette - fan DBCC PAGE oant hobt_id en nei de net dokuminteare %%physloc%% en %%lockres%% funksjes.

Lit ús earst prate oer wachtsjen op PAGE-slûzen, en dan geane wy ​​troch nei KEY-slûzen.

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

As jo ​​query wachtet op in PAGE-slot, sil SQL Server jo it adres fan dy side jaan.

Troch "PAGE: 6:3:70133" ôf te brekken krije wy:

  • database_id = 6
  • data_file_id = 3
  • side_nûmer = 70133

1.1) Untsiferje database_id

Litte wy de databasenamme fine mei de query:

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

Dit is iepenbier DB WideWorldImporters op myn SQL Server.

1.2) Op syk nei de namme fan it gegevensbestân - as jo ynteressearre binne

Wy sille data_file_id brûke yn 'e folgjende stap om de tabelnamme te finen. Jo kinne gewoan oerslaan nei de folgjende stap, mar as jo ynteressearre binne yn 'e triemnamme, kinne jo it fine troch in query út te fieren yn' e kontekst fan 'e fûn databank, troch data_file_id te ferfangen yn dizze query:

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

Yn de WideWorldImporters databank dit is in triem neamd WWI_UserData en ik haw it weromset nei C: MSSQLDATA WideWorldImporters_UserData.ndf. (Oeps, jo hawwe my betrape dat ik bestannen op de systeemskiif sette! Nee! Dat wie ûnhandich).

1.3) Krij de objektnamme fan DBCC PAGE

No witte wy dat side #70133 yn gegevensbestân 3 heart by de WorldWideImporters-database. Wy kinne de ynhâld fan dizze side besjen mei de net-dokumintearre DBCC PAGE en trace flagge 3604.
Opmerking: ik leaver DBCC PAGE te brûken op in restaurearre kopy fan in reservekopy earne op in oare server, om't it in net dokumintearre ding is. Yn guon gefallen, sy kin resultearje yn in dump wurdt oanmakke (ca. oersetter - de keppeling, spitigernôch, liedt nearne, mar beoardielje troch de url, wy prate oer filtere yndeksen).

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

Troch troch de resultaten te rôljen kinne jo object_id en index_id fine.
Untsiferje Key en Page WaitResource yn deadlocks en slûzen
Hast klear! No kinne jo de tabel- en yndeksnammen fine mei de query:

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 no sjogge wy dat it slotwachtsjen wie op 'e PK_Sales_OrderLines-yndeks fan' e Sales.OrderLines-tabel.

Opmerking: Yn SQL Server 2014 en letter kin de objektnamme ek fûn wurde mei de net-dokumintearre DMO sys.dm_db_database_page_allocations. Mar jo moatte elke side yn 'e databank freegje, dy't net heul cool sjocht foar grutte databases, dus ik brûkte DBCC PAGE.

1.4) Is it mooglik om de gegevens te sjen op 'e side dy't blokkearre is?

No ja. Mar ... binne jo wis dat jo it echt nedich hawwe?
It is stadich sels op lytse tafels. Mar it is wat cool, dus om't jo sa fier lêzen hawwe ... litte wy it oer %%physloc%% hawwe!

%%physloc%% is in net dokumintearre stik magy dat in fysike identifier foar elke yngong werombringt. jo kinne brûke %%physloc%% tegearre mei sys.fn_PhysLocFormatter yn SQL Server 2008 en heger.

No't wy witte dat wy de side yn Sales.OrderLines beskoattelje woene, kinne wy ​​nei alle gegevens sjen yn dizze tabel, dy't opslein is yn gegevensbestân #3 op side #70133, mei dizze query:

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

Lykas ik sei, it is stadich sels op lytse tafels. Ik haw NOLOCK tafoege oan it fersyk, om't wy noch gjin garânsje hawwe dat de gegevens wêr't wy nei wolle sjen krekt itselde binne as doe't it slot waard ûntdutsen - dus kinne wy ​​feilich smoarch lêzen dwaan.
Mar, hoera, de query jout my deselde 25 rigen werom dêr't ús query foar fochten
Untsiferje Key en Page WaitResource yn deadlocks en slûzen
Genôch oer PAGE-slûzen. Wat as wy wachtsje op in KEY slot?

2) waitresource = "KEY: 6: 72057594041991168 (ce52f92a058c)" = Database_Id, HOBT_Id (magyske hash dy't kin wurde ûntsifere mei %%lockres%% as jo dat echt wolle)

As jo ​​query besiket in rekord yn 'e yndeks te sluten en sels beskoattele wurdt, komme jo op in folslein oar type adres.
Troch "6: 72057594041991168 (ce52f92a058c)" yn dielen te brekken, krije wy:

  • database_id = 6
  • hobt_id = 72057594041991168
  • magyske hash = (ce52f92a058c)

2.1) Untsiferje database_id

Dit wurket krekt itselde as it foarbyld hjirboppe! Fyn de databasenamme mei de query:

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

Yn myn gefal is it noch altyd itselde DB WideWorldImporters.

2.2) Hobt_id ûntsiferje

Yn 'e kontekst fan' e fûn databank moatte jo in query útfiere nei sys.partitions mei in pear joins dy't helpe om de nammen fan 'e tabel en yndeks te bepalen ...

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

It fertelt my dat it fersyk wachte op de Application.Countries slot mei help fan de PK_Application_Countries yndeks.

2.3) No in bytsje magy %%lockres%% - as jo wolle útfine hokker yngong is beskoattele

As ik echt wol witte hokker rige it slot wie op, Ik kin fine út troch in query de tabel sels. Wy kinne de net-dokumintearre %%lockres%%-funksje brûke om in yngong te finen dy't oerienkomt mei de magyske hash.
Tink derom dat dizze query de hiele tabel scant, en op grutte tabellen kin dit hielendal net leuk wêze:

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

Ik haw NOLOCK tafoege (op advys fan Klaus Aschenbrenner op Twitter) om't blokkades in probleem wurde kinne. Wy wolle gewoan sjen nei wat der no is, en net wat der wie doe't de transaksje begon - ik tink net dat gegevenskonsistinsje foar ús wichtich is.
Voila, it rekord dêr't wy foar fochten!
Untsiferje Key en Page WaitResource yn deadlocks en slûzen

Acknowledgements en fierder lêzen

Ik herinner my net wa't earst in protte fan dizze dingen beskreau, mar hjir binne twa berjochten oer de minst dokuminteare dingen dy't jo miskien leuk fine:

Boarne: www.habr.com

Add a comment