Zdarza się, że z poziomu SQL Servera wykonujemy operacje w systemie operacyjnym Windows i w pewnym momencie zabijamy poleceniem KILL z poziomu SQL Servera sesję, która owe operacje prowadzi. Nierzadko prowadzi to do sytuacji, w której zabita sesja na długo (a czasem w nieskończoność) pozostaje na liście sesji w master.dbo.sysprocesses (cmd = ‚KILLED/ROLLBACK’) lub w widoku dynamicznym sys.dm_exec_requests (command = ‚KILLED/ROLLBACK’).
Przykład:
Wykonujemy zapytania (analogiczne zapytania do DMV i sysprocesses) i oglądamy „wiszącą” sesję o @@SPID = 52:
SELECT r.session_id, r.command, s.host_process_id FROM sys.dm_exec_requests AS r INNER JOIN sys.dm_exec_sessions AS s ON r.session_id = s.session_id WHERE r.command = 'KILLED/ROLLBACK'; GO SELECT spid, cmd, hostprocess FROM master.dbo.sysprocesses WHERE cmd = 'KILLED/ROLLBACK'; GO
Wynik:
session_id command host_name host_process_id ---------- ---------------- --------- --------------- 52 KILLED/ROLLBACK CLIENT1 3720 spid cmd hostname hostprocess ------ ---------------- -------- ----------- 52 KILLED/ROLLBACK CLIENT1 3720
Jak sobie poradzić z taką „wiszącą” sesją? Nie bez przyczyny w zapytaniach wybrałem kolumny host_process_id i hostprocess. Obie pokazują ID procesu (tu – 3720) na maszynie CLIENT1. Aby sesja zniknęła i przestała zatruwać nam życie, należy na wskazanej maszynie zabić proces o wskazanym ID. Jeżeli maszyna (host) to serwer hostujący instancję SQL Server, na której „wisi” sesja, można spróbować użyć procedury rozszerzonej xp_cmdshell (o ile jest włączona i o ile z poziomu SQL Servera da się na tej maszynie zabić proces w systemie Windows – kwestia uprawnień):
EXEC master.dbo.xp_cmdshell 'taskkill /PID 3720';
Bardziej jednak prawdopodobne, że będzie potrzebna interwencja administratora Windows (domeny?). W każdym razie, przynajmniej wiadomo, co trzeba zrobić, by uniknąć operacji, która biednemu DBA wydaje się często jedynym ratunkiem – restartu usługi SQL Servera.