Shkruajmë Key dhe Page WaitResource në bllokime dhe bllokase

Nëse po përdorni raportin mbi bllokimet (blocked process report) ose po grumbulloni grafikat e bllokimeve të ofruara nga SQL Server, herë pas here do të përballeni me gjëra të tilla:

waitresource="PAGE: 6:3:70133"

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

Ndoshta, në atë XML gjigand që po shqyrtoni, do të ketë më shumë informacion (grafikat e bllokimeve përmbajnë një listë burimesh, e cila ndihmon në identifikimin e emrave të objektit dhe indeksit), por jo gjithmonë.

Ky tekst do t'ju ndihmojë ta kuptoni.

Të gjitha informacionet që janë këtu janë në internet në vende të ndryshme, ato janë thjesht shumë të shpërndara! Dua t'i grumbulloj të gjitha së bashku - nga DBCC PAGE te hobt_id dhe funksionet e pa dokumentuara %%physloc%% dhe %%lockres%%.

Së pari, le të flasim për pritjet në bllokimet PAGE, dhe pastaj të kalojmë te bllokimet KEY.

1) waitresource="PAGE: 6:3:70133" = Id_Baze_Datoj: Id_Fajli: Numri_i_Faqes

Nëse pyetja juaj pret për një bllokim PAGE, SQL Server do t'ju japë adresën e kësaj faqe.

Duke e ndarë "PAGE: 6:3:70133" ne marrim:

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

1.1) Shkruajmë database_id

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

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

Kjo është publike Baza e të Dhënave WideWorldImporters në SQL Server-in tim.

1.2) KĂ«rkojmĂ« emrin e fajlit tĂ« tĂ« dhĂ«nave — nĂ«se jeni tĂ« interesuar

Do të përdorim data_file_id në hapin tjetër për të gjetur emrin e tabelës. Mund të kaloni thjesht te hapi tjetër, por nëse jeni të interesuar për emrin e fajlit, mund ta gjeni duke ekzekutuar pyetjen në kontekstin e Baza e të Dhënave të gjetur, duke futur data_file_id në këtë pyetje:

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

Në Baza e të Dhënave WideWorldImporters, ky është një fajll i quajtur WWI_UserData dhe është rikuperuar te C:MSSQLDATAWideWorldImporters_UserData.ndf. (Ups, më kapët teksa vendosja skedarët në disk me sistemin! Jo! Doli në mënyrë të pazakontë).

1.3) Merrni emrin e objektit nga DBCC PAGE

Tani e dimë se faqja #70133 në fajlin e të dhënave 3 i përket Baza e të Dhënave WideWorldImporters. Mund të shohim përmbajtjen e kësaj faqeje duke përdorur DBCC PAGE të pa dokumentuar dhe trace-flag 3604.
ShĂ«nim: preferoj tĂ« pĂ«rdor DBCC PAGE nĂ« njĂ« kopje tĂ« rikuperuar nga backup nĂ« njĂ« server tjetĂ«r, sepse kjo Ă«shtĂ« njĂ« gjĂ« e pa dokumentuar. NĂ« disa raste, ajo mund tĂ« çojĂ« nĂ« krijimin e njĂ« dubliku (shĂ«nim i pĂ«rkthyesit — lidhja, fatkeqĂ«sisht, nuk çon asgjĂ«, por gjykoj sipas url se bĂ«het fjalĂ« pĂ«r indekset e 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 përpara rezultateve, mund të gjeni object_id dhe index_id.
Shkruajmë Key dhe Page WaitResource në bllokime dhe bllokase
Gati! Tani mund të gjeni emrat e tabelës dhe indeksit përmes pyetjes:

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 tani shohim se pritja për bllokimin ishte në indeksin PK_Sales_OrderLines të tabelës Sales.OrderLines.

Shënim: Në SQL Server 2014 dhe më lart, emri i objektit gjithashtu mund të gjendet përmes DMO të pa dokumentuar sys.dm_db_database_page_allocations. Por do t'ju duhet të kërkoni çdo faqe në DB, që duket jo shumë mirë për bazat e të dhënave të mëdha, kështu që unë përdora DBCC PAGE.

1.4) A mund të shohim të dhënat në atë faqe që ishte e bllokuar?

Po, por
 a jeni absolutisht të sigurt se ju nevojitet kjo?
Kjo Ă«shtĂ« e ngadalshme edhe pĂ«r tabela tĂ« vogla. Por Ă«shtĂ« ndonjĂ«herĂ« interesante, kĂ«shtu qĂ«, pĂ«r sa kohĂ« keni arritur nĂ« kĂ«tĂ« pikë  le tĂ« flasim pĂ«r %%physloc%%!

