Próbuję zrozumieć / nauczyć się, jak wyśledzić szczegóły zablokowanej sesji.
Więc stworzyłem następującą konfigurację:
create table foo (id integer not null primary key, some_data varchar(20));
insert into foo values (1, 'foo');
commit;
Teraz łączę się z bazą danych dwukrotnie od dwóch różnych klientów.
Problemy z pierwszą sesją:
begin transaction
update foo set some_data = 'update'
where id = 1;
Wyraźnie nie popełniam tam, aby zachować zamki.
W drugiej sesji wystawiam to samo oświadczenie i oczywiście, że czeka się na zablokowanie. Teraz próbuję użyć różnych zapytań unoszących się wokół, aby zobaczyć, że sesja 2 czeka na foo
tabelę.
sp_who2
pokazuje następujące (usunąłem niektóre kolumny, aby pokazać tylko ważne informacje):
SPID | Status | BlkBy | DBName | Command | SPID | ŻĄDANIE ID ----- + -------------- + ------- + ---------- + ---------- -------- + ------ + ---------- 52 | spanie | . | foodb | OCZEKUJĄCE NA POLECENIE | 52 | 0 53 | spanie | . | foodb | OCZEKUJĄCE NA POLECENIE | 53 | 0 54 | ZAWIESZONY | 52 | foodb | AKTUALIZACJA | 54 | 0 56 | RUNNABLE | . | foodb | WYBIERZ W | 56 | 0
Jest to oczekiwane, sesja 54 jest blokowana przez nie zatwierdzone zmiany z sesji 52.
Zapytanie sys.dm_os_waiting_tasks
również to pokazuje. Wyrok:
select session_id, wait_type, resource_address, resource_description
from sys.dm_os_waiting_tasks
where blocking_session_id is not null;
zwroty:
session_id | wait_type | adres_zasobu | opis_zasobu ----------- + ----------- + -------------------- + ----- -------------------------------------------------- -------------------------- 54 | LCK_M_X | 0x000000002a35cd40 | keylock hobtid = 72057594046054400 dbid = 6 id = tryb lock4ed1dd780 = X relatedObjectId = 72057594046054400
Ponownie oczekuje się tego.
Mój problem polega na tym, że nie potrafię znaleźć rzeczywistej nazwy obiektu, na który czeka sesja 54.
Znalazłem kilka zapytań, które łączą się sys.dm_tran_locks
i sys.dm_os_waiting_tasks
podobają:
SELECT ....
FROM sys.dm_tran_locks AS l
JOIN sys.dm_os_waiting_tasks AS wt ON wt.resource_address = l.lock_owner_address
Ale w moim powyższym scenariuszu testowym to połączenie nic nie zwraca. Więc to dołączenie jest złe lub dm_tran_locks
faktycznie nie zawiera informacji, których szukam.
Tak więc szukam zapytania, które zwraca coś takiego:
„ sesja 54 czeka na blokadę w tabelifoo
”.
Niektóre informacje w tle:
Prawdziwy problem, który próbuję rozwiązać, jest nieco bardziej skomplikowany, ale sprowadza się do pytania „na który stół czeka sesja 54”. Problem dotyczy dużej procedury składowanej, która aktualizuje kilka tabel i wybiera z widoku, który uzyskuje dostęp do niektórych z tych tabel. select
Oświadczenie jest zablokowany chociaż mamy izolacji migawka i czytać zaangażowana migawka włączona. Zrozumienie, dlaczego wybór jest zablokowany (co, moim zdaniem, nie byłoby możliwe, jeśli włączona jest izolacja migawek), będzie następnym krokiem.
Na początek chciałbym dowiedzieć się, na co czeka ta sesja.