MySql:一个表死锁?

MySql:一个表死锁?,mysql,database-deadlocks,Mysql,Database Deadlocks,我正在windows和PHP上使用最新的MySQL版本5.7.21 我有两个线程在做类似simplified的事情,我尝试将其分解以进行测试和演示: Thread 1: while(true) { START TRANSACTION; SELECT id FROM t FOR UPDATE; UPDATE t SET ...=...; COMMIT; } Thread 2: while(true) { START TRANSACTION; SELECT id F

我正在windows和PHP上使用最新的MySQL版本5.7.21

我有两个线程在做类似simplified的事情,我尝试将其分解以进行测试和演示:

Thread 1:
while(true)
{  START TRANSACTION;
   SELECT id FROM t FOR UPDATE;
   UPDATE t SET ...=...;
   COMMIT;
}

Thread 2:
while(true)
{   START TRANSACTION;
    SELECT id FROM t WHERE id IN (...) FOR UPDATE;
    UPDATE t SET ...=... WHERE id IN (...);
    COMMIT;
}
我的问题:大约10-20轮后,我得到:

Deadlock found when trying to get lock; try restarting transaction 
in SELECT id FROM t WHERE id IN(...)
我不知道为什么这是一个僵局。有什么想法吗

奇怪的是,每次提交后执行Sleep1时,它都会起作用

增加:

show engine innodb status;

------------------------
LATEST DETECTED DEADLOCK
------------------------
2018-04-08 16:50:30 0x15d0
*** (1) TRANSACTION:
TRANSACTION 162475673, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 121, OS thread handle 1592, query id 91399 localhost 127.0.0.1 root statistics
SELECT id FROM t WHERE t.id IN('1') FOR UPDATE
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 40153 page no 17 n bits 104 index PRIMARY of table `db`.`t` trx id 162475673 lock_mode X locks rec but not gap waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 49; compact format; info bits 0
 0: len 4; hex 00000001; asc     ;;
 1: len 6; hex 000009af2e7d; asc     .};;
 2: len 7; hex 5600010b002a9a; asc V    * ;;
 3: len 30; hex 4d4848484848484848484848484848484848484848484848484848484848; asc MHHHHHHHHHHHHHHHHHHHHHHHHHHHHH; (total 255 bytes);
 4: len 0; hex ; asc ;;
 5: SQL NULL;
 6: SQL NULL;
 7: len 0; hex ; asc ;;
 8: len 0; hex ; asc ;;
 9: len 0; hex ; asc ;;
 10: len 0; hex ; asc ;;
 11: len 0; hex ; asc ;;
 12: len 0; hex ; asc ;;
 13: SQL NULL;
 14: SQL NULL;
 15: SQL NULL;
 16: SQL NULL;
 17: SQL NULL;
 18: SQL NULL;
 19: SQL NULL;
 20: len 1; hex 81; asc  ;;
 21: len 3; hex 800100; asc    ;;
 22: len 2; hex 8000; asc   ;;
 23: len 0; hex ; asc ;;
 24: len 1; hex 30; asc 0;;
 25: len 0; hex ; asc ;;
 26: len 1; hex 81; asc  ;;
 27: SQL NULL;
 28: len 1; hex 80; asc  ;;
 29: len 0; hex ; asc ;;
 30: len 1; hex 01; asc  ;;
 31: len 4; hex 80000000; asc     ;;
 32: len 4; hex 80000000; asc     ;;
 33: len 4; hex 80000000; asc     ;;
 34: len 4; hex 80000000; asc     ;;
 35: len 4; hex 80000000; asc     ;;
 36: SQL NULL;
 37: SQL NULL;
 38: len 1; hex 80; asc  ;;
 39: len 1; hex 80; asc  ;;
 40: len 1; hex 80; asc  ;;
 41: SQL NULL;
 42: len 0; hex ; asc ;;
 43: len 4; hex 80000000; asc     ;;
 44: len 4; hex 00000001; asc     ;;
 45: len 0; hex ; asc ;;
 46: len 4; hex 00000001; asc     ;;
 47: len 0; hex ; asc ;;
 48: len 0; hex ; asc ;;

*** (2) TRANSACTION:
TRANSACTION 162475666, ACTIVE 0 sec starting index read, thread declared inside InnoDB 5000
mysql tables in use 1, locked 1
1823 lock struct(s), heap size 172240, 33299 row lock(s)
MySQL thread id 120, OS thread handle 5584, query id 91402 localhost 127.0.0.1 root updating
UPDATE t SET number=CONCAT(number, 'H')
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 40153 page no 17 n bits 104 index PRIMARY of table `db`.`t` trx id 162475666 lock_mode X locks rec but not gap
Record lock, heap no 2 PHYSICAL RECORD: n_fields 49; compact format; info bits 0
 0: len 4; hex 00000001; asc     ;;
 1: len 6; hex 000009af2e7d; asc     .};;
 2: len 7; hex 5600010b002a9a; asc V    * ;;
 3: len 30; hex 4d4848484848484848484848484848484848484848484848484848484848; asc MHHHHHHHHHHHHHHHHHHHHHHHHHHHHH; (total 255 bytes);
 4: len 0; hex ; asc ;;
 5: SQL NULL;
 6: SQL NULL;
 7: len 0; hex ; asc ;;
 8: len 0; hex ; asc ;;
 9: len 0; hex ; asc ;;
 10: len 0; hex ; asc ;;
 11: len 0; hex ; asc ;;
 12: len 0; hex ; asc ;;
 13: SQL NULL;
 14: SQL NULL;
 15: SQL NULL;
 16: SQL NULL;
 17: SQL NULL;
 18: SQL NULL;
 19: SQL NULL;
 20: len 1; hex 81; asc  ;;
 21: len 3; hex 800100; asc    ;;
 22: len 2; hex 8000; asc   ;;
 23: len 0; hex ; asc ;;
 24: len 1; hex 30; asc 0;;
 25: len 0; hex ; asc ;;
 26: len 1; hex 81; asc  ;;
 27: SQL NULL;
 28: len 1; hex 80; asc  ;;
 29: len 0; hex ; asc ;;
 30: len 1; hex 01; asc  ;;
 31: len 4; hex 80000000; asc     ;;
 32: len 4; hex 80000000; asc     ;;
 33: len 4; hex 80000000; asc     ;;
 34: len 4; hex 80000000; asc     ;;
 35: len 4; hex 80000000; asc     ;;
 36: SQL NULL;
 37: SQL NULL;
 38: len 1; hex 80; asc  ;;
 39: len 1; hex 80; asc  ;;
 40: len 1; hex 80; asc  ;;
 41: SQL NULL;
 42: len 0; hex ; asc ;;
 43: len 4; hex 80000000; asc     ;;
 44: len 4; hex 00000001; asc     ;;
 45: len 0; hex ; asc ;;
 46: len 4; hex 00000001; asc     ;;
 47: len 0; hex ; asc ;;
 48: len 0; hex ; asc ;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 40153 page no 17 n bits 104 index PRIMARY of table `db`.`t` trx id 162475666 lock_mode X waiting
Record lock, heap no 2 PHYSICAL RECORD: n_fields 49; compact format; info bits 0
 0: len 4; hex 00000001; asc     ;;
 1: len 6; hex 000009af2e7d; asc     .};;
 2: len 7; hex 5600010b002a9a; asc V    * ;;
 3: len 30; hex 4d4848484848484848484848484848484848484848484848484848484848; asc MHHHHHHHHHHHHHHHHHHHHHHHHHHHHH; (total 255 bytes);
 4: len 0; hex ; asc ;;
 5: SQL NULL;
 6: SQL NULL;
 7: len 0; hex ; asc ;;
 8: len 0; hex ; asc ;;
 9: len 0; hex ; asc ;;
 10: len 0; hex ; asc ;;
 11: len 0; hex ; asc ;;
 12: len 0; hex ; asc ;;
 13: SQL NULL;
 14: SQL NULL;
 15: SQL NULL;
 16: SQL NULL;
 17: SQL NULL;
 18: SQL NULL;
 19: SQL NULL;
 20: len 1; hex 81; asc  ;;
 21: len 3; hex 800100; asc    ;;
 22: len 2; hex 8000; asc   ;;
 23: len 0; hex ; asc ;;
 24: len 1; hex 30; asc 0;;
 25: len 0; hex ; asc ;;
 26: len 1; hex 81; asc  ;;
 27: SQL NULL;
 28: len 1; hex 80; asc  ;;
 29: len 0; hex ; asc ;;
 30: len 1; hex 01; asc  ;;
 31: len 4; hex 80000000; asc     ;;
 32: len 4; hex 80000000; asc     ;;
 33: len 4; hex 80000000; asc     ;;
 34: len 4; hex 80000000; asc     ;;
 35: len 4; hex 80000000; asc     ;;
 36: SQL NULL;
 37: SQL NULL;
 38: len 1; hex 80; asc  ;;
 39: len 1; hex 80; asc  ;;
 40: len 1; hex 80; asc  ;;
 41: SQL NULL;
 42: len 0; hex ; asc ;;
 43: len 4; hex 80000000; asc     ;;
 44: len 4; hex 00000001; asc     ;;
 45: len 0; hex ; asc ;;
 46: len 4; hex 00000001; asc     ;;
 47: len 0; hex ; asc ;;
 48: len 0; hex ; asc ;;

*** WE ROLL BACK TRANSACTION (1)
------------
TRANSACTIONS
------------
Trx id counter 162475684
Purge done for trx's n:o < 162475683 undo n:o < 0 state: running but idle
History list length 28
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 281475162769200, not started
0 lock struct(s), heap size 1136, 0 row lock(s)

死锁不是错误。死锁是一种正常的操作。向我们显示显示引擎innodb状态的结果;就在僵局之后。MySQL可能会对中的WHERE id使用一个间隙锁…谢谢你的回复。我添加了innodb状态。我知道这不是一个错误,只是想了解为什么会发生这种情况,也许可以消除它-总是比重新启动事务更快。仍然不确定为什么会出现死锁。唯一有效的方法是将GET_LOCK和RELEASE_LOCK作为循环中的第一个/最后一个命令。但我认为这正是事务应该看到的。它是有效的,当从t中选择id时,id在。。。更新;在具有所有ID的第一个线程中。但只需从t中选择id,其中id用于更新;不。奇怪的