Ачкычтын жана беттин күтүү ресурсун туюк жана кулпуларда чечмелөө

Эгер сиз бөгөттөлгөн процесстин отчетун колдонсоңуз же SQL Server тарабынан берилген туюк графиктерди мезгил-мезгили менен чогултсаңыз, сиз төмөнкүдөй нерселерге туш болосуз:

waitresource=“PAGE: 6:3:70133“

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

Кээде сиз окуп жаткан гигант XMLде көбүрөөк маалымат болот (туйрук диаграммалары объектти жана индекстин аталыштарын табууга жардам берген ресурстардын тизмесин камтыйт), бирок дайыма эмес.

Бул текст аларды чечмелөөгө жардам берет.

Бул жерде бардык маалыматтар ар кайсы жерлерде Интернетте, ал жөн гана абдан таратылган! Мен баарын бириктиргим келет - DBCC PAGEден hobt_idге жана документтештирилбеген %%physloc%% жана %%lockres%% функцияларына чейин.

Биринчиден, келгиле, PAGE кулпуларындагы күтүүлөр жөнүндө сүйлөшөлү, андан кийин биз KEY кулпуларына өтөбүз.

1) waitresource=“PAGE: 6:3:70133” = Database_Id: FileId: PageNumber

Эгерде сиздин сурооңуз PAGE кулпусун күтүп жатса, SQL Server сизге ошол барактын дарегин берет.

"PAGE: 6:3:70133" дегенди бөлүү менен биз төмөнкүнү алабыз:

  • database_id = 6
  • data_file_id = 3
  • бет_саны = 70133

1.1) Database_id шифрин чечмелөө

Сурамдын жардамы менен маалымат базасынын атын табалы:

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

Бул коомдук DB WideWorldImporters менин SQL серверимде.

1.2) Маалымат файлынын атын издеп - эгер сизди кызыктырса

Таблица атын табуу үчүн кийинки кадамда data_file_id колдонобуз. Сиз жөн гана кийинки кадамга өтсөңүз болот, бирок сиз файлдын аталышына кызыгып жатсаңыз, аны бул сурамда data_file_id алмаштырып, табылган маалымат базасынын контекстинде суроону иштетүү аркылуу таба аласыз:

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

WideWorldImporters маалымат базасында бул WWI_UserData деп аталган файл жана мен аны C:MSSQLDATAWideWorldImporters_UserData.ndf деп калыбына келтирдим. (Ой, сиз мени тутумдук дискке файлдарды коюп жатып кармап алдыңыз! Жок! Ыңгайсыз болду).

1.3) Объекттин атын DBCC PAGEден алыңыз

Эми биз №70133 маалымат файлындагы 3-бет WorldWideImporters маалымат базасына таандык экенин билебиз. Биз бул барактын мазмунун документтештирилбеген DBCC PAGE жана 3604 байкоо желеги аркылуу карай алабыз.
Эскертүү: Мен DBCC PAGEди башка сервердеги резервдик көчүрмөдөн калыбына келтирилген көчүрмөдө колдонууну жактырам, анткени бул документтештирилбеген нерсе. Кээ бир учурларда, ал таштандынын пайда болушуна алып келиши мүмкүн (болжол менен котормочу - шилтеме, тилекке каршы, эч жакка алып барбайт, бирок url ​​боюнча, биз чыпкаланган индекстер жөнүндө сөз болуп жатат).

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

Натыйжаларды сыдырып, сиз object_id жана index_id таба аласыз.
Ачкычтын жана беттин күтүү ресурсун туюк жана кулпуларда чечмелөө
Дээрлик бүттү! Эми сиз суроону колдонуу менен таблица жана индекс аттарын таба аласыз:

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

Эми биз кулпу күтүү Sales.OrderLines таблицасынын PK_Sales_OrderLines индексинде болгонун көрөбүз.

Эскертүү: SQL Server 2014 жана андан кийинки версияларында объекттин атын документтештирилбеген DMO sys.dm_db_database_page_allocations аркылуу да тапса болот. Бирок сиз базанын ар бир барагын сурашыңыз керек, бул чоң маалымат базалары үчүн анча деле сонун көрүнбөйт, ошондуктан мен DBCC PAGE колдондум.

