2013-11-10 2 views
0

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

У меня был запрос 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  

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

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

Спасибо

+0

Исходный запрос, который работал в течение 30 часов. Что это было на самом деле? –

+0

Это был запрос, который считывал данные из файла excel с помощью openquery и вставлял его в таблицу temp. файл excel имеет около 30 строк, поэтому он очень мал. И я всегда запускаю этот запрос, но никогда не занимал много времени. даже если я просто запустил запрос для чтения данных из файла, он будет навсегда. SELECT * FROM OPENROWSET ('MSDASQL', 'Driver = {Microsoft Text Driver (* .txt; * .csv)}; DBQ = E: \ UploadFiles \;', 'SELECT * from new.csv') – Jaylen

+0

Делает ли ' SELECT * FROM sys.dm_os_waiting_tasks WHERE session_id = 61' вернуть что-нибудь? –

ответ

1

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

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

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

ALTER DATABASE [Data base name] SET MULTI_USER 

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

+0

Эта команда будет просто пытаться убить соответствующие сеансы. Это проще, чем выполнять кучу команд KILL в цикле, но это то же самое и не сможет магически убить сеанс, выполняющий откат. Это преднамеренно и предназначено для защиты вашей базы данных, и именно поэтому прекращение обслуживания является таким опасным подходом. –

+0

Я выполнил первый запрос. Когда я попытался выполнить второй запрос, я получил следующую ошибку. Msg 102, Level 15, State 6, Line 1 Неверный синтаксис рядом с 'MULTIUSER_USER'. – Jaylen

+0

@Mike - Правильный синтаксис будет 'SET MULTI_USER' –

3

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

Вы можете посмотреть на этот пункт 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... виды все еще существуют только для обратной совместимости. Тем не менее,, в некоторых случаях вы можете использовать его для определения waitresource - он может предоставлять информацию о удаленном экземпляре/сеансе в зависимости от типа связанного сервера, который может предоставить вам информацию, которую вы можете использовать, чтобы убить процесс на другой конец. В вашем случае это не актуально, потому что удаленный «сервер» - это просто текстовый файл. Возможно, вы можете убить задачу с помощью диспетчера задач ...

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

  3. You should not CONVERT(VARCHAR without specifying a length.

  4. You should not use shorthand like ms - if you mean MILLISECOND, type MILLISECOND. И вам нужна миллисекундная точность при измерении запроса, который работает в течение 30 часов?

  5. Будьте очень осторожны с '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; 
    
+1

, но это уже 24 часа! – Jaylen

+0

@ Майк хорошо, если он сделал 30 часов работы, прежде чем отменить его, вы должны ожидать, что это займет не менее * 30 часов, чтобы отменить его. –

+0

@AaronBertrand - Хотя кажется, что он был виден в ожидании типа 'OLEDB' для' 23,8' часов и подсчета. –

0

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

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

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