Страницы

Поиск по вопросам

понедельник, 8 июля 2019 г.

Как завершить спящие процессы ничего не сломав?

Программа создаёт блокировки и процессы которые висят. Помогает завершение процессов с помощью T-SQL. Но есть проблема, вместе с этим завершаются нужные процессы, в следствии чего набранные данные не сохраняются(было замечено несколько раз) или при работе в другом окне программы завершается процесс главной формы.
DECLARE @v_spid INT DECLARE c_Users CURSOR FAST_FORWARD FOR SELECT SPID FROM master..sysprocesses (NOLOCK) WHERE spid>50 AND status='sleeping' AND DATEDIFF(mi,last_batch,GETDATE())>=5 AND spid<>@@spid
OPEN c_Users FETCH NEXT FROM c_Users INTO @v_spid WHILE (@@FETCH_STATUS=0) BEGIN PRINT 'KILLing '+CONVERT(VARCHAR,@v_spid)+'...' EXEC('KILL '+@v_spid) FETCH NEXT FROM c_Users INTO @v_spid END
CLOSE c_Users DEALLOCATE c_Users


Ответ

Нехорошо убивать процессы, не выяснив причину. Тем более, что sleeping означает ожидание сервером запроса от клиента, а под это условие могут быть квалифицированы сессии в совершенно разном логическом состоянии.
У сессии может быть открытая транзакция и она может быть в состоянии sleeping между отдельными командами, а может не быть открытых транзакций - например, клиент просто подсоединился к серверу, или клиент подсоединился и сделал запрос, а соединение не закрыл (скоро опять понадобится).
процессы которые висят
Вам лучше расследовать ситуацию. Иногда бывает достаточно sp_who, sp_who2 и sp_lock
Основные причины подвисания процесса при запросе, как правило:
запрос никто не блокирует, он долгий сам по себе запрос долгий, потому что он блокируется чем-то
другим запросом пользовательской транзакцией
Поищите сессии, делающие долгие запросы
SELECT s.session_id, r.total_elapsed_time, r.wait_time, r.wait_type, r.wait_resource, r.blocking_session_id FROM sys.dm_exec_sessions s JOIN sys.dm_exec_requests r ON r.session_id = s.session_id WHERE s.is_user_process = 1 AND s.session_id != @@SPID ORDER BY r.total_elapsed_time DESC;
Если сессия блокирована кем-то, то вы увидите идентификатор сессии в blocking_session_id
Потом уже по конкретной сессии можно посмотреть что в ней происходит вплоть до текста и плана конкретно выполняющейся в данный момент команды:
SELECT r.session_id, t.text, p.query_plan, stmt_text = SUBSTRING( t.text, r.statement_start_offset / 2 + 1, (CASE r.statement_end_offset WHEN -1 THEN DATALENGTH(t.text) ELSE r.statement_end_offset END - r.statement_start_offset) / 2 + 1 ), stmt_plan = CAST(stp.query_plan AS xml) FROM sys.dm_exec_requests r CROSS APPLY sys.dm_exec_query_plan(r.plan_handle) p CROSS APPLY sys.dm_exec_sql_text(r.plan_handle) t CROSS APPLY sys.dm_exec_text_query_plan(r.plan_handle, r.statement_start_offset, r.statement_end_offset) stp WHERE r.session_id = @sessionID;
Поискать сессии с незавершенными транзакциями можно, например, так:
SELECT s_tr.session_id, a_tr.transaction_id, open_time_msec = DATEDIFF(millisecond, a_tr.transaction_begin_time, GETDATE()) FROM sys.dm_tran_session_transactions s_tr JOIN sys.dm_tran_active_transactions a_tr ON a_tr.transaction_id = s_tr.transaction_id WHERE s_tr.is_user_transaction = 1 AND s_tr.session_id != @@SPID ORDER BY a_tr.transaction_begin_time;

Комментариев нет:

Отправить комментарий