在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
前言某天,突然被问到 MySQL 的 next-key lock,我瞬间的反应就是: 这都是啥啥啥??? 这一个截图我啥也看不出来呀? 仔细一看,好像似曾相识,这不是《MySQL 45 讲》里面的内容么? 什么是 next-key lock
官网的解释大概意思就是:next-key 锁是索引记录上的记录锁和索引记录之前的间隙上的间隙锁的组合。 先给自己来一串小问号???
既然啥都不懂,那只好从头开始操作实践一把了! 先看看看 《MySQL 45 讲》中丁奇老师的结论: 看了这结论,应该可以解答一大部分问题,不过有一句非常非常重点的话需要关注: 所以,以上的规则,对现在的版本并不一定适用,下面我以 环境准备MySQL 版本:8.0.25 隔离级别:可重复读(RR) 存储引擎:InnoDB mysql> select @@global.transaction_isolation,@@transaction_isolation\G mysql> show create table t\G 如何使用 Docker 安装 MySQL,可以参考另一篇文章《使用 Docker 安装并连接 MySQL》 主键索引首先来验证主键索引的 next-key lock 的范围 此时数据库的数据如图所示,对主键索引来说此时数据间隙如下: 主键等值查询 —— 数据存在 mysql> begin; select * from t where id = 10 for update; 这条 SQL,对 可以通过 # mysql> select * from performance_schema.data_locks; mysql> select * from performance_schema.data_locks\G 具体字段含义可以参考 官方文档 结果主要包含引擎、库、表等信息,咱们需要重点关注以下几个字段:
结果很明显,这里是对表添加了一个 IX 锁 并对主键索引 id = 10 的记录,添加了一个 同样 可以得出结论: 对主键等值加锁,且值存在时,会对表添加意向锁,同时会对主键索引添加行锁。 主键等值查询 —— 数据不存在mysql> select * from t where id = 11 for update; 如果是数据不存在的时候,会加什么锁呢?锁的范围又是什么? 在验证之前,分析一下数据的间隙。
使用 data_locks 分析一下锁信息: 看下锁的信息 此时在另一个 Session 执行 SQL,答案显而易见,是 id = 12 不可以插入,而 id = 15 是可以更新的。 可以得出结论,在数据不存在时,主键等值查询,会锁住该主键查询条件所在的间隙。 主键范围查询(重点)mysql> begin; select * from t where id >= 10 and id < 11 for update; 根据 《MySQL 45 讲》分析得出下面结果:
先看下 data_locks 可以看到除了表锁之外,还有 id = 10 的行锁( 所以实际上 id = 15 是可以进行更新的。也就是说 结果验证也是正确的,id = 12 插入阻塞,id = 15 更新成功。 当范围的右侧是包含等值查询呢? mysql> begin; select * from t where id > 10 and id <= 15 for update; 来分析一下这个 SQL:
同样先看一下 data_locks 可以看出只添加了一个主键索引 id = 15 的 X 锁。 验证下 id = 15 是否可以更新?再验证 id = 16 是否可以插入? 事实证明是没有问题的! 当然,这里有小伙伴会说,在 《MySQL 45 讲》 里面说这里有一个 bug,会锁住下一个 next-key。 事实证明,这个 bug 已经被修复了。修复版本为 参考链接地址: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-18.html 搜索关键字:Bug #29508068) 咱们可以分别用 8.0.17 进行复现一下: 在 8.0.17 中 再来看下是 现在我估计大概率是在 8.0.18 版本修复 对比 data_locks 数据: 注意红色下划线部分,在 8.0.17 版本中 总结本文主要通过实际操作,对主键加锁时的 next-key lock 范围进行了验证,并查阅资料,对比版本得出不同的结论。 结论一:
优化后,导致后开,这个不知道是因为优化后,主键的区间会直接后开,还是因为是个 bug。具体小伙伴可以尝试一下。 结论二通过使用
基本已经摸清主键的 next-key lock 范围,注意版本使用的是 8.0.25。 疑问
文章篇幅有限,小伙伴可以先自己思考一下,尽量自己操作试一试,实践出真知。至于具体答案,那就需要下一篇文章进行验证并总结结论了。 到此这篇关于浅谈MySQL next-key lock 加锁范围 的文章就介绍到这了,更多相关MySQL next-key lock 加锁范围 内容请搜索极客世界以前的文章或继续浏览下面的相关文章希望大家以后多多支持极客世界! |
请发表评论