杀死SQL spid后丢失数据

时间:2014-08-16 09:01:15

标签: sql-server data-integrity spid

对于我来说,作为新手DBA,这是一个非常危险的情况。

有时当我看到Activity Monitor屏幕中出现死锁时,如果查询没有结束并且处于挂起状态并且也是一个头部阻塞,我必须杀死该spid。并非总是如此,但有时候,虽然很少,在杀死spid后,大量数据正在从数据库中丢失。 我猜它从锁定开始就丢失数据直到我杀了。 据我所知,Sql server不会立即保存数据,它会等待一段时间(某种循环可能每15分钟一次)并在认为一切正常时保存数据。

例如,我每6小时进行一次完整备份,每10分钟进行一次事务备份。昨晚它无法在00:00进行备份,原因是spid在暂停状态等待。当我在早上08:30杀死那个spid时,我从00:00到08:30丢失了所有桌子的所有数据。

我有完整的恢复模式并使用MsSqlServer2012。

在生产数据库中丢失数据是非常大的风险。 我的问题是;我怎么能确定,在杀死spid之前SQL确实保存了数据?

2 个答案:

答案 0 :(得分:1)

在您描述的情况下,确实没有办法防止数据丢失。 SQL Server旨在检测死锁并自动选择要杀死的受害者(当然,除非您使用DEADLOCK_PRIORITY指定哪个查询不太重要)。这意味着必须进行回滚,并且SQL Server必须进行内务处理以确保数据一致性。你干涉了。没有办法丢失数据。

假设您有两个查询尝试使用资源并出现死锁。经过一段时间SQL Server检测到这一点并决定杀死一个线程。由于SQL Server遵循ACID的原则,因此查询不仅会自动停止,而且会开始回滚。如果此查询进行了大量更改,则意味着SQL Server必须滚动日志并在线程停止之前撤消所有更改。这意味着SQL Server找到死锁和解决死锁之间可能会经历非常非常长的时间。如果您尝试通过杀死死锁SPID来加速该过程,那么AT NO POINT。

这更多是组织和操作限制而非技术限制。您和使用SQL Server的员工必须意识到,如果您开始查询,它必须完成。这意味着查询是否完成,遇到错误并且必须回滚,是否选择在死锁场景中被杀死并且必须回滚等等,所有查询必须完成。知道了这一点,你应该继续前进,你不能杀死SPID,因为它们需要很长时间,或者因为它们已经陷入僵局。如果由于生产力的损失而被利益相关者追捕以杀死SPID,请教育他们为什么违规查询必须完成以及如果您进行干预可能会发生什么(生产数据丢失)。谈谈业务风险而不是“我们应该”或“我们不应该”。如果利益相关者不相信并且仍然希望您执行类似杀死SPID的操作,请升级到您的管理层并让他们做出决定。如果您是管理层,请非常清楚地记录利益相关方要求您执行危险操作并准备好文档。相信我,他们会问为什么生产服务器整天都在关闭,你需要能够清楚地记录所有玩家及其角色。

此外,使用服务器教育员工将大型交易拆分为较小的交易,或使用BEGIN / COMMIT。这样,如果出现问题并且必须回滚查询,则需要几分钟或几小时而不是几天。在过去的两年里,我们办公室的数据爆炸式增长,现在我们有几个表格,每个表格超过10亿行。学习期间非常痛苦:我们有几个星期的生产力是在厕所,因为人们试图进行大量更新或构建非常大的数据集,出现错误,随后的回滚是DAYS。在我们学习并实施了一些标准操作程序以将查询分解为更小的批次之后,事情变得更好了。不过,如果DBA刚刚开始杀死SPID,我会不禁想到会发生什么。

如果您继续杀死SPID,那么您可以采取任何措施来防止数据丢失。您必须让SQL Server继续管理查询,直到它完成或终止并完成回滚。如果您尝试手动终止这些查询,则会丢失数据。没有办法解决这个问题。

进一步阅读:

http://msdn.microsoft.com/en-us/library/aa480356.aspx

http://technet.microsoft.com/en-us/library/aa213030%28v=sql.80%29.aspx

https://www.simple-talk.com/sql/database-administration/handling-deadlocks-in-sql-server/

答案 1 :(得分:0)

使用块在代码内部完成数据库处理后,所有阻塞问题都消失了。