大家好,欢迎回到性能调优培训。上2个星期我们已经讨论了SQLServer里的悲观和乐观锁。今天我想谈下SQL Server里对于锁的一个特殊现象:所谓的锁升级(Lock Escalations)。在我们进入那个问题的细节前,我想先谈下SQL Server内部使用的锁层级(Lock Hierarchy)

锁层级(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语句。如果你想了解更多锁升级信息,可以看下我以前写一篇文章《锁升级》。

下周我们继续SQL Server里的锁和阻塞,讲下死锁,还有SQL Server如何处理它们。请继续关注!

围观PPT:

1007_19_锁升级.rar

第19/24周 锁升级(Lock Escalations)相关推荐

  1. DB2 set current schema也能导致锁升级(lock escalation)?

    最近遇到锁升级的问题,发现db2diag.log里出现set current schema语句导致锁升级,印象中只有SQL语句会导致锁升级.于是模拟了一下,模拟的重点在于如何把locklist用满,并 ...

  2. MySQL 锁的相关知识 | lock与latch、锁的类型、简谈MVCC、锁算法、死锁、锁升级

    文章目录 lock与latch 锁的类型 MVCC 一致性非锁定读(快照读) 一致性锁定读(当前读) 锁算法 死锁 锁升级 lock与latch 在了解数据库锁之前,首先就要区分开 lock 和 la ...

  3. SQL Server Lock Escalation - 锁升级

    Articles Locking in Microsoft SQL Server (Part 12 – Lock Escalation) http://dba.stackexchange.com/qu ...

  4. MySQL 避免行锁升级为表锁——使用高效的索引

    众所周知,MySQL 的 InnoDB 存储引擎支持事务,支持行级锁(innodb的行锁是通过给索引项加锁实现的).得益于这些特性,数据库支持高并发.如果 InnoDB 更新数据使用的不是行锁,而是表 ...

  5. 12.synchronized的锁重入、锁消除、锁升级原理?无锁、偏向锁、轻量级锁、自旋、重量级锁

    小陈:呼叫老王...... 老王:来了来了,小陈你准备好了吗?今天我们来讲synchronized的锁重入.锁优化.和锁升级的原理 小陈:早就准备好了,我现在都等不及了 老王:那就好,那我们废话不多说 ...

  6. 第十二章:synchronized与锁升级

    相关面试题 锁优化背景 Synchronized 锁性能变化 jdk5 以前 复习:为什么任意一个对象都能成为锁? jdk6 之后 synchronized的种类以及锁升级流程 锁升级流程 无锁 偏向 ...

  7. synchronized 字节码层原理解析及锁升级

    作为Java程序员可能使用synchronized的频次不是很多大部分时间都是在crud,但是作为一个技术人还是要有点追求的,本篇文章想写了好久在此之前需要了解Java运行时数据区.Java字节码与字 ...

  8. SQL Server 锁升级

    锁升级(Lock Escalations)是 SQL Server 使用的优化技术,用来控制在 SQL Server 锁管理里把持锁的数量.锁升级是将许多细粒度锁 ((如行或页) 锁)转换为表锁的过程 ...

  9. synchronized 底层如何实现?什么是锁升级、降级?

    synchronized 底层如何实现?什么是锁升级.降级? synchronized 代码块是由一对 monitorenter/monitorexit 指令实现的,Monitor 对象是同步的基本实 ...

最新文章

  1. 卡巴斯基:远程工具Ammyy Admin被用来盗取银行账户
  2. 小米五android o卡吗,【图片】小米5优化教程,吃鸡卡的进来!!!_小米5吧_百度贴吧...
  3. JQuery开发之Galleriffic图片插件介绍
  4. [Android实例] 同一Activity的实例被多次重复创建
  5. 进程编译连接动态库,需要将动态库改为lib***.so
  6. python读取配置文件存在某配置_Python读取ini配置文件的方式
  7. 模块简介与matplotlib基础
  8. 虚函数与纯虚函数区别
  9. 软件项目管理知识点总结
  10. 最全总结 | 聊聊 Python 数据处理全家桶(Sqlite篇)
  11. 千峰教育2218期2022.10.19日
  12. Py之lime:lime库的简介、安装、使用方法之详细攻略
  13. 计算机开机进桌面很久,教你解决win10电脑开机黑屏很久才进入桌面的方法
  14. Oracle 存储过程中打印SQL影响的行数
  15. 第三方Banner制作轮播图的具体方法
  16. 如何生成随机数(模拟掷骰子的过程)-C语言
  17. android5.1.1版本怎么升级,Android 5.1 悄悄升级 版本号升至 LMY47E
  18. 2021年教你增加拿到BAT等大厂offer几率,分享PDF高清版
  19. python3.7批量爬取百度图片/搜狗图片
  20. 如何减少上下文切换?

热门文章

  1. 无法启动outlook “外出时的助理程序”
  2. 新一代数据中心:多层级混合设计与标准化评估
  3. Effective user and Real user
  4. vue开发使用vue-particles如何兼容IE11?
  5. Memcache知识点梳理
  6. freebsd重启网卡命令
  7. Google guava cache源码解析1--构建缓存器(3)
  8. hadoop + spark+ hive 集群搭建(apache版本)
  9. JavaScript对象
  10. AntDB上使用uuid