Як відслідковувати блокування, яке трапляється менше секунди - SQL Server


14

Я намагаюся вирішити проблему блокування, яка трапляється менше ніж на секунду. Програма OLTP дуже чутлива і має мати час реакції менше 200 мс для деяких транзакцій відповідно до узгодженої угоди про угоди. У нас виникли деякі проблеми ескалації блокування з новим випуском коду, який нам вдалося вирішити, зменшуючи розмір партії в оновленнях. Навіть маючи невеликий розмір партії, ми підозрюємо, що новий sp блокує ті самі рядки, що й операції OLTP оновлюються.

Мені потрібно знайти сеанс, який заблокується, і ресурс його очікування. Згідно з моїм розумінням, "поріг заблокованого процесу" може встановитись як мінімум на 1 секунду, і це не спричинить блокування.

Я експериментую з wait_info та wait_completed x подіями.

Чи є інший спосіб, як ми могли б це відстежити. Спасибі


Той же питання про так по тим же користувачем: stackoverflow.com/questions/38407021 / ...
TheGameiswar

Відповіді:


10

Оскільки вас конкретно цікавить блокування, а не загальне очікування, locks_lock_waitsрозширена подія звучить більш підходящим.

З фільтром увімкнено increment >= 200

CREATE EVENT SESSION [locks_lock_waits] ON SERVER 
ADD EVENT sqlserver.locks_lock_waits(
        ACTION(sqlserver.sql_text)
            WHERE  ( [sqlserver].[is_system] = 0
                     AND [increment] >= 200
                     AND [counter] <= 1000 ) 
    )
ADD TARGET package0.ring_buffer;

GO

ALTER EVENT SESSION [locks_lock_waits]  
ON SERVER  STATE = start;  

Вищезгадане збирає заяви, які очікують на блокування протягом порогової кількості часу, але не дає конкретного ресурсу блокування.

Я ніколи не використовував цю подію і не маю уявлення про те, скільки накладних витрат на цей сеанс виникне на вашому виробничому сервері.

Я знайшов це відео по темі. Це настійно рекомендую фільтрувати, counterщоб зменшити кількість зібраних подій, і я це зробив вище.

Тут також згадується стара застаріла незадокументована команда

dbcc lock(StallReportThreshold, 200) -- 200 is threshold in ms

Який (якщо увімкнено прапор 3605 відстеження) скидає обмежену інформацію, наприклад нижче, до журналу помилок SQL Server.

Процес 53 чекав 6844 мс для блокування S на RID: 2: 1: 120: 2 результат: OKWAIT

Я лише згадую це, мимохідь, оскільки розширені події все-таки були б переважнішими, оскільки це документально підтверджено та набагато сильніше.


Я перевірив locks_lock_waits, і, як ви сказали, у нього немає інформації про ресурс. Але я не знав, що приріст був час. Хороший інформаційний замок dbcc, виглядає чудово. Чи знаєте ви, як довго ця інформація доступна, перш ніж її можна скинути в журнал помилок.
jesijesi

Вибачте, я не зрозумів себе. Я запитав, скільки у нас часу, поки ми не виконаємо команду блокування dbcc. Наприклад, блокування відбувається, і якщо я запускаю dbcc lock через годину, ми все-таки отримуємо інформацію?
jesijesi

@jesijesi - Я ніколи раніше про це не чув. У мене немає більше інформації про це. Я навіть не знаю параметрів, які потрібно передати, щоб відключити його. Але ви запускаєте dbcc lock(StallReportThreshold, 200) перше, і воно виводить інформацію, коли поріг буде перевищено, доки включено прапор 3605 сліду. SQL Server не збирає цю інформацію на випадок, якщо ви можете запустити її пізніше.
Мартін Сміт

2
Спасибі. просто додавши посилання, яке має корисну функцію для перетворення значень ресурсу_0,1,2 в xevents. sqlnotes.info/2011/10/24/…
jesijesi

5

Якщо вас цікавить блокування, доступні декілька розширених подій:

lock_acquired
lock_released
lock_escalation

Перші дві події містять durationстовпчик у (мікросекундах), на який ви можете відфільтрувати ваші пороги. Вони також проводять resource_descriptionакцію, яка дасть вам детальну інформацію про залучені ресурси.

lock_escalationПодія також має statementдію , яке ви можете додати , щоб зібрати заяву T-SQL , яке викликало ескалацію блокування. Це також є escalation_cause. Ось приклад сеансу:

CREATE EVENT SESSION [locking] ON SERVER 
ADD EVENT sqlserver.lock_acquired( SET collect_resource_description = (1) ),
ADD EVENT sqlserver.lock_escalation( SET collect_statement = (1) ),
ADD EVENT sqlserver.lock_released( SET collect_resource_description = (1) )
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=OFF,STARTUP_STATE=OFF)
GO

Я підозрюю, що, мабуть, є причина, що ви не можете встановити поріг заблокованого звіту про процес менше ніж секунди: блокування ідеально нормально в RDBMS - двигун бази даних повинен блокувати ресурси, щоб захистити їх. Хоча не існує офіційного визначення, коли блокування стає блокувальним, блокування тикання протягом другої секунди мені здається нормальним.


1
блокування блокується, як тільки комусь заборонено доступ до ресурсу, і йому доведеться почекати через блокування.
Мартін Сміт

Дякую, я планую використовувати lock_acquired з полем тривалості.
jesijesi

Удачі. Оскільки ви перебуваєте на SQL Server 2014, ви можете використовувати таблиці пам'яті OLTP в пам'яті з власне складеними збереженими документами, які пропонують високопродуктивний варіант без засувок. Ви також можете подивитися на ізоляцію знімків.
wBob
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.