7

我正在阅读关于 SQL Server 锁升级的MSDN 页面上的 SQL Server 锁升级

我的问题是,似乎存在锁升级的主要原因是为了减少维护更多锁的开销(例如,当为一个表获取更多行锁时,然后将行级锁升级到表级)。我的问题是,维护更多的锁会提高并发性,这是一个好处,为什么是开销?在我的拙见中,锁应该足够小,以通过提高并发性来提高数据库性能。谁能用简单的方式解释为什么需要锁升级以及所谓的锁开销是什么?

提前谢谢,乔治

4

5 回答 5

15

谁能用简单的方式解释为什么需要锁升级以及所谓的锁开销是什么?

当您更新表并锁定一行时,您需要以某种方式记录这个事实:这是一行,它已被更新并锁定。

当你更新百万行时,你需要做这百万次,因此有一些空间来保存百万锁。

SQL Server 在内存中保存一个锁列表,而 Oracle 在表空间中保存。

这可能是因为 Oracle 比较老(比我老),而 SQL Server 比 Oracle 还年轻。

从设计师的角度来看,将临时资源(如锁)保存在永久存储中并不是那么明显的解决方案。只需提一件事:您可能需要磁盘写入才能执行SELECT FOR UPDATE.

Oracle 的核心功能是在 80 年代初开发的,当时根本无法选择将内容保存在内存中。他们只需要以某种方式使用磁盘空间。

如果要使用磁盘空间,则必须在磁盘的某处放置一个锁。

如果不在行本身内,在哪里保持一行的锁?

SQL Server 锁系统的开发人员在发明名为 Sybase 的 RDBMS 设计时,决定将临时的东西(即锁)存储在临时存储器(即 RAM)中。

但是 Oracle 的设计总是平衡的:如果你的数据库中有 1,000,000 行,那么你就有 1,000,000 个锁的存储空间,如果你有 10 亿行,你可能会存储 10 亿个锁,等等。

SQL Server 的设计在这个意义上是有缺陷的,因为你的 RAM 和 HDD 空间可能不平衡。您可能很容易拥有 16M 的 RAM 和几 TB 的磁盘空间。而你的记忆就是无法拥有所有的锁。

这就是为什么当锁计数达到某个限制时,SQL Server 决定升级锁:它不是为数据页中的 10 个单独的行(需要 10 条记录)保持锁,而是锁定整个数据页(这需要1 条记录)。

另一方面,Oracle 在更新行时,只是将锁直接写入数据页。

这就是为什么 Oracle 的锁是行级的。

Oracle 不会以一般意义上的“管理”锁:例如,您无法在 Oracle 中获取锁定页面的列表。

当事务需要更新一行时,它只是去该行并查看它是否被锁定。

如果是,它会查看哪个事务持有锁(此信息包含在数据页的锁描述符中)并将自身添加到该事务的通知队列中:当锁定事务终止时,原始事务会收到通知并锁定数据。

从并发的角度来看,锁升级完全是穷人的解决方案:它不会增加并发。比如说,你可以锁定你甚至没有碰过的行。

从性能的角度来看,在内存中做事当然比在磁盘上做事要快。

但是由于 Oracle 缓存了数据块,并且上述实际操作无论如何都是在内存中执行的,因此性能是相同或接近的。

于 2009-05-16T16:55:58.737 回答
4

如果 SQL Server 优化器估计/决定查询将“访问”某个范围内的所有行,那么在该范围内持有单个锁而不是必须协商许多锁(必须针对锁进行测试类型)。这是除了消耗更少的锁资源(系统范围的资源)之外的。

如果您有一个设计良好的模式和适合您的查询工作负载的索引,这些索引会定期维护,那么您不必担心正在发生的升级。在许多情况下,可以通过适当的覆盖索引来消除阻塞表锁。

更新:查询的覆盖索引意味着不需要执行对集群的查找,这减少了阻塞插入表的机会。

于 2009-05-16T16:47:21.317 回答
1

锁开销意味着管理一个表锁比管理大量行锁更明智。因为每个锁都占用一些内存,所以很多行锁比一个表锁消耗更多的内存。所以锁升级从行->页->表锁开始。

于 2009-05-16T16:23:10.547 回答
1

“高效”的定义很复杂。有时,如果许多进程可以在没有冲突的情况下进行并发优化,那么优化并发性会更有效。有时,通过临时并发攻击来更快地完成单个进程会更有效。升级的锁将阻止其他进程,因此该进程可以完成其工作并让路。

于 2009-05-16T16:54:57.663 回答
1

有关如何维护锁的具体信息,您可以查看 Microsoft SQL Server 2005: The Storage Engine 的第 8 章(我不隶属于此,这只是我遇到的第一个内部信息)。如果您有一个 books24x7 帐户,它就在那里。它显示在大于 16gb 内存的机器上,锁哈希表中有 2^25 (33554432) 个插槽,上限为 2^31 个插槽。

对于给定的应用程序,您可能会发现仅使用细粒度锁的总吞吐量会更高。正如您可能猜到的那样,这完全取决于锁管理的开销与潜在的过度锁定相比如何。

于 2009-05-16T18:14:18.643 回答