MySQL 主键索引在 RR 和 RC 隔离级别下的加锁情况总结

点击上方“业余草”,选择“置顶公众号”

第一时间获取技术干货和业界资讯!


MySQL 主键索引在 RR 和 RC 隔离级别下的加锁情况总结_第1张图片


最近群里不少人讨论了一些高质量的问题。我今天抽时间给大家总结一个 MySQL InnoDB 存储引擎各种不同 SQL 情况下,加行锁、间隙锁、next-key lock 做一个总结。如果有错误的地方,请大家指正!


MySQL 主键索引在 RR 和 RC 隔离级别下的加锁情况总结_第2张图片


为了讲清楚相关加锁的情况,我们先来创建一个测试验证用的表。结构如下所示:

MySQL 主键索引在 RR 和 RC 隔离级别下的加锁情况总结_第3张图片

然后插入几条测试数据。注意,我是在 MySQL 5.7 版本上测试的

640?wx_fmt=png

在开始之前,我先来解释一下,RR 和 RC。


RR 隔离级别就是,可重复读。REPEATABLE READ。


RC 隔离级别就是,读已提交。READ COMMITTED。


搞明白 RR 和 RC 后,我们先来看第一种情况。查询条件是聚簇索引,也就是主键索引的精确匹配情况。

MySQL 主键索引在 RR 和 RC 隔离级别下的加锁情况总结_第4张图片

上面这种情况下,如果 SQL 是精确查询,不管是 RR 还是 RC 隔离级别下,都会在命中的索引上加 record lock(行锁)。X 锁是排它锁(Exclusive Lock),也有人称作是写锁。S 锁是共享锁(Shared Lock),也有人称作是读锁。不管是 X 锁,还是 S 锁,都是加在行上的。注意,行锁不是加在记录上的,而是加在索引上的!


第二种情况,如果是范围查询,那么在在 RC 隔离级别下,会在所有命中的行的聚簇索引上加 record locks(锁行)。因为 RC 级别下是没有间隙锁的。

MySQL 主键索引在 RR 和 RC 隔离级别下的加锁情况总结_第5张图片

第三种情况,在 RR 隔离级别下,会在所有命中的行的聚簇索引上加 next-key locks(锁住行和间隙)。最后命中的索引的后一条记录,也会被加上 next-key lock。


MySQL 主键索引在 RR 和 RC 隔离级别下的加锁情况总结_第6张图片

第四种情况,如果查询结果为空,即没有命中任何聚族索引,那么,在 RC 隔离级别下,什么也不会锁。


第五种情况,如果查询结果为空,即没有命中任何聚族索引,那么,在 RR 隔离级别下,会锁住查询目标所在的间隙。

640?wx_fmt=png

以上,对于主键索引加锁的场景基本上已经全部覆盖到了。如果你还有什么疑问想讨论的,请加我微信:xttblog。


RR 隔离级别实现起来,要比 RC 复杂的多。给你留一个问题,MySQL 是出于什么样的考虑,默认是采用 RR 隔离级别?


MySQL 主键索引在 RR 和 RC 隔离级别下的加锁情况总结_第7张图片

扫描海报上的二维码,返现9元的加我微信:xttblog

你可能感兴趣的:(MySQL 主键索引在 RR 和 RC 隔离级别下的加锁情况总结)