乐趣区

关于mysql: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;

表有两列,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 机制来防止幻读问题。

退出移动版