【发布时间】:2011-06-18 16:19:59
【问题描述】:
对于同时具有主键和单独唯一索引的表上的事务,我遇到了 innodb 锁定问题。似乎如果 TX 使用唯一键删除记录,然后重新插入相同的记录,这将导致下一个键锁定而不是预期的记录锁定(因为键是唯一的)。请参阅下面的测试用例以及我希望拥有哪些锁的记录的细分:
DROP TABLE IF EXISTS foo;
CREATE TABLE `foo` (
`i` INT(11) NOT NULL,
`j` INT(11) DEFAULT NULL,
PRIMARY KEY (`i`),
UNIQUE KEY `jk` (`j`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
INSERT INTO foo VALUES (5,5), (8,8), (11,11);
(注意:只需在 TX1 sql 之后运行 TX2 sql,在单独的连接中)
TX1
START TRANSACTION;
DELETE FROM foo WHERE i=8;
导致 i=8 上的排他锁(没有间隙锁,因为 i 是主键且唯一)
INSERT INTO foo VALUES(8,8);
导致 i=8 和 j= 8 的排他锁,以及 i=6 和 i=7 以及 j=6 和 j=7 的共享意图锁
TX2
START TRANSACTION;
INSERT INTO foo VALUES(7,7);
导致 i=7 和 j=7 的排他锁,以及 i=6 和 j=6 上的共享意向锁
我希望 TX2 不会被 TX1 阻止,但事实确实如此。奇怪的是,阻塞似乎与 TX1 的插入有关。我这样说是因为如果 TX1 的插入语句在删除之后没有运行,则 TX2 的插入不会被阻塞。就好像 TX1 重新插入 (8,8) 会导致索引 j 上的下一个键锁定 (6,8]。
任何见解将不胜感激。
【问题讨论】:
标签: mysql database performance locking innodb