MySQL中的死锁:engine.log分析

时间:2017-03-28 13:49:18

标签: mysql deadlock

如何理解死锁的原因 - 即如何找出哪些交易捕获了哪些锁?

我有 engine.log 文件,其中包含以下死锁:

------------------------
LATEST DETECTED DEADLOCK
------------------------
170327 11:09:53
*** (1) TRANSACTION:
TRANSACTION 4 2719072253, ACTIVE 5 sec, OS thread id 26215 starting index read
...
INSERT INTO... (the first transaction)

*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 36025889 n bits 96 index `PRIMARY` of table `mydb`.`mytable` trx id 4 2719072253 lock mode S locks rec but not gap waiting

...
*** (2) TRANSACTION:
TRANSACTION 4 2719072205, ACTIVE 35 sec, OS thread id 25564 starting index read, thread declared inside InnoDB 485

UPDATE ... (the second transaction)

*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 36025889 n bits 96 index `PRIMARY` of table `mydb`.`mytable` trx id 4 2719072205 lock_mode X locks rec but not gap
Record lock, heap no 27 PHYSICAL RECORD: n_fields 72; compact format; info bits 0
...

 *** (2) WAITING FOR THIS LOCK TO BE GRANTED:
 RECORD LOCKS space id 0 page no 42767646 n bits 120 index `PRIMARY` of table `mydb`.`mytable` trx id 4 2719072205 lock_mode X locks rec but not gap waiting

...

 *** WE ROLL BACK TRANSACTION (1)

我对日志中描述内容的看法如下:

1。交易№2最初有一个锁(并且日志中的锁的类型不明确):

  

***(2)HOLDS THE LOCK(S)

     

RECORD LOCKS space id 0 page no 36025889 n bits 96 index PRIMARY of   table mydb.mytable trx id 4 2719072205 lock_mode X锁定rec但不锁定   间隙

     

记录锁定,堆没有27物理记录:n_fields 72;紧凑格式;   信息位0

2。交易№1试图获得S型锁定:

  

***(1)等待获得此锁定:

     

RECORD LOCKS ... trx id 4 2719072253锁定模式S锁定rec而不是间隙   等待

并且在尝试失败后,它开始等待释放交易№2锁;

3. 然后交易№2试图获得X类型的锁定:

  

***(2)等待获得此锁定:

     

RECORD LOCKS ... trx id 4 2719072205 lock_mode X锁定rec但不锁定间隙   等待

并且在尝试失败后,它开始等待,直到事务№1获得S锁并释放它。

我是否正确理解日志,或者我的解释是错误的?

1 个答案:

答案 0 :(得分:3)

您的解释几乎是正确的。一些想法补充:

  • 在innodb中有two basic types of locks:共享(S)和独占(X)。如果事务在记录上持有X锁,则在事务完成之前,不能在相同记录上授予S或X锁。如果事务在记录上持有S锁,则可以立即授予另一个S锁,但X锁请求必须等到第一个事务完成。

  • 第二个事务是update,它对正在更新的索引记录保持独占(X)锁定。因此,第一个事务无法在相同记录上获得S锁定。但是,第二个事务正在等待在另一组记录上授予X锁定(page no与其他锁定不同)。

  • 摘录并未告诉我们哪个事务锁定了第二个事务正在等待的记录。我们只能假设这是第一笔交易 - 否则就不会陷入僵局。