【发布时间】:2010-03-10 19:01:26
【问题描述】:
我在 MySQL InnoDB 引擎中发现了这种有趣的问题,谁能解释为什么引擎总是声称它是死锁。
首先,我创建了一个单行单列的表:
CREATE TABLE `SeqNum` (`current_seq_num` bigint(30) NOT NULL default '0',
PRIMARY KEY (`current_seq_num`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
Query OK, 0 rows affected (0.03 sec)
mysql> insert into SeqNum values (5);
Query OK, 1 row affected (0.00 sec)
现在,我有两个 MySQL 连接器线程,在 thread1:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select `current_seq_num` into @curr_seq FROM SeqNum FOR UPDATE;
Query OK, 1 row affected (0.00 sec)
现在,在 thread2 中,我做了完全相同的事情:
mysql> begin;
Query OK, 0 rows affected (0.00 sec)
mysql> select `current_seq_num` into @curr_seq FROM SeqNum FOR UPDATE;
在默认的innodb_lock_wait_timeout之前,thread2只是等待thread1释放对表的排他锁,这是正常的。
但是,在thread1中,如果我输入以下更新查询:
mysql> update SeqNum set `current_seq_num` = 8;
ERROR 1213 (40001): Deadlock found when trying to get lock;
try restarting transaction
现在,thread2 完成了 select 查询,因为 thread1 退出了。
另外,在thread1中,如果我输入带有where子句的更新查询,可以很好的执行:
mysql> update SeqNum set `current_seq_num` = 8 where `current_seq_num` =5
Query OK, 1 row affected (0.00 sec)
谁能解释一下?
【问题讨论】:
-
我认为区别在于死锁和疑似死锁。只是猜测,因为他们使用相同的锁,并且需要一段时间,这是一个死锁的情况。
-
我无法复制您的事件序列(我相信我昨天可以)。现在,从线程 1 执行的任何更新都没有出现死锁。请您用整个序列(包括插入 SeqNum)以及有关版本和隔离模式的信息来更新问题?
-
Martin:我用详细的序列事件更新了问题。我只是再次尝试以确保它始终相同。
-
WilliamLou:我完全按照你的顺序,但我没有陷入僵局。也许您正在运行一个有错误的版本。你在运行哪个版本?我已经尝试过 5.1.44-community (Windows) 和 5.1.37-1ubuntu5.1。