mysql RC 隔离级别下为什么需要 next key lock 来保证唯一索引有效性

 一:RC 隔离级别下通过next key lock 来保证唯一约束生效

  我们知道在RC隔离级别中几乎不会出现 Gap Lock,但是官方文档中列出了如下两个例外情况(在外键约束和唯一性约束时还是会使用Gap Lock,即使在RC隔离级别下)。

 

二:未使用 next key lock,RC隔离级别下出现唯一约束失效BUG

我实话按我个人的理解,RC隔离级别下确实不需要使用Gap Lock 来保证唯一性约束。有人跟我有同样的想法,并且MySQL 做了修改去掉了使用Gap Lock 来保证唯一性,但是很不幸的是,修改后发生了唯一约束失效的BUG,bug地址如下:

bug#68021

  上面的bug中以及下面的阿里云内核月报文章中,都给出了触发bug的测试脚本

MySQL · 内核分析 · InnoDB主键约束和唯一约束的实现分析

在内核月报中给出的触发bug的例子如下:

Transaction 1:
begin;
delete from t1 where c2 = 5; // 加X NOT_GAP lock,成功
Transaction 2:
insert into t1 select 1,5; // 加S NOT_GAP lock,等待
Transaction 3:
insert into t1 select 2,5; // 加S NOT_GAP lock,等待
Transaction 1:
commit;
T1 释放X NOT_GAP lock
T2 加S NOT_GAP lock成功
T3 加S NOT_GAP lock成功(S锁互相兼容)
T2 加X insert intention lock成功(X IK和S RK兼容)
T3 加X insert intention lock成功(X IK和S RK,X IK均兼容)
T2 插入记录成功
T3 插入记录成功

三:我的疑惑

上面例子中看似解释是很合理的,但是我有一个疑惑,在 T1 提交后,T2,T3 确实会成功的加上 S NOT_GAP lock。但是有一个重要的环节好像被忽略了,那就是修改或者读取页面需要对页面加上RW-X-LATCH 或者RW-S-LATCH锁,所以正确的过程应该如下

1) T2 申请页面上的 RW-X-LATCH 锁,成功后进行唯一约束检查发现冲突,所以

T2 释放 RW-X-LATCH 并等待S NOT_GAP lock

2) T3 申请页面上的 RW-X-LATCH 锁,成功后进行唯一约束检查发现冲突,所以

T3 释放 RW-X-LATCH 并等待S NOT_GAP lock

3) T1事务提交

4) T1事务提交后,T2,T3获取了各自等待的 S NOT_GAP lock,但是他们获取的锁都是在没有 RW-X-LATCH 锁的保护下获得的,所以这时T2和T3 应该重新获取 RW-X-LATCH锁,在该锁的保护下重新判断加锁,因为这个过程是串行的,所以我认为不应该导致两条记录都被插入成功,最后只应该有一条插入成功

NOTE:第三部分只是个人的疑惑,能力有限,如果哪位大神对这一块比较清楚的,望请不吝赐教

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

渔夫数据库笔记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值