ProHoster > Blog > administratë > Deshifroni çelësin dhe burimin e pritjes së faqes në bllokime dhe bllokime
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:
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
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.
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%%!
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ë.
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ë 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!
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ë: