我们有一个大型多用途应用程序,在许多表上都存在 OBJECT 和 PAGE 块。我们无法重新考虑设计,但需要减少影响客户端机器性能的块。我一直在考虑在一张表上禁用锁升级,但需要知道它会给其他资源带来什么压力。磁盘 i/o 已经紧张。额外的单个锁会比自动表锁需要更多的 i/o 吗?它会比我们的应用程序数据库更影响我们的系统数据库吗?我们不进行全表更新/读取。每个请求只会处理表的一小部分。
1 回答
我们有一个大型多用途应用程序,在许多表上都存在 OBJECT 和PAGE 块。
...
磁盘i/o已经紧张。额外的单个锁会比自动表锁需要更多的i/o吗?
您误解了锁升级,这从我大胆提出的问题部分中可以清楚地看出。
Lock escalation go from rows to table
or from pages to table
(我排除了分区,因为它不是你的情况),所以如果现在你有页面锁,它不是 lock escalation。
除非您使用提示 ( rowlock
, paglock
),否则服务器会选择锁定粒度,并且如果选择page locks
了则不会升级。如果它随后删除所有page locks
并用 替换它们table lock
,则表示lock escalation
发生。
错误的第二件事是您认为锁与IO
. 这不是真的。锁保存在内存中,与读取无关。您可以查看这篇文章以了解锁定更细粒度时如何增加:CPU usage
为什么ROWLOCK 提示会使 SQL Server 中的查询变慢和阻塞更糟。query duration
您应该了解导致锁升级的原因。
锁定升级阈值
ALTER TABLE SET LOCK_ESCALATION
当使用该选项未在表上禁用锁升级时,并且存在以下任一情况时,将触发锁升级:
- 单个 Transact-SQL 语句在单个非分区表或索引上获取至少 5,000 个锁。
- 单个 Transact-SQL 语句在分区表的单个分区上获取至少 5,000 个锁,并且该
ALTER TABLE SET LOCK_ESCALATION
选项设置为 AUTO。- 数据库引擎实例中的锁数超过内存或配置阈值。
因此,如果每个语句阈值达到 5,000 个锁,则应将操作拆分为更小的批次。
如果你有内存压力,禁用锁升级会让你的情况变得更糟。
更新
锁不是磁盘结构。您不会直接在数据页或表头上找到锁字段,并且跟踪锁的元数据永远不会写入磁盘。锁是内部内存结构:它们消耗部分用于 SQL Server 的内存。锁由锁资源标识,锁资源是对被锁定资源(行、索引键、页或表)的描述。为了跟踪数据库、锁的类型和描述锁定资源的信息,每个锁在 32 位系统上需要 64 字节的内存,在 64 位系统上需要 128 字节的内存。这种 64 字节或 128 字节的结构称为锁块。...锁管理器维护一个锁哈希表。包含在锁块中的锁资源被散列以确定散列表中的目标散列槽。散列到同一槽的所有锁块都从散列表中的一个条目链接在一起。每个锁定块都包含一个描述锁定资源的 15 字节字段。锁块还包含指向锁所有者块列表的指针。这三个状态中的每一个都有一个单独的锁所有者列表。
希望能帮助到你。