Как остановить процесс в MS SQL Server?

Вопрос: У меня есть некоторые процессы, которые требуют много времени для завершения. Я выполнил q-запрос, который занял 30 часов "Я забыл об этом", поэтому я убил его, используя "kill id", но он пытался откинуться уже более 30 часов. Может кто-нибудь, пожалуйста, скажите мне, как я могу заставить это остановиться? когда я запускаю этот запрос select

Вопрос:

У меня есть некоторые процессы, которые требуют много времени для завершения.

Я выполнил q-запрос, который занял 30 часов “Я забыл об этом”, поэтому я убил его, используя “kill id”, но он пытался откинуться уже более 30 часов.

Может кто-нибудь, пожалуйста, скажите мне, как я могу заставить это остановиться?

когда я запускаю этот запрос

select p.spid , right(convert(varchar, dateadd(ms, datediff(ms, P.last_batch, getdate()), ‘1900-01-01’), 121), 12) as ‘batch_duration’ , P.program_name from master.dbo.sysprocesses P where P.spid > 50 and P.status not in (‘background’, ‘sleeping’) and P.cmd not in (‘AWAITING COMMAND’ ,’MIRROR HANDLER’ ,’LAZY WRITER’ ,’CHECKPOINT SLEEP’ ,’RA MANAGER’) order by batch_duration desc

Я получаю следующие результаты

61 23:40:48.893 Microsoft SQL Server Management Studio — Query 51 23:33:03.410 Microsoft SQL Server Management Studio — Query 58 23:01:08.960 Microsoft SQL Server Management Studio — Query 55 20:45:41.953 Microsoft SQL Server Management Studio — Query 64 19:08:37.310 Microsoft SQL Server Management Studio — Query 62 00:00:05.207 Microsoft SQL Server Management Studio — Query

Когда я запускаю kill 61, я получаю следующий SPID 61: транзакционный откат продолжается. Расчетное завершение отката: 0%. Ориентировочное время: 0 секунд. (это имело место в течение последних 24 часов!)

Что я могу сделать, чтобы исправить эту проблему?

благодаря

Лучший ответ:

Если вы хотите убить все процессы, возможно, самый быстрый способ:

ALTER DATABASE [Data base name] SET SINGLE_USER WITH ROLLBACK IMMEDIATE

После этого вы можете вернуться к предыдущему состоянию базы данных:

ALTER DATABASE [Data base name] SET MULTI_USER

Это приведет к уничтожению всех процессов без перезапуска сервера. Если вы хотите убить набор конкретных процессов и “kill @spid” не работает, я могу только рекомендовать вам использовать соединение с ЦАП и посмотреть, что произойдет.

Ответ №1

Тебе просто придется подождать. Некоторые люди паникуют и тянут шнур питания, но это, скорее всего, означает, что откат начнется после перезапуска службы.

Вы можете посмотреть этот элемент Connect для возможных обходных решений (и подтверждение того, что это известная проблема и вряд ли будет исправлена в ближайшее время):

Http://connect.microsoft.com/SQLServer/feedback/details/187192/openquery-to-linked-server-hangs…

В стороне, несколько вещей о вашем запросе:

  1. Вы должны использовать только sysprocesses если используете SQL Server 2000 или старше. Начиная с SQL Server 2005 вы должны использовать DMV (например, sys.dm_exec_requests). Старые sys… views все еще существуют только для обратной совместимости. Однако в некоторых случаях вы можете использовать его для определения waitresource – он может предоставлять информацию о удаленном экземпляре/сеансе в зависимости от типа связанного сервера, который может предоставить вам информацию, которую вы можете использовать, чтобы убить процесс на другом конец. В вашем случае это не актуально, потому что удаленный “сервер” – это просто текстовый файл. Возможно, вы можете убить задачу с помощью Диспетчера задач…

  2. spid > 50 – не очень надежный способ идентифицировать несистемные процессы. Например, новые DMV позволяют идентифицировать пользовательские процессы с помощью sys.dm_exec_sessions.is_user_process.

  3. Вы не должны CONVERT(VARCHAR без указания длины.

  4. Вы не должны использовать сокращенное обозначение ms – если вы имеете в виду MILLISECOND, введите MILLISECOND. И вам нужна миллисекундная точность при измерении запроса, который работает в течение 30 часов?

  5. Будьте очень осторожны с ‘string delimited column aliases’ с ‘string delimited column aliases’ – этот синтаксис в некоторых случаях устарел и также выглядит как строковый литерал для большинства читателей. Если вы действительно хотите разграничить псевдоним (в этом случае вам не нужно), используйте [square brackets].

  6. Ваше усечение времени имеет для меня мало смысла. Если запрос выполнялся в течение четырех дней, вы бы не знали. Почему нет:

    ;WITH x AS ( SELECT session_id, command, [status], s = DATEDIFF(SECOND, start_time, CURRENT_TIMESTAMP) FROM sys.dm_exec_requests AS r WHERE EXISTS ( SELECT 1 FROM sys.dm_exec_sessions WHERE session_id = r.session_id AND is_user_process = 1 ) AND start_time < DATEADD(HOUR, -1, CURRENT_TIMESTAMP) ) SELECT session_id, command, [status], s, CONVERT(VARCHAR(12), s / 86400) + ‘ days ‘ + CONVERT(VARCHAR(2), (s % 86400) / 3600) + ‘ hours ‘ + CONVERT(VARCHAR(2), (s % 86400) % 3600 / 60) + ‘ minutes.’ FROM x ORDER BY s DESC;

Ответ №2

Вы не можете избежать ROLLBACK. Вы должны стараться избегать этого. Насколько я понимаю, есть 3 копии одного и того же кода?

Возможно, вы можете использовать проверку SEMAPHORE перед ее запуском. Например:

Проверьте, существует ли временная таблица до запуска 30-часового кода. Если таблица существует, вы не запускаете код, иначе вы создаете таблицу THEN, за которой вы запускаете код.

Оцените статью
Добавить комментарий