简介:
大家好 , 我是xp 。
突然想起 , 上篇的MySQL5.7 MVCC原理分析与调试只是描述了mvcc解决不可重复读的情况 , 并没有描述如何解决幻读的 。
幻读:侧重于insert、delete这种操作 , 第一次查出生成视图之后 , 即便有别的事务insert、delete , 也不影响后续的查询 。
首先解释下本次涉及的3种锁:
- X锁:俗称写锁/排他锁 , 即加锁之后 , 不允许别的事务来修改当前数据 。
- GAP锁:俗称间隙锁 , 就是锁住某个范围(RR级别解决幻读的关键)
- Next-Key锁:GAP锁+记录本身
文章插图
八股文:B+tree:非叶子节点只存储索引 , 所有叶子节点之间都有一个链指针 , 不存储数据 , 数据记录都存放在叶子节点中 。
如下图所示:
文章插图
上面是B+tree的数据结构 , 一定要记住叶子节点 , 里面包含了索引和data(主键/其他数据) 。
有一点需要说明:叶子节点是按页存储的 , 页之间是双向链表 , 页里面的叶子节点是单向链表 。
来个预热:
文章插图
场景:1:表结构(id是主键 , count为普通索引):
文章插图
开启事务1:
文章插图
先查询count = 5 , 生成视图 。
开始事务2:
文章插图
【Next-Key锁的分析与调试 MySQL5.7 解决幻读的原理】此时插入一条count = 4的数据 , 很明显 , 被阻塞住了 。
为啥要阻塞count = 4的记录呢?因为RR级别下 , 其实是加了GAP锁 , 不允许插入某个范围的值 , 从而避免了幻读的出现 , 那么这个范围是怎么定义的呢?
文章插图
这是官网的 , 应用于我上面的例子 , 锁住的就是(3 , 5] , (5 , 7] , 左开右闭 。
好了 , 大家都散了吧 。结论已经得出了:
加了范围锁 , 不允许插入数据 , 所以不会出现幻读的情况 , 范围如上 。
文章插图
什么 , 你反对?
文章插图
对于GAP的范围 , 看到网上很多讨论 , 有的说是测试的左开右闭 , 也有说测试的左闭右开 。
这里 , 我想说 , 虽然实践是检验真理的标准 , 但是实践的前提是 , 你得明白实践方式对不对 。
好 , 我们继续 , 上面的测试情况:
可以具体成上图 , 因为是普通索引 , 所以data只包含了主键 。
文章插图
那么锁住的是哪一块呢?
文章插图
锁的其实是上述的区间 , 而左开右闭 , 左闭右开都是错误的 。要看插入的位置
文章插图
超出那个区间的就可以插入 , 反之即不可以插入 , 这个位置是按主键排序的 。
- count=3,id=32 , 可以插入
- count=3,id=34 , 不可以插入
- count=7,id=76 , 不可以插入
- count=7,id=78 , 可以插入
1.count=3,id=32:
推荐阅读
- 网站被XSS攻击挂马的危害
- MySQL误删数据后切勿跑路
- 小程序消息推送,订阅消息的实现,定时推送订阅消息功能
- 如何判断MySQL实例出了问题
- 能发现又能阻止入侵的防护技术——入侵防御系统
- 5款让人赞不绝口的电脑软件!绿色纯净无广,建议悄悄收藏
- 实战总结的7个C程序,好东西不私藏
- 人工智能文档编写器:使用AI生成Javadocs等文档的插件扩展
- Tomcat源码篇-简单到超乎想象的启动流程
- 金俊眉属于小种红茶吗,金俊眉茶的功效与作用女人们