【MySQL】next-key lock规则
目录
next-key lock
next-key lock是行锁和间隙锁的组合,只有在InnoDB的可重复读隔离级别下,才可以使用。
行锁是加在索引上的。如果索引,就对该索引加锁。列上没有索引,就会在主键上加锁。
间隙锁是加在索引之间的锁,用于避免其他事务在某个间隙内插入或修改数据,只有在可重复读隔离级别下才可使用。
next-key lock避免了幻读问题的产生。
加锁规则
-
加锁的基本单位是
next-key lock。 -
查找过程中,访问到的对象才会加锁,此处的对象是指索引。
-
对于唯一索引上的等值查询,加锁时,
next-key lock退化为行锁。 -
对于非唯一索引上的等值查询,需要向右遍历,访问到不满足条件的第一个值。给该值加锁时,
next-key lock退化为间隙锁。 -
对于唯一索引上的范围查询,会访问到不满足条件的第一个值为止。如果是
MySQL8.0.23版本,next-key lock会退化为间隙锁,其他版本(>= 5.7.24, >= 8.0.13)待测试。 -
对于非唯一索引上的范围查询,也会访问到不满足条件的第一个值为止。对于
MySQL8.0.23版本,next-key lock不会退化为间隙锁。
主键加锁
通常情况下,给索引加锁的同时,也会给主键加行锁(不论索引是行锁还是间隙锁)。
如果使用lock in share mode加锁,并且使用到了覆盖索引,则主键不会被加锁。应当避免这种情况产生。
如果使用for update加锁,并且查询数据存在,则即使使用到了覆盖索引,也会给主键加行锁。
delete语句的规则类似于select ... for update。
limit的影响
如果使用了limit关键字,当查询到的记录数量达到limit要求时,会停止扫描,从而可以减小加锁范围。