Jak śledzić blokowanie, które zdarza się krócej niż sekundę - SQL Server


14

Próbuję rozwiązać problem blokowania, który występuje przez mniej niż sekundę. Aplikacja OLTP jest bardzo wrażliwa i musi mieć czas odpowiedzi mniejszy niż 200 ms dla niektórych transakcji zgodnie z ustaloną umową SLA. Wystąpiły pewne problemy z eskalacją blokady w nowej wersji kodu, które udało nam się rozwiązać, zmniejszając rozmiar partii w aktualizacjach. Nawet przy małej wielkości partii podejrzewamy, że nowy sp blokuje te same wiersze, które aktualizują transakcje OLTP.

Muszę znaleźć blokowaną sesję i zasób, na który czeka. Zgodnie z moim rozumieniem „próg zablokowanego procesu” można ustawić na co najmniej 1 sekundę, więc nie spowoduje to zablokowania blokady.

Eksperymentuję z wydarzeniami wait_info i wait_completed x.

Czy jest jakiś inny sposób, aby to wyśledzić. Dzięki


to samo pytanie na ten sam użytkownik: stackoverflow.com/questions/38407021/…
— TheGameiswar

Odpowiedzi:


10

Ponieważ jesteś szczególnie zainteresowany blokowaniem, a nie ogólnym oczekiwaniem, locks_lock_waitswydarzenie rozszerzone wydaje się bardziej odpowiednie.

Przy włączonym filtrze 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;  

Powyższe gromadzi instrukcje czekające na blokady przez określony czas, ale nie podaje określonego zasobu blokady.

Nigdy nie korzystałem z tego wydarzenia i nie mam wglądu w to, ile narzutu spowodowałoby to na twoim serwerze produkcyjnym.

Znalazłem ten film na ten temat. To zdecydowanie zaleca filtrowanie w countercelu zmniejszenia liczby zebranych zdarzeń i zrobiłem to powyżej.

Wspomina także o starym, nieudokumentowanym poleceniu

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

Który (jeśli flaga śledzenia 3605 jest włączona) zrzuca ograniczone informacje, takie jak poniżej, do dziennika błędów SQL Server.

Proces 53 czekał 6844 ms na S lock na RID: wynik 2: 1: 120: 2: OKWAIT

Wspominam o tym mimochodem, ponieważ i tak dłuższe wydarzenia byłyby zdecydowanie lepsze, ponieważ są one udokumentowane i mają znacznie większą moc.


Testowałem locks_lock_waits i, jak powiedziałeś, nie ma informacji o zasobach. Ale nie wiedziałem, że przyrost to czas. Dobra informacja blokada dbcc, wygląda świetnie. Czy wiesz, jak długo te informacje są dostępne, zanim można je zrzucić do dziennika błędów.
— jesijesi

Przepraszam, nie wyraziłem siebie. Pytałem, ile mamy czasu do uruchomienia komendy dbcc lock. Np. Następuje blokowanie i jeśli uruchomię blokadę dbcc po godzinie, czy nadal otrzymujemy informacje?
— jesijesi

@jesijesi - Nigdy wcześniej o tym nie słyszałem. Nie mam więcej informacji na ten temat. Nie znam nawet parametrów, które należy przekazać, aby je wyłączyć. Ale uruchamiasz się dbcc lock(StallReportThreshold, 200) pierwszy i wyświetla informacje po przekroczeniu progu, o ile włączona jest flaga śledzenia 3605. SQL Server nie zbiera tych informacji na wypadek, gdybyś mógł je później uruchomić.
— Martin Smith

2
Dzięki. po prostu dodając link, który ma przydatną funkcję do konwersji wartości resource_0,1,2 w xevents. sqlnotes.info/2011/10/24/…
— jesijesi

5

Jeśli chcesz zablokować, dostępnych jest kilka rozszerzonych wydarzeń:

lock_acquired
lock_released
lock_escalation

Pierwsze dwa zdarzenia mają durationkolumnę (w mikrosekundach), którą można filtrować według progów. Mają też resource_descriptionakcję, która da ci szczegółowe informacje na temat zaangażowanych zasobów.

W lock_escalationzdarzeniu jest także statementakcja, którą można dodać, aby zebrać instrukcję T-SQL, która uruchomiła eskalację blokady. Ma również escalation_cause. Oto przykładowa sesja:

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

Podejrzewam, że istnieje prawdopodobnie powód, dla którego nie można ustawić progu raportu zablokowanego procesu na mniej niż sekundę: blokowanie jest w RDBMS całkowicie normalne - silnik bazy danych musi blokować zasoby, aby je chronić. Chociaż nie ma oficjalnej definicji, kiedy blokowanie staje się blokowaniem, blokowanie tykania w czasie poniżej sekundy wydaje mi się normalne.


1
blokowanie staje się blokowane, gdy tylko ktoś odmówi dostępu do zasobu i będzie musiał czekać z powodu blokady.
— Martin Smith

Dziękuję, planuję użyć lock_acquired z polem czasu trwania.
— jesijesi

Powodzenia. Korzystając z programu SQL Server 2014, można używać tabel OLTP w pamięci z natywnie skompilowanymi przechowywanymi procesorami oferującymi opcję wysokiej wydajności bez zatrzasków. Możesz także spojrzeć na izolację migawki.
— wBob
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.