我怎样才能安全地杀死一个长时间运行的MSSQL查询?

最近我们有一个SQL作业插入到数据库中。 查询已经连续几天没有运行,所以使用KILL SPID杀死了这个查询。 然后这个过程开始回滚了好几天,似乎只是在那里挂起。

使用STATUSONLY运行KILL SPID给出了一条消息,指出“预计完成时间”为100%,“预计剩余时间”为0秒。

最终,我们不得不重新启动删除该进程的SQL服务。

我的问题是,你应该如何杀死一个SQL过程? 这是唯一的方法吗?

你做的一切都正确,但你已经考虑了回滚的成本。 你说你的查询已经运行好几天了,所以它会把date的数据写成日志文件作为未提交的事务。 通过杀死任务,你开始回滚,这是你必须等待的。

如果您希望能够以较less的影响杀死事务,请考虑批处理事务并偶尔提交。 如果你能完全避免交易,那对于长时间运行的工作会更好。

我已经看到了回滚“挂起”,正如你所描述的,唯一的办法就是重启SQL服务。

重要的是确保回滚真的挂起,而不是实际上回滚(正如你所看到的,WITH STATUSONLY是不完全可靠的)。 如果在回滚实际回滚时重新启动SQL服务,则在重新启动SQL服务之后,数据库将停留在“恢复”模式,直到回滚完成。

我唯一能说的另一种方法是使用刷新SQL Activity Monitor,看看SPID的CPU和/或IO数是否还在增加。 如果是,那么回滚仍在进行中,而且您不应该重新启动SQL。 给它更多的时间。

还有一点 :不要试图做一些疯狂的事情,比如删除日志文件。 这将“停止”事务回滚,但代价是数据库的完整性。 我使用的唯一其他技术(假设回滚事务是自上次备份以来对数据库唯一重要的更改)是从最近的备份中恢复,我们确定这将比等待额外的一天更快更容易回滚发生。 这当然高度依赖于数据库活动的性质。