ProHoster > Blog > Ma'muriyat > Tugallanish va qulflarda kalit va Page WaitResource-ni shifrlash
Tugallanish va qulflarda kalit va Page WaitResource-ni shifrlash
Agar siz bloklangan jarayon hisobotidan foydalansangiz yoki vaqti-vaqti bilan SQL Server tomonidan taqdim etilgan blokirovka grafiklarini to'plasangiz, siz quyidagi holatlarga duch kelasiz:
Ba'zan siz o'rganayotgan gigant XMLda ko'proq ma'lumot bo'ladi (tug'in grafiklarida ob'ekt va indeks nomlarini aniqlashga yordam beradigan resurslar ro'yxati mavjud), lekin har doim ham emas.
Ushbu matn ularni tushunishga yordam beradi.
Bu erda joylashgan barcha ma'lumotlar Internetda turli joylarda joylashgan, u juda tarqatilgan! Men hamma narsani birlashtirmoqchiman - DBCC PAGE dan hobt_id va hujjatsiz %%physloc%% va %%lockres%% funktsiyalarigacha.
Birinchidan, keling, PAGE blokirovkalarida kutish haqida gapiraylik, keyin esa KEY qulflariga o'tamiz.
1.2) Ma'lumotlar fayli nomini qidiring - agar sizni qiziqtirsa
Jadval nomini topish uchun keyingi bosqichda data_file_id dan foydalanamiz. Siz shunchaki keyingi bosqichga o'tishingiz mumkin, lekin agar siz fayl nomi bilan qiziqsangiz, uni topilgan ma'lumotlar bazasi kontekstida ushbu so'rovda data_file_id o'rniga so'rovni bajarish orqali topishingiz mumkin:
USE WideWorldImporters;
GO
SELECT
name,
physical_name
FROM sys.database_files
WHERE file_id = 3;
GO
WideWorldImporters ma'lumotlar bazasida bu WWI_UserData deb nomlangan fayl va men uni C:MSSQLDATAWideWorldImporters_UserData.ndf ga tikladim. (Of, siz meni tizim diskiga fayllarni joylashtirayotganimda ushladingiz! Yo‘q! Bu noqulay edi).
1.3) DBCC PAGE dan obyekt nomini oling
Endi biz 70133-ma'lumotlar faylidagi №3 sahifa WorldWideImporters ma'lumotlar bazasiga tegishli ekanligini bilamiz. Biz ushbu sahifa mazmunini hujjatsiz DBCC PAGE va 3604 kuzatuv bayrog'i yordamida ko'rib chiqishimiz mumkin.
Eslatma: Men DBCC PAGE-dan boshqa serverdagi zaxiradan tiklangan nusxada foydalanishni afzal ko'raman, chunki bu hujjatlashtirilmagan narsa. Ba'zi hollarda u dump hosil bo'lishiga olib kelishi mumkin (taxminan. tarjimon - havola, afsuski, hech qaerga olib kelmaydi, lekin url-ga ko'ra, biz filtrlangan indekslar haqida gapiramiz).
/* 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
Natijalarni aylanib chiqsangiz, siz object_id va index_id ni topishingiz mumkin.
Deyarli bajarildi! Endi siz so'rov yordamida jadval va indeks nomlarini topishingiz mumkin:
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
Va endi biz qulfni kutish Sales.OrderLines jadvalining PK_Sales_OrderLines indeksida bo'lganini ko'ramiz.
Eslatma: SQL Server 2014 va undan keyingi versiyalarida obyekt nomini hujjatsiz DMO sys.dm_db_database_page_allocations yordamida ham topish mumkin. Lekin siz ma'lumotlar bazasidagi har bir sahifani so'rashingiz kerak, bu katta ma'lumotlar bazalari uchun unchalik ajoyib ko'rinmaydi, shuning uchun men DBCC PAGE dan foydalandim.
1.4) Bloklangan sahifadagi ma'lumotlarni ko'rish mumkinmi?
Xo'sh, ha. Lekin... bu sizga haqiqatan ham kerakligiga ishonchingiz komilmi?
Hatto kichik stollarda ham sekin. Lekin bu juda zo'r, shuning uchun siz hozirgacha o'qiganingizdan beri... keling, %%physloc%% haqida gapiraylik!
Endi biz Sales.OrderLines-da sahifani bloklashni xohlayotganimizni bilganimizdan so'ng, biz ushbu so'rov yordamida №3 sahifadagi №70133 ma'lumotlar faylida saqlangan ushbu jadvaldagi barcha ma'lumotlarni ko'rib chiqishimiz mumkin:
Use WideWorldImporters;
GO
SELECT
sys.fn_PhysLocFormatter (%%physloc%%),
*
FROM Sales.OrderLines (NOLOCK)
WHERE sys.fn_PhysLocFormatter (%%physloc%%) like '(3:70133%'
GO
Aytganimdek, hatto kichik stollarda ham sekin. Men so‘rovga NOLOCK ni qo‘shdim, chunki biz ko‘rmoqchi bo‘lgan ma’lumotlar qulf aniqlangandagi bilan bir xil ekanligiga hali kafolatimiz yo‘q – shuning uchun biz iflos o‘qishlarni xavfsiz bajarishimiz mumkin.
Ammo, shoshilinch, so'rov menga so'rovimiz kurashgan bir xil 25 qatorni qaytaradi.
PAGE qulflari haqida yetarli. Agar biz KEY qulfini kutayotgan bo'lsak-chi?
2) waitresource=“KEY: 6:72057594041991168 (ce52f92a058c)” = Database_Id, HOBT_Id (agar chindan ham xohlasangiz, %%lockres%% yordamida shifrlanishi mumkin boʻlgan sehrli xesh)
Agar so'rovingiz indeksdagi yozuvni blokirovka qilishga urinsa va o'zi qulflansa, siz butunlay boshqa turdagi manzilga ega bo'lasiz.
"6:72057594041991168 (ce52f92a058c)" ni qismlarga bo'lib, biz quyidagilarni olamiz:
ma'lumotlar bazasi_id = 6
hobt_id = 72057594041991168
sehrli xesh = (ce52f92a058c)
2.1) Database_id shifrini ochish
Bu yuqoridagi misol bilan bir xil ishlaydi! So'rov yordamida ma'lumotlar bazasi nomini toping:
SELECT
name
FROM sys.databases
WHERE database_id=6;
GO
Topilgan ma'lumotlar bazasi kontekstida siz jadval va indeks nomlarini aniqlashga yordam beradigan juft birikmalar bilan sys.partitions so'rovini bajarishingiz kerak...
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
Bu so'rovni PK_Application_Countries indeksidan foydalangan holda Application.Countries blokirovkasida kutayotganini aytadi.
2.3) Endi bir oz sehrli %%lockres%% - agar siz qaysi yozuv bloklanganligini bilmoqchi bo'lsangiz
Agar men haqiqatan ham qaysi qatorda qulf yoqilganligini bilmoqchi bo'lsam, jadvalning o'zini so'rash orqali bilib olaman. Sehrli xeshga mos keladigan yozuvni topish uchun hujjatsiz %%lockres%% funksiyasidan foydalanishimiz mumkin.
E'tibor bering, bu so'rov butun jadvalni skanerlaydi va katta jadvallarda bu umuman qiziq bo'lmasligi mumkin:
SELECT
*
FROM Application.Countries (NOLOCK)
WHERE %%lockres%% = '(ce52f92a058c)';
GO
Men NOLOCK (Twitterdagi Klaus Aschenbrennerning maslahati bilan) chunki blokirovkalar muammoga aylanishi mumkin. Biz tranzaksiya boshlanganda nima borligini emas, balki hozir nima borligini ko‘rib chiqmoqchimiz – ma’lumotlarning izchilligi biz uchun muhim deb o‘ylamayman.
Voila, biz kurashgan rekord!
Minnatdorchilik va qo'shimcha o'qish
Bularning ko'pini kim birinchi bo'lib tasvirlaganini eslay olmayman, lekin bu erda sizga yoqadigan eng kam hujjatlashtirilgan narsalar haqida ikkita xabar bor: