目录

【MySQL】next-key lock规则

next-key lock

next-key lock是行锁和间隙锁的组合,只有在InnoDB的可重复读隔离级别下,才可以使用。

行锁是加在索引上的。如果索引,就对该索引加锁。列上没有索引,就会在主键上加锁。

间隙锁是加在索引之间的锁,用于避免其他事务在某个间隙内插入或修改数据,只有在可重复读隔离级别下才可使用。

next-key lock避免了幻读问题的产生。

加锁规则

  1. 加锁的基本单位是next-key lock

  2. 查找过程中,访问到的对象才会加锁,此处的对象是指索引。

  3. 对于唯一索引上的等值查询,加锁时,next-key lock退化为行锁。

  4. 对于非唯一索引上的等值查询,需要向右遍历,访问到不满足条件的第一个值。给该值加锁时,next-key lock退化为间隙锁。

  5. 对于唯一索引上的范围查询,会访问到不满足条件的第一个值为止。如果是MySQL8.0.23版本,next-key lock会退化为间隙锁,其他版本(>= 5.7.24, >= 8.0.13)待测试。

  6. 对于非唯一索引上的范围查询,也会访问到不满足条件的第一个值为止。对于MySQL8.0.23版本,next-key lock不会退化为间隙锁。

主键加锁

通常情况下,给索引加锁的同时,也会给主键加行锁(不论索引是行锁还是间隙锁)。

如果使用lock in share mode加锁,并且使用到了覆盖索引,则主键不会被加锁。应当避免这种情况产生。

如果使用for update加锁,并且查询数据存在,则即使使用到了覆盖索引,也会给主键加行锁。

delete语句的规则类似于select ... for update

limit的影响

如果使用了limit关键字,当查询到的记录数量达到limit要求时,会停止扫描,从而可以减小加锁范围。