%%physloc%% është një copë magjie e pa dokumentuar që kthen identifikuesin fizik për çdo regjistrim. Ju mund ta përdorni %%physloc%% së bashku me sys.fn_PhysLocFormatter në SQL Server 2008 dhe më lart.

Tani, kur e dimë se kemi dashur të bllokojmë faqen në Sales.OrderLines, mund të shohim të gjitha të dhënat në këtë tabelë, të cilat ruhen në skedarin e të dhënave #3 në faqe #70133, përmes kësaj pyetjeje:

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

Siç thashĂ« — kjo Ă«shtĂ« e ngadalshme edhe pĂ«r tabela tĂ« vogla. Kam shtuar NOLOCK nĂ« pyetje sepse nuk kemi asnjĂ« garanci qĂ« tĂ« dhĂ«nat qĂ« duam tĂ« shohim janĂ« ato tĂ« njĂ«jta qĂ« ishin nĂ« momentin qĂ« u zbulua bllokimi — kĂ«shtu qĂ« mund tĂ« bĂ«jmĂ« lehtĂ«sisht leximet e ndotura.
Por, urra, pyetja më kthen ato 25 rreshta që po luftonim për të marrë
Shkruajmë Key dhe Page WaitResource në bllokime dhe bllokase
Mjaft me bllokimet PAGE. ÇfarĂ« ndodh nĂ«se jemi duke pritur pĂ«r bllokim KEY?

2) waitresource=“KEY: 6:72057594041991168 (ce52f92a058c)” = Database_Id, HOBT_Id (hash magjik qĂ« mund tĂ« dekodifikohet me %%lockres%%, nĂ«se e dĂ«shironi me tĂ« vĂ«rtetĂ«)

Nëse pyetja juaj përpiqet të bllokojë një regjistrim në indeks dhe përfundon duke u bllokuar vetë, merrni një lloj krejtësisht të ndryshëm të adresës.
Duke ndarĂ« “6:72057594041991168 (ce52f92a058c)” nĂ« pjesĂ«, ne marrim:

  • database_id = 6
  • hobt_id = 72057594041991168
  • hashi magjik = (ce52f92a058c)

2.1) Shkruaj database_id

Kjo funksionon pikërisht si shembulli më sipër! Gjejmë emrin e bazës së të dhënave përmes një kërkese:

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

NĂ« rastin tim — Ă«shtĂ« akoma e njĂ«jta Baza e tĂ« DhĂ«nave WideWorldImporters.

2.2) Shkruaj hobt_id

NĂ« kontekstin e bazĂ«s sĂ« tĂ« dhĂ«nave tĂ« gjetur, duhet tĂ« kryhet njĂ« kĂ«rkesĂ« ndaj sys.partitions me çift join-esh qĂ« 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

Ai më thotë se kërkesa ka pritur për bllokimin e Application.Countries, duke përdorur indeksin PK_Application_Countries.

2.3) Tani pak magji %%lockres%% — nĂ«se dĂ«shironi tĂ« zbuloni se cila regjistrim ishte i bllokuar

Nëse vërtet dua të di se mbi cilin rresht ishte nevoja për bllokim, mund ta zbuloj këtë përmes një kërkese ndaj tabelës së vet. Mund të përdorim funksionin e pa dokumentuar %%lockres%% për të gjetur regjistrimin që përputhet me hash-in magjik.
Kujdes, se kjo kërkesë do të skanojë të gjithë tabelën dhe në tabelat e mëdha kjo mund të mos jetë shumë e këndshme:

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

Kam shtuar NOLOCK (sipariß nga Klaus Aschenbrenner nĂ« Twitter) sepse bllokimet mund tĂ« bĂ«hen problem. Duam thjesht tĂ« shikojmĂ« se çfarĂ« ka tani, jo se çfarĂ« ka pasur kur filloi transaksioni — nuk mendoj se Ă«shtĂ« e rĂ«ndĂ«sishme qĂ« tĂ« dhĂ«nat tĂ« jenĂ« tĂ« qĂ«ndrueshme.
Voila, regjistrimi për të cilin luftuam!
Shkruajmë Key dhe Page WaitResource në bllokime dhe bllokase

Faleminderit dhe lexim i mëtejshëm

Nuk e mbaj mend se kush e përshkroi për herë të parë shumë nga këto gjëra, por ja dy postime për gjërat më pak të dokumentuara, që mund t'ju interesojnë:

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster