Ĉifri Ŝlosilon kaj Paĝo WaitResource en blokiĝoj kaj seruroj

Se vi uzas la blokitan procezan raporton aŭ kolektas la blokiĝajn grafikojn provizitajn de SQL-Servilo periode, vi renkontos aferojn kiel ĉi tion:

waitresource = "PAĜO: 6:3:70133"

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

Kelkfoje, estos pli da informoj en tiu giganta XML, kiun vi studas (blokaj grafikaĵoj enhavas liston de rimedoj, kiuj helpas vin eltrovi la nomojn de la objekto kaj indekso), sed ne ĉiam.

Ĉi tiu teksto helpos vin deĉifri ilin.

Ĉiuj informoj, kiuj estas ĉi tie, estas en la interreto en diversaj lokoj, ĝi simple estas tre distribuata! Mi volas kunmeti ĉion, de DBCC PAGE ĝis hobt_id ĝis la nedokumentitaj %%physloc%% kaj %%lockres%% funkcioj.

Unue, ni parolu pri atendoj sur PAĜAJ seruroj, kaj poste transiru al KEY-seruroj.

1) waitresource = "PAGE: 6:3:70133" = Datumbazo_Id: FileId: PaĝoNumero

Se via peto atendas sur PAĜA seruro, SQL-Servilo donos al vi la adreson de tiu paĝo.

Malkonstruante "PAGE: 6:3:70133" ni ricevas:

  • datumbazo_id = 6
  • data_file_id = 3
  • paĝo_numero = 70133

1.1) Malĉifri database_id

Trovu la nomon de la datumbazo uzante la demandon:

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

Ĝi estas publika DB WideWorldImporters sur mia SQL-Servilo.

1.2) Serĉante la nomon de la datumdosiero - se vi interesiĝas

Ni uzos data_file_id en la sekva paŝo por trovi la tabelnomon. Vi povas simple transsalti al la sekva paŝo, sed se vi interesiĝas pri la dosiernomo, vi povas trovi ĝin farante demandon en la kunteksto de la trovita datumbazo, anstataŭigante data_file_id en ĉi tiu demando:

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

En la datumbazo WideWorldImporters ĉi tio estas dosiero nomata WWI_UserData kaj mi reestigis ĝin al C:MSSQLDATAWideWorldImporters_UserData.ndf. (Ho, vi kaptis min metante dosierojn sur la sisteman diskon! Ne! Estas embarase).

1.3) Akiru objektonomon de DBCC PAĜO

Ni nun scias, ke paĝo #70133 en datumdosiero 3 apartenas al la datumbazo WorldWideImporters. Ni povas rigardi la enhavon de ĉi tiu paĝo uzante la nedokumentitan DBCC-PAĜO kaj spura flago 3604.
Noto: Mi preferas uzi DBCC-PAĜON sur restarigita kopio ie sur alia servilo, ĉar ĝi estas nedokumentita aĵo. En iuj kazoj, ŝi povas rezultigi rubejon (ĉ. tradukisto - la ligilo bedaŭrinde kondukas nenien, sed juĝante laŭ la url, ni parolas pri filtritaj indeksoj).

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

Rulumlante al la rezultoj, vi povas trovi la object_id kaj index_id.
Ĉifri Ŝlosilon kaj Paĝo WaitResource en blokiĝoj kaj seruroj
Preskaŭ farita! Nun vi povas trovi la tabelajn kaj indeksajn nomojn kun demando:

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

Kaj ĉi tie ni vidas, ke la atendo sur la seruro estis sur la indekso PK_Sales_OrderLines de la tablo Sales.OrderLines.

Noto: En SQL Server 2014 kaj supre, la objektonomo ankaŭ troveblas uzante la nedokumentitan DMO sys.dm_db_database_page_allocations. Sed vi devas pridemandi ĉiun paĝon en la datumbazo, kiu ne aspektas tre bonega por grandaj datumbazoj, do mi uzis DBCC PAGE.

