Дешифрујте кључ и Паге ВаитРесоурце у застојима и закључавањима

Ако користите извештај о блокираном процесу или периодично прикупљате графиконе застоја које пружа СКЛ Сервер, наићи ћете на следеће ствари:

ваитресоурце="ПАГЕ: 6:3:70133"

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

Понекад ће у том огромном КСМЛ-у који проучавате бити више информација (графови застоја садрже листу ресурса који вам помажу да сазнате имена објекта и индекса), али не увек.

Овај текст ће вам помоћи да их дешифрујете.

Све информације које се овде налазе налазе се на интернету на разним местима, једноставно су веома дистрибуиране! Желим све да спојим, од ДБЦЦ ПАГЕ до хобт_ид до недокументованих функција %%пхислоц%% и %%лоцкрес%%.

Прво, хајде да причамо о чекању на закључавање СТРАНА, а затим пређимо на КЕИ закључавање.

1) ваитресоурце="ПАГЕ: 6:3:70133" = Датабасе_Ид: ФилеИд: ПагеНумбер

Ако ваш захтев чека на закључавање ПАГЕ, СКЛ Сервер ће вам дати адресу те странице.

Растављајући „ПАГЕ: 6:3:70133“ добијамо:

  • ид_базе података = 6
  • дата_филе_ид = 3
  • број_странице = 70133

1.1) Дешифровање базе_ид

Пронађите име базе података помоћу упита:

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

Јавно је ДБ ВидеВорлдИмпортерс на мом СКЛ серверу.

1.2) Тражите назив датотеке са подацима - ако сте заинтересовани

Користићемо дата_филе_ид у следећем кораку да пронађемо име табеле. Можете само да пређете на следећи корак, али ако вас занима име датотеке, можете га пронаћи покретањем упита у контексту пронађене базе података, замењујући дата_филе_ид у овај упит:

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

У бази података ВидеВорлдИмпортерс ово је датотека која се зове ВВИ_УсерДата и вратила сам је у Ц:МССКЛДАТАВидеВорлдИмпортерс_УсерДата.ндф. (Упс, ухватили сте ме како стављам датотеке на системски диск! Не! То је срамотно).

1.3) Добијте име објекта са ДБЦЦ ПАГЕ

Сада знамо да страница #70133 у датотеци података 3 припада бази података ВорлдВидеИмпортерс. Можемо погледати садржај ове странице користећи недокументовану ДБЦЦ ПАГЕ и заставицу праћења 3604.
Напомена: Више волим да користим ДБЦЦ ПАГЕ на обновљеној копији негде на другом серверу, јер је то недокументована ствар. У неким случајевима она може резултирати депонијом (прибл. преводилац - линк, нажалост, не води никуда, али судећи по урл-у, говоримо о филтрираним индексима).

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

Померањем до резултата можете пронаћи објецт_ид и индек_ид.
Дешифрујте кључ и Паге ВаитРесоурце у застојима и закључавањима
Скоро готов! Сада можете пронаћи називе табела и индекса помоћу упита:

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

И овде видимо да је чекање на закључавање било на ПК_Салес_ОрдерЛинес индексу табеле Салес.ОрдерЛинес.

Напомена: У СКЛ Сервер 2014 и новијим верзијама, име објекта се такође може пронаћи помоћу недокументованог ДМО-а сис.дм_дб_датабасе_паге_аллоцатионс. Али морате да питате сваку страницу у бази података, што не изгледа баш кул за велике базе података, па сам користио ДБЦЦ ПАГЕ.

1.4) Да ли је могуће видети податке на страници која је блокирана?

Нууу, да. Али... да ли сте сигурни да вам је заиста потребно?
Споро је чак и на малим столовима. Али је некако кул, па пошто сте читали довде... хајде да причамо о %%пхислоц%%!

%%пхислоц%% је недокументовани део магије који враћа физички ИД за сваки унос. можете користити %%пхислоц%% заједно са сис.фн_ПхисЛоцФорматтер у СКЛ Серверу 2008 и новијим.

Сада када знамо да желимо да блокирамо страницу у Салес.ОрдерЛинес, можемо погледати све податке у овој табели, која је ускладиштена у датотеци података #3 на страници #70133, са следећим упитом:

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

Као што сам рекао, споро је чак и на малим столовима. Додао сам НОЛОЦК захтеву јер још увек немамо гаранције да су подаци које желимо да погледамо потпуно исти као у време када је закључавање откривено - тако да можемо безбедно да вршимо прљава читања.
Али, ура, упит ми враћа оних 25 редова за које се наш упит борио
Дешифрујте кључ и Паге ВаитРесоурце у застојима и закључавањима
Доста о закључавању ПАГЕ. Шта ако чекамо кључну браву?

2) ваитресоурце="КЕИ: 6:72057594041991168 (це52ф92а058ц)" = Датабасе_Ид, ХОБТ_Ид (магични хеш који се може дешифровати са %%лоцкрес%% ако заиста желите)

Ако ваш упит покуша да закључа унос у индексу и буде закључан сам, добићете потпуно другачији тип адресе.
Разбијајући „6:72057594041991168 (це52ф92а058ц)“ на делове, добијамо:

  • ид_базе података = 6
  • хобт_ид = 72057594041991168
  • магични хеш = (це52ф92а058ц)

2.1) Дешифровање базе_ид

Ради потпуно исто као у горњем примеру! Назив базе података проналазимо помоћу упита:

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

У мом случају је исто ДБ ВидеВорлдИмпортерс.

2.2) Дешифрујте хобт_ид

У контексту пронађене базе података, потребно је да упитате сис.партитионс са неколико спојева који ће вам помоћи да одредите имена табеле и индекса ...

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

Каже ми да је захтев чекао на закључавању Апплицатион.Цоунтриес користећи индекс ПК_Апплицатион_Цоунтриес.

2.3) Сада за мало %%лоцкрес%% магије - ако желите да сазнате који је унос закључан

Ако заиста желим да знам у ком реду је била потребна брава, могу сазнати упитом у самој табели. Можемо да користимо недокументовану функцију %%лоцкрес%% да пронађемо унос који одговара магичном хешу.
Имајте на уму да ће овај упит скенирати целу табелу, а на великим табелама ово можда уопште није забавно:

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

Додао сам НОЛОЦК (по савету Клауса Ашенбренера на Твитеру) јер браве могу бити проблем. Желимо само да погледамо шта је ту сада, а не шта је било када је трансакција почела – не мислим да нам је конзистентност података важна.
Воила, рекорд за који смо се борили!
Дешифрујте кључ и Паге ВаитРесоурце у застојима и закључавањима

Признања и даље читање

Не сећам се ко је први описао многе од ових ствари, али ево два поста о најмање документованим стварима које би вам се могле свидети:

Извор: ввв.хабр.цом

Додај коментар