Day79【概念解析】Next-key Lock
行业概念

Day79【概念解析】Next-key Lock

· 约 1,023 字 · 阅读约 6 分钟
目录

整理定义

临键锁(Next-key Lock)= Gap Lock + Record Lock

临键锁是索引记录上的记录锁和索引记录之前的间隙上的间隙锁的组合。

复述展开

InnoDB 以这样的方式执行行级锁定:当它搜索或扫描表索引时,它会在遇到的索引记录上设置共享锁(S锁)或排他锁(X锁)。 因此,行级锁实际上是索引记录锁。 索引记录上的临键锁也会影响该索引记录之前的“间隙”。 也就是说,临键锁是索引记录锁加上索引记录之前间隙上的间隙锁。 如果一个会话对索引中的记录 R 具有共享锁或独占锁,则另一个会话无法在索引顺序中紧邻 R 之前的间隙中插入新索引记录。

假设索引包含值 10、11、13 和 20。该索引可能的临键锁涵盖以下区间,其中圆括号表示排除区间端点,方括号表示包含端点:

(-∞, 10]
(10, 11]
(11, 13]
(13, 20]
(20, +∞)

对于最后一个间隔,临键锁锁定索引中最大值和“supremum”伪记录的值高于索引中的任何值。上确界不是一个真正的索引记录,因此,实际上,这个下一个键锁只锁定最大索引值后面的间隙。 InnoDB的默认事务隔离级别为 可重复读(Repeated Read)。在这种情况下,InnoDB使用临键锁进行搜索和索引扫描,这可以防止幻读。

也可以理解为一种特殊的间隙锁。通过临建锁可以解决幻读的问题。 每个数据行上的非唯一索引列上都会存在一把临键锁,当某个事务持有该数据行的临键锁时,会锁住一段左开右闭区间的数据。需要强调的一点是,InnoDB 中行级锁是基于索引实现的,临键锁只与非唯一索引列有关,在唯一索引列(包括主键列)上不存在临键锁。

T2会因为T1对 age 为 19的列进行锁定后,将(14,20]的区间进行了锁定

很明显,事务 A 在对 age 为 24 的列进行 UPDATE 操作的同时,也获取了(14,20] 这个区间内的临键锁。

【funnylog.gitee.io/mysql45/21讲为什么我只改一行的语句,锁这么多.html】

理解体会

这里对 记录锁、间隙锁、临键锁 做一个总结

  • InnoDB 中的行锁的实现依赖于索引,一旦某个加锁操作没有使用到索引,那么该锁就会退化为表锁。

  • 记录锁存在于包括主键索引在内的唯一索引中,锁定单条索引记录。

  • 临键锁存在于非唯一索引中,锁定开区间范围内的一段间隔,它是基于间隙锁实现的。

相关文章