1.4) Ĉu eblas vidi la datumojn sur la paĝo kiu estis blokita?

Nuuu, jes. Sed... ĉu vi certas, ke vi vere bezonas ĝin?
Ĝi estas malrapida eĉ sur malgrandaj tabloj. Sed estas iom mojosa, do ĉar vi legis ĉi tien... ni parolu pri %%physloc%%!

%%physloc%% estas nedokumentita magio, kiu resendas fizikan identigilon por ĉiu eniro. vi povas uzi %%physloc%% kune kun sys.fn_PhysLocFormatter en SQL Server 2008 kaj supre.

Nun kiam ni scias, ke ni volis bloki la paĝon en Sales.OrderLines, ni povas rigardi ĉiujn datumojn en ĉi tiu tabelo, kiu estas konservita en datumdosiero #3 sur paĝo #70133, kun la sekva demando:

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

Kiel mi diris, ĝi malrapidas eĉ sur etaj tabloj. Mi aldonis NOLOCK al la peto ĉar ni ankoraŭ ne havas garantiojn, ke la datumoj, kiujn ni volas rigardi, estas ĝuste la samaj, kiel ĝi estis en la momento, kiam la seruro estis malkovrita - do ni povas sekure fari malpurajn legadojn.
Sed, hure, la demando resendas al mi la tre 25 vicojn por kiuj batalis nia demando.
Ĉifri Ŝlosilon kaj Paĝo WaitResource en blokiĝoj kaj seruroj
Sufiĉe pri PAGE-ŝlosado. Kio se ni atendas ŝlosilon?

2) waitresource="KEY: 6:72057594041991168 (ce52f92a058c)" = Database_Id, HOBT_Id (magia hash kiu povas esti malĉifrita per %%lockres%% se vi vere volas)

Se via demando provas ŝlosi sur indeksa eniro kaj estas ŝlosita memstare, vi ricevas tute alian specon de adreso.
Rompante "6:72057594041991168 (ce52f92a058c)" en partojn, ni ricevas:

  • datumbazo_id = 6
  • hobt_id = 72057594041991168
  • magia haŝo = (ce52f92a058c)

2.1) Malĉifri database_id

Ĝi funkcias ĝuste same kiel kun la supra ekzemplo! Ni trovas la nomon de la datumbazo uzante la demandon:

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

En mia kazo, estas same DB WideWorldImporters.

2.2) Malĉifri hobt_id

En la kunteksto de la trovita datumbazo, vi devas pridemandi sys.partitions kun kelkaj kuniĝoj, kiuj helpos determini la nomojn de la tabelo kaj indekso ...

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

Ĝi diras al mi, ke la peto atendis ĉe la Apliko.Lando-ŝlosilo uzante la indekso PK_Application_Countries.

2.3) Nun por iom %%lockres%% magio - se vi volas ekscii, kiu eniro estis ŝlosita

Se mi vere volas scii sur kiu vico la seruro estis bezonata, mi povas ekscii pridemandante la tabelon mem. Ni povas uzi la nedokumentitan %%lockres%% funkcion por trovi eniron kiu kongruas kun la magia hash.
Notu, ke ĉi tiu demando skanos la tutan tabelon, kaj sur grandaj tabeloj tio eble tute ne amuzas:

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

Mi aldonis NOLOCK (laŭ la konsilo de Klaus Aschenbrenner ĉe tvitero) ĉar seruroj povas esti problemo. Ni nur volas rigardi kio estas tie nun, kaj ne kio estis tie kiam la transakcio komenciĝis - mi ne pensas, ke tiu datuma konsistenco estas grava por ni.
Voila, la rekordo por kiu ni batalis!
Ĉifri Ŝlosilon kaj Paĝo WaitResource en blokiĝoj kaj seruroj

Dankon kaj plua legado

Mi ne memoras, kiu unue priskribis multajn el ĉi tiuj aferoj, sed jen du afiŝoj pri la malplej dokumentitaj aferoj, kiujn vi eble ŝatos:

fonto: www.habr.com

Aldoni komenton