1.4) Бөгөттөлгөн баракчадагы маалыматтарды көрүүгө болобу?

Ооба, ооба. Бирок... ал чындап керек экенине ишенесиңби?
Ал кичинекей столдордо да жай. Бирок бул кандай сонун, андыктан сиз ушуга чейин окуганыңыздан бери... %%physloc%% жөнүндө сүйлөшөлү!

%%physloc%% - бул ар бир жазуу үчүн физикалык идентификаторду кайтарган сыйкырдын документтештирилбеген бөлүгү. Сиз колдоно аласыз %%physloc%% жана sys.fn_PhysLocFormatter менен SQL Server 2008 жана андан жогору.

Эми биз Sales.OrderLines баракчасын кулпулоону каалаганыбызды билгенден кийин, бул суроону колдонуу менен №3 беттеги №70133 маалымат файлында сакталган бул таблицадагы бардык маалыматтарды карай алабыз:

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

Мен айткандай, ал кичинекей столдордо да жай. Мен сурамга NOLOCK коштум, анткени биз карап көргүбүз келген маалыматтар кулпу табылгандагыдай эле экенине кепилдик жок, ошондуктан биз кир окууларды коопсуз кыла алабыз.
Бирок, тезирээк, сурам мага биздин сурообуз күрөшкөн 25 сапты кайтарып берет
Ачкычтын жана беттин күтүү ресурсун туюк жана кулпуларда чечмелөө
PAGE кулпулары жөнүндө жетиштүү. АЧЫЧКЫ кулпусун күтүп жатсакчы?

2) waitresource=“KEY: 6:72057594041991168 (ce52f92a058c)” = Database_Id, HOBT_Id (эгер сиз чындап кааласаңыз, %%lockres%% аркылуу шифрленген сыйкырдуу хэш)

Эгерде сиздин сурооңуз индекстеги жазууну бекитүүгө аракет кылып, өзү кулпуланып калса, сиз даректин такыр башка түрүнө ээ болосуз.
"6:72057594041991168 (ce52f92a058c)" бөлүктөргө бөлүп, биз:

  • database_id = 6
  • hobt_id = 72057594041991168
  • сыйкырдуу хэш = (ce52f92a058c)

2.1) Database_id шифрин чечмелөө

Бул жогорудагы мисалдагыдай эле иштейт! Суроо аркылуу маалымат базасынын атын табыңыз:

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

Менин учурда ал дагы эле DB WideWorldImporters.

2.2) hobt_id шифрин чечмелөө

Табылган маалымат базасынын контекстинде sys.partitions программасына таблицанын жана индекстин аталыштарын аныктоого жардам бере турган жуп кошулмалар менен суроону аткаруу керек...

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

Бул сураныч PK_Application_Countries индексин колдонуу менен Application.Countries кулпусунда күтүп жатканын айтып турат.

2.3) Эми бир аз сыйкыр %%lockres%% - эгер сиз кайсы жазуу кулпуланганын билгиңиз келсе

Эгерде мен чындап эле кулпу кайсы катарда болгонун билгим келсе, таблицанын өзүнөн сураштырып биле алам. Биз сыйкырдуу хэшке дал келген жазууну табуу үчүн документтештирилбеген %%lockres%% функциясын колдоно алабыз.
Сураныч, бул суроо бүт таблицаны сканерлей турганын эске алыңыз, ал эми чоң столдордо бул кызыксыз болушу мүмкүн:

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

Мен NOLOCK коштум (Твиттердеги Клаус Ашенбреннердин кеңеши боюнча) анткени бөгөт коюу көйгөйгө айланышы мүмкүн. Биз транзакция башталганда эмне болгонун эмес, азыр эмне бар экенин карап көргүбүз келет - биз үчүн маалыматтардын ырааттуулугу маанилүү деп ойлобойм.
Voila, биз күрөшкөн рекорд!
Ачкычтын жана беттин күтүү ресурсун туюк жана кулпуларда чечмелөө

Ыраазычылык жана андан ары окуу

Бул нерселердин көбүн ким биринчи жолу сүрөттөп бергени эсимде жок, бирок бул жерде сизге эң аз документтештирилген нерселер тууралуу эки пост бар:

Source: www.habr.com

Комментарий кошуу