如何安全地终止长时间运行的 MSSQL 查询?

如何安全地终止长时间运行的 MSSQL 查询?

最近,我们有一个 SQL 作业插入数据库。该查询已不必要地运行了几天,因此使用 KILL SPID 将其终止。然后,该进程开始回滚几天,似乎就挂在那里了。

运行 KILL SPID WITH STATUSONLY 会出现一条消息,指出“预计完成度”为 100% 且“预计剩余时间”为 0 秒。

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

我的问题是 - 您应该如何终止 SQL 进程?这是唯一的方法吗?

答案1

您做对了所有事情,但您考虑了回滚的成本。您说您的查询运行了几天,因此它会将几天的数据作为未提交的事务写入日志文件。通过终止任务,您启动了回滚,这就是您必须等待的结果。

如果您希望能够以较小的影响终止事务,请考虑批量处理事务并偶尔提交。如果您可以完全避免事务,那么这对于长期运行的作业来说会更好。

答案2

我看到了您描述的回滚“挂起”,摆脱它的唯一方法是重新启动 SQL 服务,就像您所做的那样。

确保回滚确实挂起,而不是仍然实际回滚非常重要(如您所见,WITH STATUSONLY 并不完全可靠)。风险在于,如果您在回滚期间重新启动 SQL 服务实际上仍在回滚,则重新启动 SQL 服务后,数据库将停留在“恢复”模式,直到回滚完成。

我唯一能判断的方法是刷新 SQL 活动监视器,并查看 SPID 的 CPU 和/或 IO 计数是否仍在增加。如果是,则回滚仍在进行中,您不应重新启动 SQL。给它更多时间。

另外一点:不要试图删除日志文件等疯狂的事情。这将“停止”事务回滚,但代价是数据库的完整性。我使用的唯一其他技术(假设回滚的事务是仅有的恢复自上次备份以来数据库发生的重要变化)的一种方法就是简单地从最新备份中恢复,我们认为这比等待一天回滚更快、更简单。当然,这在很大程度上取决于数据库活动的性质。

相关内容