为什么MySQL中会出现这种死锁?

为什么MySQL中会出现这种死锁?,mysql,database,deadlock,Mysql,Database,Deadlock,我使用JMeter测试我的程序,不知怎么的,总响应数停止增加,然后我发现MySQL中存在死锁。我不明白下面的日志是什么意思。似乎transaction2拥有一个S锁,并试图拥有同一个表的X锁。这会导致僵局吗?如果是,为什么会发生这种情况 ATEST DETECTED DEADLOCK ------------------------ 2019-01-02 14:38:27 0x70000f30a000 *** (1) TRANSACTION: TRANSACTION 24004, ACTIVE

我使用JMeter测试我的程序,不知怎么的,总响应数停止增加,然后我发现MySQL中存在死锁。我不明白下面的日志是什么意思。似乎transaction2拥有一个S锁,并试图拥有同一个表的X锁。这会导致僵局吗?如果是,为什么会发生这种情况

ATEST DETECTED DEADLOCK
------------------------
2019-01-02 14:38:27 0x70000f30a000
*** (1) TRANSACTION:
TRANSACTION 24004, ACTIVE 0 sec inserting
mysql tables in use 2, locked 2
LOCK WAIT 5 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 2
MySQL thread id 11953, OS thread handle 123145549275136, query id 418447 localhost 127.0.0.1 username executing
INSERT INTO MRBS_SCHEDULE (ID,START_TIME,END_TIME,ROOM_ID,CREATE_BY,PRESIDE,REPEAT_ID,DESCRIPTION,NUM,TITLE,PRESIDE_EMAIL,PROJECTOR,CONFERENCE_CALL,CREATE_ID,BOOK_TIME,END_TYPE,EXPECTED_END_TIME) select null,'2019-01-03 19:53:00','2019-01-03 19:53:00',10113558,'d','d',12245755,'fdsfds',10,null,'d@sh.ff.com',0,0,10227622,'2019-01-02 14:38:27.358',0,'2019-01-03 19:53:00' from dual WHERE NOT EXISTS (SELECT * FROM MRBS_SCHEDULE ms where ms.START_TIME<'2019-01-03 19:53:00' and ms.END_TIME>'2019-01-03 19:53:00' and ms.ROOM_ID=10113558)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 55 page no 228 n bits 872 index IND_MRBS_SCHEDULE_END_TIME of table `meeting`.`mrbs_schedule` trx id 24004 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 24005, ACTIVE 0 sec inserting
mysql tables in use 2, locked 2
5 lock struct(s), heap size 1136, 2 row lock(s), undo log entries 2
MySQL thread id 11940, OS thread handle 123145557155840, query id 418448 localhost 127.0.0.1 username executing
INSERT INTO MRBS_SCHEDULE (ID,START_TIME,END_TIME,ROOM_ID,CREATE_BY,PRESIDE,REPEAT_ID,DESCRIPTION,NUM,TITLE,PRESIDE_EMAIL,PROJECTOR,CONFERENCE_CALL,CREATE_ID,BOOK_TIME,END_TYPE,EXPECTED_END_TIME) select null,'2019-01-03 19:54:00','2019-01-03 19:54:00',10113685,'z','z',12245756,'fdsfds',10,null,'z@sz.ff.com',0,0,10227544,'2019-01-02 14:38:27.397',0,'2019-01-03 19:54:00' from dual WHERE NOT EXISTS (SELECT * FROM MRBS_SCHEDULE ms where ms.START_TIME<'2019-01-03 19:54:00' and ms.END_TIME>'2019-01-03 19:54:00' and ms.ROOM_ID=10113685)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 55 page no 228 n bits 872 index IND_MRBS_SCHEDULE_END_TIME of table `meeting`.`mrbs_schedule` trx id 24005 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 55 page no 228 n bits 872 index IND_MRBS_SCHEDULE_END_TIME of table `meeting`.`mrbs_schedule` trx id 24005 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)

编辑:表MRBS_SCHEDULE主键使用自动增量

死锁可以随时发生,这是正常行为。当事务1尝试使用表A更新表B,但同时事务2尝试使用表B更新表A时,会发生这种情况

基本上,事务保持着它们自己的状态,因为没有人愿意放弃,所以出现了死锁

您可以使用innodb\u lock\u wait\u timeout为数据库设置死锁阈值

根据文件

默认情况下启用死锁检测时,InnoDB会自动检测事务死锁并回滚一个或多个事务以打破死锁。InnoDB尝试选择要回滚的小型事务,其中事务的大小由插入、更新或删除的行数决定

如果InnoDB_table_locks=1为默认值,autocommit=0,则InnoDB知道表锁,并且它上面的MySQL层知道行级锁。否则,InnoDB无法检测死锁,其中涉及MySQL lock TABLES语句设置的表锁或InnoDB以外的存储引擎设置的锁。通过设置innodb_lock_wait_timeout系统变量的值来解决这些情况

参考: