Mysql innodb锁定:在持有X时不应该授予IX,但确实如此

时间:2011-12-06 15:45:51

标签: mysql locking innodb

根据manual,IX表锁与X行锁冲突,因此在保持这样的锁时不能授予。引用

  

如果请求事务与现有锁兼容,则授予锁,但如果它与现有锁冲突,则不授予锁。

上表显示IX和X锁定冲突。但是,这不是我所经历的。使用mysql命令行工具,如果我执行以下

drop table if exists test; create table test (A int, B int, primary key (A,B), index (A)) TYPE = InnoDB;  insert into test values (1,1); start transaction; delete from test where a=1;

然后运行SHOW ENGINE INNODB状态,我得

------------
TRANSACTIONS
------------
Trx id counter 0 4604459
Purge done for trx's n:o < 0 4604457 undo n:o < 0 0
History list length 13
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0 4604434, not started, process no 2015, OS thread id 140642069153536
MySQL thread id 55, query id 1689 localhost esben
---TRANSACTION 0 4604256, not started, process no 2015, OS thread id 140642068752128
MySQL thread id 45, query id 1708 localhost root
SHOW ENGINE INNODB STATUS
---TRANSACTION 0 4604458, ACTIVE 15 sec, process no 2015, OS thread id 140642068952832
2 lock struct(s), heap size 368, 2 row lock(s), undo log entries 1
MySQL thread id 56, query id 1707 localhost esben
TABLE LOCK table "esben_mosegris-esben-trunk"."test" trx id 0 4604458 lock mode IX
RECORD LOCKS space id 7800 page no 3 n bits 72 index "PRIMARY" of table "esben_mosegris-esben-trunk"."test" trx id 0 4604458 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 32
 0: len 4; hex 80000001; asc     ;; 1: len 4; hex 80000001; asc     ;; 2: len 6; hex 00000046422a; asc    FB*;; 3: len 7; hex 00000000392350; asc     9#P;;

请注意,事务4604459在表中的一行上保持X锁定,因此另一个事务不可能在“test”表上进行IX锁定。但是,执行

start transaction; delete from test where a=2;

在另一个mysql命令行客户端直接通过,给出以下输出

------------
TRANSACTIONS
------------
Trx id counter 0 4604460
Purge done for trx's n:o < 0 4604457 undo n:o < 0 0
History list length 13
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0 4604256, not started, process no 2015, OS thread id 140642068752128
MySQL thread id 45, query id 1712 localhost root
SHOW ENGINE INNODB STATUS
---TRANSACTION 0 4604459, ACTIVE 18 sec, process no 2015, OS thread id 140642069153536
2 lock struct(s), heap size 368, 1 row lock(s)
MySQL thread id 55, query id 1710 localhost esben
TABLE LOCK table "esben_mosegris-esben-trunk"."test" trx id 0 4604459 lock mode IX
RECORD LOCKS space id 7800 page no 3 n bits 72 index "PRIMARY" of table "esben_mosegris-esben-trunk"."test" trx id 0 4604459 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

---TRANSACTION 0 4604458, ACTIVE 55 sec, process no 2015, OS thread id 140642068952832
2 lock struct(s), heap size 368, 2 row lock(s), undo log entries 1
MySQL thread id 56, query id 1707 localhost esben
TABLE LOCK table "esben_mosegris-esben-trunk"."test" trx id 0 4604458 lock mode IX
RECORD LOCKS space id 7800 page no 3 n bits 72 index "PRIMARY" of table "esben_mosegris-esben-trunk"."test" trx id 0 4604458 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
 0: len 8; hex 73757072656d756d; asc supremum;;

Record lock, heap no 2 PHYSICAL RECORD: n_fields 4; compact format; info bits 32
 0: len 4; hex 80000001; asc     ;; 1: len 4; hex 80000001; asc     ;; 2: len 6; hex 00000046422a; asc    FB*;; 3: len 7; hex 00000000392350; asc     9#P;;

我错过了什么?我的问题是因为这个位经过,我得到了一个死锁,因为两个事务现在都持有一个IX锁。或者可能是因为两者都试图抓住相同的范围锁定。我可以绕过这个,但我讨厌专门解决mysql奇怪问题的代码,特别是当我无法解释它时。

在第二个注释中,是否有某些地方解释了“记录锁定”中的所有字段?

1 个答案:

答案 0 :(得分:0)

我为此创建了一张票http://bugs.mysql.com/bug.php?id=63665。原因是锁仅在相同的粒度上冲突,因此ROW锁永远不会与上表中的TABLE锁冲突。在故障单中,我建议对手册进行一些改进,以使其更清晰。