首页 > 一个innodb next-key lock的问题

一个innodb next-key lock的问题

表结构:

CREATE TABLE `test_lock` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=60 DEFAULT CHARSET=utf8

隔离级别:REPEATABLE-READ
innodb_locks_unsafe_for_binlog:0

表内容:

+----+
| id |
+----+
| 12 |
| 39 |
| 59 |
+----+

session1:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test_lock where id <= 39 for update;
+----+
| id |
+----+
| 12 |
| 39 |
+----+
2 rows in set (0.00 sec)

session2:

mysql> insert into test_lock values(40);

问题:
1.id是主键,为什么session2还会等待session1的锁呢
2.就算有next-key lock,它不应该是锁住(39, 59]吗,为什么在session2中插入的值是70时还会等待呢。


我理解的答案是这样:
理论上如果是唯一索引,mysql会将next-key lock降级为record lock,但是如果正好某个查询导致整个索引都被锁定了(是不是可以理解为整个表都被锁定,所以相当于是表锁),mysql就不做任何处理,也就是不会降级处理,所以会发现插入任何数据或者修改任何数据都会被阻塞。
这只是我的猜想,还没有找到支持我这个观点的理论依据。


首先N锁是加在索引记录上的,而<=39会对39和59两条记录加N锁。
insert操作会先发起一个I锁(插入意向锁),这个I锁是要对59加的,根据精确兼容性,对已持有N锁的记录加I锁会冲突。

【热门文章】
【热门文章】