3

我的一位同事(我保证是同事!)自上周四以来在我们的主 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 writeslogical_reads
52 暂停更新 daily_prices... 2328469 408947075 13831137 42458588 151809497

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

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

2 回答 2

2

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

在重新获得一些控制/工作系统方面,如果您有合适的备份,请让另一个数据库联机恢复备份/tlog 备份,但您不希望恢复到事务启动后的时间(或者它仍然必须回滚它.) 这至少为您提供了一个可以继续开发工作的系统,但不太可能是 prod 系统的理想情况。

如果它是生产服务器,请在执行之前与个人谈谈测试查询和查询计划的适用性。我相信许多 DBA 会建议不太礼貌的教学方法 :)

于 2010-07-20T12:43:14.650 回答
2

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

数据库开始回滚事务。

5天过去了。

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

(* 我们也知道足够多的数据库理论,知道数据库不会只是“忘记”正在进行的事务,但我们还在 SQL Server 错误日志中看到堆栈转储,这告诉我们 SQL Server 正在获取对不得不承担的回滚量越来越不满)

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

果然数据库进入了恢复模式。然而,SQL Server 事件日志现在每 20 秒左右向我们提供一次更新,以了解它需要多长时间(总的来说,它从日志消息中计算出大约 25 小时,但最终只有一个小时一半 (!))。

这种恢复/回滚的方法是否更快,我强烈怀疑(因为我希望 SQL Server 必须像以前一样做相同级别的工作来展开事务),但是它确实在一个半小时内完成,无论哪种方式,我不想养成在回滚到一半时重新启动生产数据库的习惯)。事件日志中的更新消息绝对是天赐之物,任何编写过批处理程序的人都会告诉你;不管结果多么不准确——至少它们是最坏的情况。

由于我们有幸成为唯一两个使用此生产盒的人,因此选择将数据库发送到恢复模式对我们有用,并为我们提供了我们之前无法访问的信息消息(或至少鉴于我们缺乏 DBA 技能,我们无法解释)。我会建议将来这样做吗?....绝对不是,但是,希望有关方面已经吸取了教训,我们可以向董事会要求一些钱来购买一个合适的开发服务器!(史诗般的乔尔测试失败!)

于 2010-07-27T08:38:49.970 回答