Decipher Key lan Page WaitResource ing deadlocks lan kunci

Yen sampeyan nggunakake laporan proses sing diblokir utawa ngumpulake grafik deadlock sing diwenehake dening SQL Server kanthi periodik, sampeyan bakal nemokake kaya iki:

waitresource="kaca: 6:3:70133"

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

Kadhangkala, bakal ana informasi liyane ing XML raksasa sing sampeyan sinau (grafik deadlock ngemot dhaptar sumber daya sing mbantu sampeyan ngerteni jeneng obyek lan indeks), nanging ora mesthi.

Tèks iki bakal mbantu nerjemahake.

Kabeh informasi ing kene ana ing Internet ing macem-macem panggonan, mung disebarake! Aku pengin sijine kabeh bebarengan, saka DBCC PAGE kanggo hobt_id kanggo undocumented %% physloc%% lan %% lockres%% fungsi.

Pisanan, ayo ngomong babagan ngenteni ing kunci PAGE, banjur pindhah menyang kunci KEY.

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

Yen panjaluk sampeyan nunggu ing kunci PAGE, SQL Server bakal menehi alamat kaca kasebut.

Mbusak "HALAMAN: 6: 3: 70133" kita entuk:

  • id_database = 6
  • data_file_id = 3
  • kaca_nomer = 70133

1.1) Dekripsi database_id

Temokake jeneng database nggunakake pitakon:

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

Iku umum DB WideWorldImporters ing SQL Server.

1.2) Nggoleki jeneng file data - yen sampeyan kasengsem

Kita bakal nggunakake data_file_id ing langkah sabanjure kanggo nemokake jeneng tabel. Sampeyan mung bisa mlumpat menyang langkah sabanjure, nanging yen sampeyan kasengsem ing jeneng berkas, sampeyan bisa nemokake kanthi mbukak pitakon ing konteks database sing ditemokake, ngganti data_file_id menyang pitakon iki:

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

Ing database WideWorldImporters iki file disebut WWI_UserData lan aku wis dibalèkaké kanggo C: MSSQLDATAWideWorldImporters_UserData.ndf. (Oops, sampeyan kejiret aku sijine file ing drive sistem! Ora! Iku isin).

1.3) Entuk jeneng obyek saka DBCC PAGE

Saiki kita ngerti manawa kaca #70133 ing file data 3 kalebu ing database WorldWideImporters. Kita bisa ndeleng isi kaca iki nggunakake DBCC PAGE sing ora didokumentasikan lan nglacak flag 3604.
Wigati: Aku luwih seneng nggunakake DBCC PAGE ing salinan dibalèkaké nang endi wae ing server liyane, amarga iku undocumented barang. Ing sawetara kasus, dheweke bisa nyebabake dump (kira-kira. penerjemah - link, sayangé, ora ndadékaké, nanging miturut url, kita ngomong babagan indeks sing disaring).

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

Kanthi nggulung menyang asil, sampeyan bisa nemokake object_id lan index_id.
Decipher Key lan Page WaitResource ing deadlocks lan kunci
Meh rampung! Saiki sampeyan bisa nemokake jeneng tabel lan indeks kanthi pitakon:

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

Lan kene kita waca sing Enteni ing kunci ana ing indeks PK_Sales_OrderLines Tabel Sales.OrderLines.

Cathetan: Ing SQL Server 2014 lan ndhuwur, jeneng obyek uga bisa ditemokake nggunakake DMO sys.dm_db_database_page_allocations sing ora duwe dokumen. Nanging sampeyan kudu takon saben kaca ing database, kang ora katon banget kelangan kanggo database gedhe, aku digunakake DBCC PAGE.

1.4) Apa bisa ndeleng data ing kaca sing diblokir?

Nuhun, iya. Nanging ... apa sampeyan yakin sampeyan butuh banget?
Iku alon sanajan ing meja cilik. Nanging iki rada kelangan, mula sampeyan wis maca nganti saiki ... ayo ngomong babagan %%physloc%%!

%% physloc%% minangka potongan sihir sing ora duwe dokumen sing ngasilake ID fisik kanggo saben entri. sampeyan bisa nggunakake %%physloc%% bebarengan karo sys.fn_PhysLocFormatter ing SQL Server 2008 lan mengko.

Saiki kita ngerti yen kita pengin mblokir kaca ing Sales.OrderLines, kita bisa ndeleng kabeh data ing tabel iki, sing disimpen ing file data #3 ing kaca #70133, kanthi pitakon ing ngisor iki:

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

Kaya sing dakkandhakake, iku alon sanajan ing meja cilik. Aku nambahake NOLOCK menyang panyuwunan amarga kita isih ora njamin yen data sing arep kita deleng persis padha karo nalika kunci ditemokake - supaya kita bisa kanthi aman nindakake maca sing reged.
Nanging, hooray, pitakon kasebut ngasilake 25 larik sing ditindakake pitakon.
Decipher Key lan Page WaitResource ing deadlocks lan kunci
Cukup babagan kunci PAGE. Apa yen kita ngenteni kunci KUNCI?

2) waitresource = "KEY: 6: 72057594041991168 (ce52f92a058c)" = Database_Id, HOBT_Id (hash sihir sing bisa didekripsi nganggo %%lockres%% yen sampeyan pengin)

Yen pitakon sampeyan nyoba ngunci entri indeks lan dikunci dhewe, sampeyan bakal entuk jinis alamat sing beda.
Mbusak "6: 72057594041991168 (ce52f92a058c)" dadi bagean, kita entuk:

  • id_database = 6
  • hobt_id = 72057594041991168
  • hash ajaib = (ce52f92a058c)

2.1) Dekripsi database_id

Kerjane persis padha karo conto ing ndhuwur! Kita nemokake jeneng database nggunakake pitakon:

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

Ing kasusku, iku padha DB WideWorldImporters.

2.2) Dekripsi hobt_id

Ing konteks database sing ditemokake, sampeyan kudu takon sys.partitions karo sawetara gabungan sing bakal mbantu nemtokake jeneng tabel lan indeks ...

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

Iku ngandhani yen panjalukan wis nunggu ing Application.Countries kunci nggunakake indeks PK_Application_Countries.

2.3) Saiki kanggo sawetara %%lockres%% sihir - yen sampeyan pengin ngerteni entri sing dikunci

Yen aku pancene pengin ngerti ing baris endi kunci sing dibutuhake, aku bisa ngerteni kanthi takon tabel kasebut dhewe. Kita bisa nggunakake fungsi undocumented %% lockres%% kanggo nemokake entri sing cocog karo hash sihir.
Elinga yen pitakon iki bakal mindai kabeh tabel, lan ing tabel gedhe iki bisa uga ora nyenengake:

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

Aku nambah NOLOCK (ing saran saka Klaus Aschenbrenner ing twitter) amarga kunci bisa dadi masalah. Kita mung pengin ndeleng apa sing ana saiki, lan dudu apa sing ana nalika transaksi diwiwiti - Aku ora mikir yen konsistensi data penting kanggo kita.
Voila, rekor sing kita geluti!
Decipher Key lan Page WaitResource ing deadlocks lan kunci

Matur nuwun lan maca luwih lanjut

Aku ora ngelingi sapa sing pisanan njlentrehake babagan iki, nanging ana rong kiriman babagan perkara sing paling ora didokumentasikake sing sampeyan seneng:

Source: www.habr.com

Add a comment