# 什么是next-key lock?

什么是next-key lock?

在RR(可重复读,mysql默认事务隔离级别)隔离级别下,mysql 通过next-key lock解决了大部分幻读的场景。
next-key lock 由行锁和间隙锁组成。
比如(5, 10) 和 加在10上的行锁组成(5,10]的next-key lock

怎么加next-key lock?

  1. 加锁的基本单位是next-key lock, 前开后闭区间;
  2. 查找过程访问的对象才会加锁
  3. 优化1:索引上的等值查询,唯一索引加锁会退化为行锁
  4. 优化2:索引上的等值查询,向右遍历且最后一个值不满足等值条件时候,next-key lock
    退化为间隙锁
  5. mysql 5.xxx <= 5.7.24 和 8.0系列 <= 8.0.13 的 版本,当给唯一索引加锁时,会
    访问到不满足条件的第一个值为止。

等值查询:指的是搜索索引树的过程。

例子

select * from t where id > 9 and id < 12 order by id desc for update;

加锁 (0, 5], (5, 10], (10, 15)

加锁过程: 第一个满足条件的是id=10,加next-key lock (5, 10],
id=10是索引树上存在的记录,继续往右侧查询,根据优化2,加间隙锁(10, 15)。
根据order by id desc,然后往左遍历,遇到5, 加next-key lock
(0, 5], 因为5已经不满足id < 9条件了,停止遍历

select * from t where id > 9 and id < 12 order by id for update;

加锁 (5, 10], (10 15]

加锁过程:跟上面一样,第一个满足条件的是id=10,加next-key lock (5, 10],
往右遍历,遇到15,加next-key lock (10, 15), 不满足id < 12条件了,停止遍历。

select * from t where c > 5 lock in share

加锁:(5,10]、(10,15]、(15,20]、(20,25]和 (25,supremum]

加锁过程:从索引树上遍历,第一个遇到10,加(5, 10], 然后,15,20,25。最后的25加的是
(25, supremum], supremum 代表正无穷。

lock in share mode 对比 for update

select id from t where c=5 lock in share mode;

加锁:(0, 5], (5, 10)

加锁过程:在索引树上找到c=5,加next-key lock (0,5], 由于不是c不是唯一索引,还需要继续往右
查找,找到10,加next-key lock (5,10],根据优化2,10不满足等值条件,退化为(5,10)。因此查询刚好被索引覆盖了,主键不用锁上,
因此主键索引5是可以更新的,但是for update就会顺便把主键也锁上

posted @ 2021-07-25 15:10  yihailin  阅读(2517)  评论(0编辑  收藏  举报