MySQL 版本为 5.6.42 。有如下表:
CREATE TABLE tab(
`id` INT PRIMARY KEY AUTO_INCREMENT,
`a` INT,
KEY `a`(`a`)
);
INSERT INTO `tt` (`id`, `a`)
VALUES
(1, 1),
(2, 4),
(3, 7),
(4, 10),
(5, 11);
SESSION 1:
START TRANSACTION;
SELECT * FROM tab WHERE a=7 FOR UPDATE;
SESSION 2:
INSERT INTO tab(a) VALUES(4); // blocking
INSERT INTO tab(a) VALUES(5); // blocking
INSERT INTO tab(a) VALUES(6); // blocking
INSERT INTO tab(a) VALUES(7); // blocking
INSERT INTO tab(a) VALUES(8); // blocking
INSERT INTO tab(a) VALUES(9); // blocking
INSERT INTO tab(a) VALUES(10); // success
我大概知道这里用到了 next-key lock,但是我从官方了解到的是 next-key lock 是 gap lock 加上 record lock,而 gap lock 定义的范围是索引前的间隙,在这里即 (4,7) 这个区间。
问题:为啥 INSERT INTO tab(a) VALUES(8); 这里的 8>7 在 (4,7) 区间之外也 block 了
参考 MySQL 官方文档:https://dev.mysql.com/doc/refman/5.6/en/innodb-locking.html#innodb-next-key-locks
其中有一段关于 next-key lock
的描述:
A next-key lock on an index record also affects the “ gap ” before that index record. That is, a next-key lock is an index-record lock plus a gap lock on the gap preceding the index record.
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.