>
MySQL版本:5.6
>存储引擎:InnoDB
>存储引擎:InnoDB
当两个任务尝试选择然后插入同一个表时发生死锁.程序如下:
Task_1 Task_2 ------ ------ Phase 1 | SELECT SELECT Phase 2 | INSERT INSERT SELECT count(id) from mytbl where name = 'someValue' and timestampdiff(hour,ts,now()) < 1; INSERT mytbl (id,name,ts) values ('newId','anotherValue',now());
死锁日志如下(一些细节被截断):
------------------------ LATEST DETECTED DEADLOCK ------------------------ 151225 8:22:17 *** (1) TRANSACTION: TRANSACTION 0 746402,ACTIVE 0 sec,process no 4690,OS thread id 140411390486272 inserting MysqL tables in use 1,locked 1 LOCK WAIT 1172 lock struct(s),heap size 112624,32914 row lock(s) MysqL thread id 3909,query id 31751474 10.20.36.38 mydb update INSERT INTO mytbl -- truncated *** (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 0 page no 5044 n bits 88 index `PRIMARY` of table `MYDB`.`mytbl` trx id 0 746402 lock_mode X insert intention waiting Record lock,heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 0: len 8; hex 73757072656d756d; asc supremum;; *** (2) TRANSACTION: TRANSACTION 0 746449,OS thread id 140411389953792 inserting,thread declared inside InnoDB 500 MysqL tables in use 1,locked 1 1172 lock struct(s),32914 row lock(s) MysqL thread id 3906,query id 31751477 10.20.36.38 mydb update INSERT INTO mytbl -- truncated *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 0 page no 5044 n bits 88 index `PRIMARY` of table `MYDB`.`MYTBL` trx id 0 746449 lock mode S Record lock,heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 0: len 8; hex 73757072656d756d; asc supremum;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 0 page no 5044 n bits 88 index `PRIMARY` of table `MYDB`.`MYTBL` trx id 0 746449 lock_mode X insert intention waiting Record lock,heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0 0: len 8; hex 73757072656d756d; asc supremum;; *** WE ROLL BACK TRANSACTION (2)
问题
>根据MysqL手册,简单的SELECT语句使用不需要S锁定的快照读取. INSERT语句需要插入单行上的X锁.那么为什么Task_2持有S锁并导致僵局?
编辑
SHOW CREATE TABLE的结果如下:
| task_content | CREATE TABLE `mytbl` ( `id` bigint(20) NOT NULL,`ts` timestamp NULL DEFAULT NULL,`name` varchar(32) DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 |