Deshifroni çelësin dhe burimin e pritjes së faqes në bllokime dhe bllokime

Nëse përdorni raportin e procesit të bllokuar ose mbledhni periodikisht grafikët e bllokimit të ofruar nga SQL Server, do të hasni gjëra të tilla si kjo:

burimi i pritjes="FAQJA: 6:3:70133"

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

Ndonjëherë, do të ketë më shumë informacion në atë XML gjigant që studioni (grafikët e bllokimit përmbajnë një listë burimesh që ju ndihmojnë të gjeni emrat e objektit dhe indeksit), por jo gjithmonë.

Ky tekst do t'ju ndihmojë t'i deshifroni ato.

Të gjitha informacionet që janë këtu janë në internet në vende të ndryshme, thjesht janë shumë të shpërndara! Dua t'i bashkoj të gjitha, nga FAQJA DBCC te hobt_id te funksionet e padokumentuara %%physloc%% dhe %%lockres%%.

Së pari, le të flasim për pritjet në kyçjet e PAGE dhe më pas të kalojmë te kyçet KEY.

1) waitresource="PAGE: 6:3:70133" = ID_Baza e të Dhënave: ID e skedarit: Numri i faqes

Nëse kërkesa juaj është duke pritur në një bllokim PAGE, SQL Server do t'ju japë adresën e asaj faqeje.

Duke zbërthyer "FAQJA: 6:3:70133" marrim:

  • ID_ja e bazës së të dhënave = 6
  • ID_e_dosje_file = 3
  • numri_faqes = 70133

1.1) Deshifroni databazën_id

Gjeni emrin e bazës së të dhënave duke përdorur pyetjen:

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

Është publike DB WideWorldImporters në serverin tim SQL.

1.2) Duke kërkuar për emrin e skedarit të të dhënave - nëse jeni të interesuar

Ne do të përdorim data_file_id në hapin tjetër për të gjetur emrin e tabelës. Thjesht mund të kaloni te hapi tjetër, por nëse jeni të interesuar për emrin e skedarit, mund ta gjeni duke ekzekutuar një pyetje në kontekstin e bazës së të dhënave të gjetur, duke zëvendësuar data_file_id në këtë pyetje:

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

Në bazën e të dhënave WideWorldImporters ky është një skedar i quajtur WWI_UserData dhe e kam rikthyer në C:MSSQLDATAWideWorldImporters_UserData.ndf. (Oops, më kapët duke vendosur skedarë në diskun e sistemit! Jo! Është e turpshme).

1.3) Merrni emrin e objektit nga FAQJA DBCC

Tani e dimë se faqja #70133 në skedarin e të dhënave 3 i përket bazës së të dhënave WorldWideImporters. Ne mund të shikojmë përmbajtjen e kësaj faqeje duke përdorur FAQEN DBCC të padokumentuar dhe gjurmën e flamurit 3604.
Shënim: Unë preferoj të përdor DBCC PAGE në një kopje të restauruar diku në një server tjetër, sepse janë gjëra të padokumentuara. Në disa raste, ajo mund të rezultojë në një hale (përafërsisht. përkthyesi - lidhja, për fat të keq, nuk të çon askund, por duke gjykuar nga url, ne po flasim për indekse të filtruar).

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

Duke lëvizur te rezultatet, mund të gjeni objektin_id dhe index_id.
Deshifroni çelësin dhe burimin e pritjes së faqes në bllokime dhe bllokime
Pothuajse mbarova! Tani mund të gjeni emrat e tabelës dhe të indeksit me një pyetje:

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

Dhe këtu shohim se pritja në bllokim ishte në indeksin PK_Sales_OrderLines të tabelës Sales.OrderLines.

Shënim: Në SQL Server 2014 dhe më lart, emri i objektit mund të gjendet gjithashtu duke përdorur DMO të padokumentuara sys.dm_db_database_page_allocations. Por ju duhet të kërkoni çdo faqe në bazën e të dhënave, e cila nuk duket shumë e lezetshme për bazat e të dhënave të mëdha, kështu që përdora DBCC PAGE.

1.4) A është e mundur të shihen të dhënat në faqen që është bllokuar?

Nuuu, po. Por… a jeni i sigurt që keni vërtet nevojë për të?
Është i ngadalshëm edhe në tavolina të vogla. Por është disi e lezetshme, kështu që meqë keni lexuar deri këtu...le të flasim për %%physloc%%!

%%physloc%% është një pjesë magjike e padokumentuar që kthen një ID fizike për çdo hyrje. ju mund të përdorni %%physloc%% së bashku me sys.fn_PhysLocFormatter në SQL Server 2008 dhe më të lartë.

Tani që e dimë se donim të bllokonim faqen në Sales.OrderLines, mund të shikojmë të gjitha të dhënat në këtë tabelë, e cila ruhet në skedarin e të dhënave #3 në faqen #70133, me pyetjen e mëposhtme:

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

Siç thashë, është e ngadaltë edhe në tavolina të vogla. I shtova NOLOCK kërkesës sepse ne ende nuk kemi asnjë garanci që të dhënat që duam të shikojmë janë saktësisht të njëjta me atë në kohën kur u zbulua bllokimi - kështu që ne mund të bëjmë me siguri lexime të pista.
Por, horay, pyetja më kthen 25 rreshtat për të cilat luftoi pyetja jonë.
Deshifroni çelësin dhe burimin e pritjes së faqes në bllokime dhe bllokime
Mjaft për kyçjet e PAGE. Po sikur të presim për një bllokim KEY?

2) waitresource="KEY: 6:72057594041991168 (ce52f92a058c)" = Data_Id, HOBT_Id (hash magjik që mund të deshifrohet me %%lockres%% nëse vërtet dëshironi)

Nëse pyetja juaj përpiqet të bllokojë një hyrje të indeksit dhe bllokohet vetë, ju merrni një lloj adrese krejtësisht të ndryshme.
Duke e ndarë "6:72057594041991168 (ce52f92a058c)" në pjesë, marrim:

  • ID_ja e bazës së të dhënave = 6
  • hobt_id = 72057594041991168
  • hash magjik = (ce52f92a058c)

2.1) Deshifroni databazën_id

Ajo funksionon saktësisht njësoj si me shembullin e mësipërm! Ne gjejmë emrin e bazës së të dhënave duke përdorur pyetjen:

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

Në rastin tim, është e njëjta gjë DB WideWorldImporters.

2.2) Deshifroni hobt_id

Në kontekstin e bazës së të dhënave të gjetur, ju duhet të kërkoni sys.partitions me disa bashkime që do të ndihmojnë në përcaktimin e emrave të tabelës dhe indeksit ...

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

Më tregon se kërkesa ishte duke pritur në bllokimin Application.Countries duke përdorur indeksin PK_Application_Countries.

2.3) Tani për disa %%lockres%% magji - nëse doni të zbuloni se cila hyrje ishte e kyçur

Nëse vërtet dua të di se në cilin rresht duhej bllokimi, mund ta zbuloj duke pyetur vetë tabelën. Mund të përdorim funksionin e padokumentuar %%lockres%% për të gjetur një hyrje që përputhet me hash-in magjik.
Vini re se kjo pyetje do të skanojë të gjithë tabelën dhe në tavolina të mëdha kjo mund të mos jetë aspak argëtuese:

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

kam shtuar NOLOCK (me këshillën e Klaus Aschenbrenner në Twitter) sepse bravat mund të jenë problem. Ne thjesht duam të shikojmë atë që është atje tani, dhe jo atë që ishte aty kur filloi transaksioni - nuk mendoj se konsistenca e të dhënave është e rëndësishme për ne.
Voila, rekordi për të cilin luftuam!
Deshifroni çelësin dhe burimin e pritjes së faqes në bllokime dhe bllokime

Mirënjohje dhe lexim të mëtejshëm

Nuk mbaj mend se kush i përshkroi i pari shumë nga këto gjëra, por këtu janë dy postime për gjërat më pak të dokumentuara që mund t'ju pëlqejnë:

Burimi: www.habr.com

Shto një koment