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.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.
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%%!
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.
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 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!
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: