1

我无法解释 MySql(5.7,InnoDB)的这个死锁输出。我知道死锁最终将通过更改应用程序级代码来解决,而您无法从这个代码段中找到根本原因。但是,希望有人能够告诉我为什么我对这个 MySql 诊断的解释是不正确的。

------------------------
LATEST DETECTED DEADLOCK
------------------------
2018-04-09 19:41:39 0x2b7323ef1700
*** (1) TRANSACTION:
TRANSACTION 33312589, ACTIVE 16 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 150744, OS thread handle 47781157312256, query id 53141856 ec2-34-250-106-67.eu-west-1.compute.amazonaws.com 34.250.106.67 sc_appuser3 statistics
/* requestId: 11e8-3c2d-fb145a10-b404-0242ac110003 */ SELECT locator FROM policy WHERE locator = 'df0d7ef5-2e14-4664-90b2-2bfb3f35cce2' AND tenant_locator = '8df5d824-6de9-4e21-8135-b19303aec800' FOR UPDATE
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 464385 page no 21 n bits 232 index policy_locator_idx of table `main_1523299445`.`policy` trx id 33312589 lock_mode X locks rec but not gap waiting
Record lock, heap no 41 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 30; hex 64663064376566352d326531342d343636342d393062322d326266623366; asc df0d7ef5-2e14-4664-90b2-2bfb3f; (total 36 bytes);
 1: len 30; hex 38646635643832342d366465392d346532312d383133352d623139333033; asc 8df5d824-6de9-4e21-8135-b19303; (total 36 bytes);
 2: len 8; hex 000000000000004e; asc N;;

*** (2) TRANSACTION:
TRANSACTION 33312511, ACTIVE 31 sec starting index read
mysql tables in use 2, locked 2
37 lock struct(s), heap size 3520, 21 row lock(s), undo log entries 10
MySQL thread id 150683, OS thread handle 47773524104960, query id 53142921 ec2-34-250-106-67.eu-west-1.compute.amazonaws.com 34.250.106.67 sc_appuser3 Sending data
/* requestId: 11e8-3c2d-cc07ac92-93f6-0242ac110002 */ UPDATE invoice_schedule iss JOIN policy p on iss.policy_id = p.id SET iss.deleted = TRUE WHERE iss.deleted = FALSE AND iss.scheduled_invoice_locator IS NULL AND (null IS NULL OR iss.start_timestamp >= null) AND p.locator = 'df0d7ef5-2e14-4664-90b2-2bfb3f35cce2' AND iss.tenant_locator = '8df5d824-6de9-4e21-8135-b19303aec800'
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 464385 page no 21 n bits 232 index policy_locator_idx of table `main_1523299445`.`policy` trx id 33312511 lock_mode X locks rec but not gap
Record lock, heap no 41 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 30; hex 64663064376566352d326531342d343636342d393062322d326266623366; asc df0d7ef5-2e14-4664-90b2-2bfb3f; (total 36 bytes);
 1: len 30; hex 38646635643832342d366465392d346532312d383133352d623139333033; asc 8df5d824-6de9-4e21-8135-b19303; (total 36 bytes);
 2: len 8; hex 000000000000004e; asc N;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 464385 page no 21 n bits 232 index policy_locator_idx of table `main_1523299445`.`policy` trx id 33312511 lock mode S waiting
Record lock, heap no 41 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 30; hex 64663064376566352d326531342d343636342d393062322d326266623366; asc df0d7ef5-2e14-4664-90b2-2bfb3f; (total 36 bytes);
 1: len 30; hex 38646635643832342d366465392d346532312d383133352d623139333033; asc 8df5d824-6de9-4e21-8135-b19303; (total 36 bytes);
 2: len 8; hex 000000000000004e; asc N;;

*** WE ROLL BACK TRANSACTION (1)

对我来说,看起来我们有两个交易涉及这个死锁。事务 2 持有这个锁,而事务 1 等待它:

RECORD LOCKS space id 464385 page no 21 n bits 232 index policy_locator_idx of table `main_1523299445`.`policy` trx id 33312589 lock_mode X locks rec but not gap waiting
Record lock, heap no 41 PHYSICAL RECORD: n_fields 3; compact format; info bits 0
 0: len 30; hex 64663064376566352d326531342d343636342d393062322d326266623366; asc df0d7ef5-2e14-4664-90b2-2bfb3f; (total 36 bytes);
 1: len 30; hex 38646635643832342d366465392d346532312d383133352d623139333033; asc 8df5d824-6de9-4e21-8135-b19303; (total 36 bytes);
 2: len 8; hex 000000000000004e; asc N;;

现在,这是我不明白的部分。事务 2 似乎也在S(共享)模式下等待同一个锁。但是,事务 2 已经在X模式下获得了锁,所以我不明白为什么它需要等待才能获得锁。

  1. 我对这个诊断输出的解释一定有问题。谁能指出这里实际发生了什么?
  2. MySql 是否有任何其他诊断信息可以帮助我了解这里发生了什么?
4

1 回答 1

1

我认为问题是如果另一个事务正在等待对该锁的独占授权,MySql 无法授予共享记录锁,即使同一个事务已经对该锁具有独占授权。

我还没有找到任何直接支持 MySql 的文档,但我想不出任何其他可能导致这种情况的文档。

于 2018-04-13T22:37:30.460 回答