【发布时间】:2020-01-31 16:36:14
【问题描述】:
我正在使用 MySQL InnoDB 表并试图了解在索引范围扫描的情况下某些行级锁定的原因。我发现根据所使用索引的唯一性,可能会锁定额外的索引记录(超出范围)。请参见下面的示例(在 8.0.18 版本中验证)。
CREATE TABLE foo (
a INT NOT NULL,
b INT NOT NULL,
c CHAR(1) NOT NULL,
PRIMARY KEY (a),
UNIQUE KEY (b)
) ENGINE=InnoDB;
INSERT INTO foo VALUES (1,1,'A'), (3,3,'B'), (5,5,'C'), (7,7,'D'), (9,9,'E');
测试用例 1
第 1 节:
START TRANSACTION;
SELECT * FROM foo WHERE a < 2 FOR UPDATE;
第 2 节:
DELETE FROM foo WHERE a = 3; -- Success
测试用例 2
这将使用表的原始行并返回已删除的记录。
第 1 节:
START TRANSACTION;
SELECT * FROM foo WHERE b < 2 FOR UPDATE;
第 2 节:
DELETE FROM foo WHERE b = 3; -- Blocks
在第二个测试用例中使用 b = 3 锁定二级索引记录看起来没有必要。
在二级索引的情况下,为什么 InnoDB 会阻止扫描范围右侧的下一个索引条目?这有什么实际原因吗? 如果 b = 3 的记录在第二个测试用例中没有被阻止,有人可以举一个可能发生的问题的例子吗?
【问题讨论】:
-
在 bugs.mysql.com 提交错误