0

我有一些需要很长时间才能终止的进程。

我运行了 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 小时都是这种情况!)

我能做些什么来解决这个问题?

谢谢

4

3 回答 3

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. 你不应该不CONVERT(VARCHAR指定长度

  4. 你不应该使用速记ms,如果你的意思是MILLISECOND,输入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;
    
于 2013-11-10T18:37:46.240 回答
1

如果要杀死所有进程,可能是,最快的方法是:

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

之后,您可能想回到以前的数据库状态:

ALTER DATABASE [Data base name] SET MULTI_USER

这将在不重新启动服务器的情况下杀死所有进程。如果您想终止一组特定进程并且“kill @spid”不起作用,我只能建议您使用 DAC 连接,看看会发生什么。

于 2013-11-10T19:05:22.307 回答
0

你无法避免回滚。您应该尽量避免启动它。我知道有 3 个相同的代码正在运行吗???

也许您可以在运行之前使用 SEMAPHORE 检查。例如:

在运行 30h 代码之前检查是否存在临时表。如果表存在,则不运行代码,否则创建表,然后运行代码。

于 2013-11-10T18:56:32.957 回答