如果我们在sql-server中启用读取已提交的快照,会有什么风险?


70

我在这里已经读到,每行将存储一些额外的数据,因此我们可能会看到性能下降,但是还有哪些其他风险?

例如。这会影响数据库的恢复吗?我们还需要采取其他措施来利用这一优势吗?

我计划执行以下命令:

ALTER DATABASE DatabaseName SET READ_COMMITTED_SNAPSHOT ON
ALTER DATABASE DatabaseName SET ALLOW_SNAPSHOT_ISOLATION ON

我相信这将使我们更接近oracle,如果一个事务正在更新,其他事务仍可以读取旧数据。这个对吗?

我正在研究此问题,因为我厌倦了SQL Server 2005中的锁定问题。我希望这可以减少用户偶尔看到的死锁,有助于提高应用程序的整体性能,并鼓励我们的开发人员为每个事务执行多个操作而无需恐惧。

Answers:


48

摘要

  1. 如果您有锁定问题,那么您的代码有问题:它不是数据库引擎
  2. 这不是魔术子弹
  3. 您可能会添加更多问题

加载

这也会增加tempdb和CPU的负载。另请参阅:

安全

最重要的,默认情况下,快照隔离在许多情况下都不安全。阅读“快照隔离”(维基百科),以了解有关写偏斜异常的更多信息。下一节是“使快照隔离可序列化”以解决此问题。

因此,总的来说,快照隔离给用户带来了一些维护非平凡约束的问题,用户可能不理解潜在的陷阱或可能的解决方案。这种转移的好处是更好的性能。

另请参阅:


35

我知道这是一个旧线程,但是我想说快照隔离在很大程度上一个神奇的子弹。它将消除您在读者和作家之间的所有障碍。但是,这不会阻止作者阻止其他作者。没有办法解决。

以我的经验,TEMPDB上的额外负载可以忽略不计,行版本控制在减少阻塞的读取器方面的好处是巨大的。

作为参考,行版本(快照隔离)是甲骨文公司已经使用了几十年来实现隔离不我已经工作了近20年的经验阻塞读者和Oracle DB的方法远远比SQL Server会少阻塞问题。尽管大多数SQL开发人员都不愿使用快照隔离,因为他们仅针对使用默认设置的数据库测试了其代码。


26

要增加其他答案的几点要点:

SET ALLOW_SNAPSHOT_ISOLATION ON仅在数据库中启用快照隔离。要利用它,您必须重新编码并SET TRANSACTION ISOLATION LEVEL SNAPSHOT进行您想应用的事务。调用代码将需要更改以处理更新冲突错误。

之后SET READ_COMMITTED_SNAPSHOT ON,提交已提交的语句使用行版本控制。请注意,这是只读的语句级行版本控制。对于更新,将检索“真实”行并应用更新锁。请参阅了解基于行版本的隔离级别中的行为摘要部分。

无论哪种方法,如果没有详尽的测试,您可能会给系统带来一系列全新的问题。


19

我相信这将使我们更接近oracle,如果一个事务正在更新,其他事务仍可以读取旧数据。这个对吗?

是的,这是正确的

值得一读gbn答案中的链接,我相信这同样适用于Oracle的默认MVCC和快照隔离模式下的SQL Server。我要补充一点,如果您了解潜在的陷阱,则IMO的收益将远远超过增加的困难(从Oracle的角度来讲)-当然,一些锁定问题也将合法地消失,这就是MVCC的意义(还有一类锁定由于代码问题而不会消失的问题,但是我假设您理解这一点。


9

我们在所有使用SQL Server DB的项目中都使用SNAPSHOT ISOLATION。不再有1205 SQL错误,不是由错误的应用程序代码引起的,而是由默认页面锁定和行锁定行为引起的。

对性能的影响是最小的,到目前为止已经过去了7年,已经在不同的系统中处理了亿万次操作,而快照分离没有任何问题。

多个不同的线程并行更新单个行中的业务关键信息的情况非常例外,并且快照隔离将成为任何不一致问题的原因的可能性非常接近零。

如果您具有OLTP系统,则可以通过设计基于多个线程中的当前行数据更新单行,在这种情况下,当然SNAPSHOTS是不可接受的。


-2

我们激活了它,并且运行4的奇怪的sql语句阻止了整个db,无论有多少个内核和所有内核。设置RCSI可以解决该问题。一旦遇到其他僵局,我就会将其打开,而不是默认情况下。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.