如何在SQL Server中杀死/解决一个长期运行的更新

时间:2010-07-20 09:35:42

标签: sql-server-2005 rollback

我的一位同事(我承诺这是一位同事!)自上周四开始在我们的主要SQL Server上运行更新(是的,这是对的人,我们现在推动了100个小时! )。有问题的SQL(在一个事务中,我可能会添加)是:

update daily_prices  set min_date = (select min(a.date)
   from daily_prices a       
   where a.key = daily_prices.key and       
   a.iid = daily_prices.iid)

(是的,我知道,令人发指......)

查询计划中的总成本为22186.7,估计要更新的行数约为1.51亿。

我们显然需要以这种或那种方式解决这个问题,我们意识到如果我们要杀死查询,我们将会产生一些残酷的回滚,但我们无法知道它到底有多远。我们唯一知道的是来自sys.dm_exec_requests的这个条目:

session_id  status      query_text              cpu_time    total_elapsed_time  reads       writes      logical_reads
52          suspended   update daily_prices...  2328469     408947075           13831137    42458588    151809497

所以我的问题是,什么是我们最好的行动方案?

  1. 等一下
  2. 杀死它并回滚,并希望它在下一个冰河时代之前回滚
  3. 别的什么?

2 个答案:

答案 0 :(得分:2)

我个人希望等待,除非我本周没有机会完成,但在此阶段的回滚可能需要比查询迄今为止更长的时间。如果它是一个生产服务器,我真的不会选择2并杀死它,除非我绝对必须。

如果您有合适的备份,重新获得某些控制/工作系统,请将另一个数据库联机恢复备份/ tlog备份,但您不希望在事务启动时恢复到更高级别(或者仍然需要回滚。)这至少为您提供了一个可以继续开发工作的系统,但不太可能是产品系统的理想情况。

如果它是生产服务器,那么在执行查询和查询计划之前,与个人有一些关于测试查询和查询计划的适用性的话。我相信很多DBA可以建议不太礼貌的教学方法:)

答案 1 :(得分:2)

所以我们厌倦了等待我们的交易完成,(整整一周后 一个SQL,谁不会?),因为它干扰了我们的备份 过程中,我们认为杀死它是一种必要的邪恶。

数据库开始回滚事务。

过了5天。

我们注意到互联网上其他地方的一些帖子有时会有些神奇 重新启动数据库并且事务将“消失”时发生, 虽然这些通常被揭穿*,但没有任何意义,我们认为我们 没有什么可遗失的,所以我们试了一下。我们知道数据库会进入 恢复模式,但无论如何数据库变得越来越不舒服 除了当前的回滚工作之外还运行任何东西,我们已经看到SQL Server在占用系统资源方面行为不端而没有将它们转移到需要完成工作的地方。

(*我们也知道足够的数据库理论知道DB不会只是“忘记” 关于正在进行的事务,但我们也看到了堆栈转储 SQL Server错误日志告诉我们SQL Server正在获取哪种类型 对它必须承担的回滚量越来越不满意了)

所以我们重新启动了数据库。

数据库确实进入了恢复模式。但是,SQL Server事件Log 现在每隔20秒左右就给我们一个更新,以了解它的持续时间 (总而言之,它从日志消息中估计大约25个小时,但它最终成了 只有一个半小时(!))。

这种恢复/回滚方法是否更快,我强烈怀疑(正如我所料 SQL Server必须像以前一样完成相同级别的工作来解开事务,但它确实在一个半小时内完成,无论哪种方式,我都不想养成在中途重启生产数据库的习惯通过回滚)。事件日志中的更新消息绝对是天赐之物,就像编写批处理程序的任何人一样 会告诉你的;然而,事实证明他们是不准确的 - 至少他们是最糟糕的情况。

因为我们有幸成为使用这个生产箱的唯一两个人,所以选择 将数据库发送到为我们工作的恢复模式,并向我们提供了信息性消息 只有我们以前的回滚状态才能访问(或者至少我们无法做到 解释我们缺乏DBA技能)。我将来会推荐这样做吗? ......但是,绝对不是希望有关各方吸取教训,并且 我们可以向董事会索取一些适当的开发服务器资金! (史诗乔尔测试失败!)