InnoDB锁的算法

行锁的三种算法

  • Record Lock:单个记录上的锁
  • Gap Lock:间隙锁,锁定一个范围,但不包含记录本身
  • Next-Key Lock:Gap Lock+Record Lock,锁定一个范围,并且锁定记录本身。
采用Next-Key Lock的锁定技术称为Next-Key Locking。它是为了解决幻读,如果一个索引有10,11,13,20这几个值,采用Next-Key Locking后,上锁的区间为:
(-∞,10)
[10,11)
[11,13)
[13,20)
[20,+∞)
我们来看下Next-Key Lock在列为唯一索引与辅助索引下的不同表现形式,先看唯一索引:
如果列是唯一索引,Next-Key Lock会被优化,并降级为Record Lock,也就是仅锁住索引本身而不是范围。
如果是辅助索引就需要好好分析下了,我们看下面的示例:
create table z(a int,b int,primary key(a),key(b)); insert into z select 1,1; insert into z select 3,1; insert into z select 5,3; insert into z select 7,6; insert into z select 10,8;

【InnoDB锁的算法】表有两列,a为唯一索引,b为辅助索引。接下来执行下面sql:
select * from z where b=3 for update;
因为a上是唯一索引,所以会在a=5的索引上加Recork lock;而b是辅助索引,其上加的是Next-Key Lock,锁定的范围是(1,3),还有一点需要注意的是,InnoDB还会对辅助索引下一个健值加上gap lock,即还有一个辅助索引范围为(3,6)的锁。因此下面的语句都会被阻塞:
select * from z where a=5 lock in share mode; insert into z select 4,2; insert into z select 6,5;

分析:
因为a=5上已经加了行锁,所有第一条SQL会阻塞;
因为2,5都在(1,3)与(3,6)范围里,所以第二条与第三条同样会被阻塞。
在REPEATABLE READ下,InnoDB采用next-key locking机制来避免幻读问题。

    推荐阅读