锁升级(Lock Escalations)

简介:

锁层级(Lock Hierarchy)

2个星期前,当我们开始讨论悲观并发模式(pessimistic concurrency)时,我告诉你SQLServer在记录层会获取共享锁(Shared Locks)和排它锁(Exclusive Locks)。遗憾的是,这不是全部事实。完整事实是SQL Server会在不同粒度(granularities)获得锁,例如数据库,不同页,最后在记录层。SQL Server实现整个所层级(lock hierarchy),如下图所示:

一旦你使用一个数据库,你的会话会在数据库上获得一个共享锁(Shared Lock)。那个共享锁是需要的,因此没有其他人可以删除数据库,或还原数据库备份。这些操作会被阻塞,因为你打开的会话。SQL Server不但在行层上有共享锁和排它锁,SQL Server也在表和页层使用所谓的意向锁(Intent Locks)

  • 在行层有共享锁(Shared Locks),在表和页上拿到意向共享锁(intent shared lock(IS))。
  • 在行层有排它锁(Exclusive Locks),在表和页上拿到意向排它锁(intent exclusive lock(IX))。

意向锁(Intent Locks)用来作为1个信号,表示在锁层级(lock hierarchy)里(很可能)有1个不兼容的锁在低一层已获得。意向锁是关系数据库主要性能调优。没有它们的话,锁管理器需要在低1层完全进入列表,来决定高1层的锁是否可以获取。如果你在表层有一个意向排它锁(IX),你就不能在表层获得排它锁(X),因为有些记录在表本身里已经是排它锁(X):在表层获得排它锁(X)会阻塞,因为在表上已经有意向排它锁(IX)。

遗憾的是这个多粒度锁并不是免费的:在SQL Server里每个锁需要96 bytes,因此会消耗一些内存,SQL Server必须保证没有查询使用太多的内存空间,不然的话内存会被耗尽。这就是为什么会有锁升级(lock escalations)的存在。

锁升级(Lock Escalations)

假设下列情景:你更新散布在20万个数据页上的1百万条记录。在那个情况下,你需要在记录本身获得1百万个排它锁(X),在不同页上获得20万个意向排它锁(IX),在表本身上获得1个意向排它锁(IX),你的查询合计需要获得1200001,在锁管理器需要近110M的锁空间——就只对这个简单查询。依据内存占用这个方法非常危险。因此你在一层一旦获得超过5000个锁,SQL Server就会触发锁升级(Lock Escalations)——例如在记录层。在那个情况下,SQL Server升级你个体细密度行锁为1个粗颗粒的表锁:

  • 个体X锁升级为1个表的X锁
  • 个体S锁升级为1个表的S锁

下图演示了锁升级发生前后的锁保持情况:

通过锁升级内存占用肯定会下降——但这也会影响你数据库的并发!在表上的排它锁(X)意味着没有其他人可以从你的表读写,在表层上的共享锁(S)意味着你的表是只读的,没有人可以写它!你数据库的吞吐量只会下降!

当你在1个层获得超过5000个锁,SQL Server就会触发锁升级。这是系统硬码限定,不同通过任何配置选项修改。自SQL Server 2008开始,你可以通过如下代码,控制通过ALTER TABLE DDL语句的锁升级:

复制代码
1 ALTER TABLE MyTableName
2 SET
3 (
4    LOCK_ESCALATION = TABLE -- or AUTO or DISABLE
5 )
6 GO
复制代码

默认情况,SQL Server总是升级到表级别(Table选项)。如果你设置升级选项为AUTO,当你的表是分区的话,SQL Server可以升级到分区级别。但对这个选项,你要非常仔细,因为如果你用错误的顺序访问分区,它会导致死锁。使用DISABLE选项,对表你停用了锁升级——这会带来刚才提到的所有各个副作用(内存消耗)。现在的问题是,你如何高效修改或删除5000条记录而不触发锁升级?

  1. 逐步更新/删除少于5000条记录(例如在WHILE循环里)
  2. 如果表分区的话,使用分区交换
  3. 临时停用锁升级,但要注意同时的内存耗用

小结

锁升级(Lock Escalations)是SQL Server提供的安全保障。它们为什么存在有个好理由,但当升级发生时,这个会引入更少并发的副作用。因此当你在写一次处理超过5000条记录的代码时要非常仔细。或许你可以逐步处理这些记录,而不是用1个大的UPDATE/DELETE语句。如果你想了解更多锁升级信息,可以看下我以前写一篇文章《锁升级》。



本文转自Woodytu博客园博客,原文链接:http://www.cnblogs.com/woodytu/p/4705602.html,如需转载请自行联系原作者

相关文章
|
SQL 数据库
解决SQL报错提供了过多的参数,最多应为 2100
解决SQL报错提供了过多的参数,最多应为 2100
1099 0
|
SQL 存储 数据挖掘
Dremio架构分析
一.Dremio架构 Dremio是基于Apache calcite、Apache arrow和Apache parquet3个开源框架构建,结构其核心引擎Sabot,形成这款DaaS(Data-as-a-Service)数据即服务平台;整体体验风格与其公司开源的Apache Drill非常接近。
10288 0
|
边缘计算 数据可视化 物联网
node-red介绍
Node-RED最初是IBM在2013年末开发的一个开源项目——基于数据流(dataflow)的可视化编程工具。
node-red介绍
|
4月前
|
数据采集 弹性计算 Kubernetes
单机扛不住,我把爬虫搬上了 Kubernetes:弹性伸缩与成本优化的实战
本文讲述了作者在大规模爬虫项目中遇到的挑战,包括任务堆积、高失败率和成本失控。通过将爬虫项目迁移到Kubernetes并使用HPA自动伸缩、代理池隔离和Redis队列,作者成功解决了这些问题,提高了性能,降低了成本,并实现了系统的弹性伸缩。最终,作者通过这次改造学到了性能、代理隔离和成本控制的重要性。
168 2
单机扛不住,我把爬虫搬上了 Kubernetes:弹性伸缩与成本优化的实战
|
4月前
|
Java 开发工具 Maven
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
【01】完整的安卓二次商业实战-详细的初级步骤同步项目和gradle配置以及开发思路-优雅草伊凡
332 6
|
11月前
|
人工智能 缓存 编解码
《告别加载卡顿!AI如何为网页加载速度开挂》
在这个信息飞速流转的时代,用户对网页加载速度的要求越来越高。AI为提升页面加载速度提供了创新解决方案,包括预测性资源预加载、智能图像优化、代码优化与精简及智能缓存管理。通过分析用户行为和数据,AI可提前加载资源、优化图像和代码结构、合理管理缓存,显著缩短加载时间,提升用户体验。这已成为网络开发的必然趋势,未来将带来更流畅的浏览体验。
388 16
|
11月前
|
机器学习/深度学习 自然语言处理 TensorFlow
解锁 AIGC 工具:入门者到高级达人的终极蜕变手册
解锁 AIGC 工具:入门者到高级达人的终极蜕变手册
|
10月前
|
存储 人工智能 安全
终端云计算步入快车道,无影云电脑综合办公体验超PC
终端云计算步入快车道,无影云电脑综合办公体验超PC
|
机器学习/深度学习 存储 并行计算
CPU 和 GPU到底有啥区别?
【5月更文挑战第10天】
2791 2
CPU 和 GPU到底有啥区别?