0

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

有时当我看到活动监视器屏幕中出现死锁时,如果查询没有结束并保持挂起状态并且还有一个头块,我必须杀死那个 spid。并非总是如此,但有时(尽管很少)在杀死 spid 后会从数据库中丢失大量数据。我猜它从锁定开始到我杀死它都会丢失数据。据我了解,Sql server 不会立即保存数据,它会等待一段时间(某种周期可能每 15 分钟一次)并在认为一切正常时保存数据。

例如,我每 6 小时进行一次完整备份,每 10 分钟进行一次事务备份。昨晚由于某种原因它无法在 00:00 进行备份,并且该 spid 处于挂起状态等待。当我在早上 08:30 杀死那个 spid 时,我从 00:00 到 08:30 丢失了所有表中的所有数据。

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

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

4

2 回答 2

2

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

假设您有两个查询试图使用一个资源并且出现了死锁。一段时间后,SQL Server 检测到这一点并决定终止一个线程。因为 SQL Server 遵循ACID的原则,所以查询不仅会自动停止,还会开始回滚。如果此查询进行了大量更改,则意味着 SQL Server 必须滚动浏览日志并撤消所有更改,然后才能停止线程。这意味着在 SQL Server 发现死锁和解决死锁之间可能会经过非常非常长的时间。在任何时候,您都不应尝试通过杀死死锁 SPID 来加快进程。

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

此外,教育使用服务器的员工将大事务分解为较小的事务,或使用BEGIN/ COMMIT。这样,如果出现问题并且必须回滚查询,则需要几分钟或几小时而不是几天。在过去的 2 年里,我们办公室的数据呈爆炸式增长,现在我们有几张表,每张表的行数都超过了 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/

于 2014-08-17T15:43:37.113 回答
1

在使用块内的代码中执行我的数据库进程后,所有阻塞问题都消失了。

于 2015-05-20T12:18:38.920 回答