Next-Key Locks

Next-Key Locks是在存储引擎innodb、事务级别在可重复读的情况下使用的数据库锁,官网上有介绍,Next-Key Locks是行锁和gap锁的组合。行锁是什么我们都很清楚,这篇文章主要简单分析一下mysql中的gap锁是什么。innodb默认的锁就是Next-Key locks。

GAP锁

gap锁,又称为间隙锁。存在的主要目的就是为了防止在可重复读的事务级别下,出现幻读问题。

在可重复读的事务级别下面,普通的select读的是快照,不存在幻读情况,但是如果加上for update的话,读取是已提交事务数据,gap锁保证for update情况下,不出现幻读。

那么gap锁到底是如何加锁的呢?

假如是for update级别操作,先看看几条总结的何时加锁的规则。

  • 唯一索引
    • 精确等值检索,Next-Key Locks就退化为记录锁,不会加gap锁
    • 范围检索,会锁住where条件中相应的范围,范围中的记录以及间隙,换言之就是加上记录锁和gap 锁。
    • 不走索引检索,全表间隙加gap锁、全表记录加记录锁
  • 非唯一索引
    • 精确等值检索,Next-Key Locks会对间隙加gap锁(至于区间是多大稍后讨论),以及对应检索到的记录加记录锁。
    • 范围检索,会锁住where条件中相应的范围,范围中的记录以及间隙,换言之就是加上记录锁和gap 锁(至于区间是多大稍后讨论)。
    • select * from xxx where aa=1 for uodate查询的记录不存在时,分为两种情况
        1. 查询条件值大于当前列最大值:gap锁为(列最大值,无限)
        1. 查询条件值小于当前列最大值大于最小值:gap锁为 [上一个值,下一个值)
        1. 查询条件值小于当前列最小值:gap锁为(无限,上一个值)
  • 非索引检索,全表间隙gap lock,全表记录record lock
  1. innodb_locks表在8.0.13版本中由performance_schema.data_locks表所代替,innodb_lock_waits表则由performance_schema.data_lock_waits表代替。