MySQL事务等待已经授予的锁,这导致死锁。

10

以下情况是否是Mysql中的一个bug?

Mysql版本:mysql.x86_64 5.0.77-4.el5_4.1

内核:Linux box2 2.6.18-128.el5 #1 SMP Wed Jan 21 10:41:14 EST 2009 x86_64 x86_64 x86_64 GNU/Linux

------------------------
LATEST DETECTED DEADLOCK
------------------------
100125  4:24:41
*** (1) TRANSACTION:
TRANSACTION 0 210510625, ACTIVE 155 sec, process no 28125, OS thread id 1243162944 starting index read
mysql tables in use 1, locked 1
LOCK WAIT 5 lock struct(s), heap size 1216, undo log entries 1
MySQL thread id 162928579, query id 527252744 box22 172.16.11.105 user updating
delete from user_grid_items where user_id = 669786974 and START_X = 45 and START_Y = 65
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 61372 n bits 328 index `PRIMARY` of table `gamesutra_beta/user_grid_items` trx id 0 210510625 lock_mode X locks rec but not gap waiting
Record lock, heap no 127 PHYSICAL RECORD: n_fields 10; compact format; info bits 0
0: len 8; hex 0000000027ec235e; asc     ' #^;; 1: len 4; hex 0000002d; asc    -;; 2: len 4; hex 00000041; asc    A;; 3: len 6; hex 00000b561243; asc    V C;; 4: len 7; hex 80000040070110; asc    @   ;; 5: len 23; hex 474949445f414e494d414c535f53515549445f50494e4b; asc GIID_ANIMALS_SQUID_PINK;; 6: len 4; hex cb59f060; asc  Y `;; 7: len 4; hex 4b59f060; asc KY `;; 8: len 4; hex 80000000; asc     ;; 9: len 1; hex 80; asc  ;;

*** (2) TRANSACTION:
TRANSACTION 0 210505911, ACTIVE 555 sec, process no 28125, OS thread id 1184323904 starting index read, thread declared inside InnoDB 500
mysql tables in use 1, locked 1
5 lock struct(s), heap size 1216, undo log entries 1
MySQL thread id 162924258, query id 527252762 box22 172.16.11.105 user updating
delete from user_grid_items where user_id = 669786974 and START_X = 45 and START_Y = 65
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 0 page no 61372 n bits 328 index `PRIMARY` of table `gamesutra_beta/user_grid_items` trx id 0 210505911 lock mode S locks rec but not gap
Record lock, heap no 127 PHYSICAL RECORD: n_fields 10; compact format; info bits 0
0: len 8; hex 0000000027ec235e; asc     ' #^;; 1: len 4; hex 0000002d; asc    -;; 2: len 4; hex 00000041; asc    A;; 3: len 6; hex 00000b561243; asc    V C;; 4: len 7; hex 80000040070110; asc    @   ;; 5: len 23; hex 474949445f414e494d414c535f53515549445f50494e4b; asc GIID_ANIMALS_SQUID_PINK;; 6: len 4; hex cb59f060; asc  Y `;; 7: len 4; hex 4b59f060; asc KY `;; 8: len 4; hex 80000000; asc     ;; 9: len 1; hex 80; asc  ;;

*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 0 page no 61372 n bits 328 index `PRIMARY` of table `gamesutra_beta/user_grid_items` trx id 0 210505911 lock_mode X locks rec but not gap waiting
Record lock, heap no 127 PHYSICAL RECORD: n_fields 10; compact format; info bits 0
0: len 8; hex 0000000027ec235e; asc     ' #^;; 1: len 4; hex 0000002d; asc    -;; 2: len 4; hex 00000041; asc    A;; 3: len 6; hex 00000b561243; asc    V C;; 4: len 7; hex 80000040070110; asc    @   ;; 5: len 23; hex 474949445f414e494d414c535f53515549445f50494e4b; asc GIID_ANIMALS_SQUID_PINK;; 6: len 4; hex cb59f060; asc  Y `;; 7: len 4; hex 4b59f060; asc KY `;; 8: len 4; hex 80000000; asc     ;; 9: len 1; hex 80; asc  ;;

*** WE ROLL BACK TRANSACTION (2)
------------

你能找到解决这个问题的方法吗? - John M
这里有类似的问题。你找到解决方案了吗? - Lee Chee Kiam
需要的两个锁是不同的(模式不同,已授予的锁是模式“S”共享/读取,正在等待模式“X”独占/写入锁)。请阅读http://dev.mysql.com/doc/refman/5.0/en/innodb-lock-modes.html 以了解详情。 - Zimbabao
4
那么,请对自己的问题发布答案并批准即可! - Tomas
3个回答

6
有时候,SHOW ENGINE INNODB STATUS 很难理解,因为它只显示事务中当前语句的信息。它不会显示在同一事务中先前发生的可能已经获得实际持有锁的语句。
在您的情况下,事务2中的先前语句在相关行上获取了共享锁。
然后,事务1试图在相同的行上获取排他锁,并且正在等待共享锁被删除。
接着,事务2在另一个语句中试图在相同的行上获取排他锁。典型的死锁现象。两个事务都无法完成。
避免这种死锁的一个解决方案是,在获取共享锁的语句之前,在事务2中使用 SELECT FOR UPDATE 语句获取该行的排他锁。

1

我以前读过一些东西,不确定它是否可能是你遇到的问题的原因,没有看到当前事务与其冲突的代码。

在处理事务时,你应该尽量让它们始终按照相同的顺序进行任何锁定... 对于订单/订单详细信息/付款系统,按照此示例中列出的顺序执行所有类似的活动。如果你有另一个进程尝试按照“订单详细信息/订单”的顺序进行事务处理,那么可能会导致死锁。

一个事务首先锁定订单号,然后处理订单详细信息。另一个事务首先锁定订单详细信息,然后尝试获取订单头。

希望对你有所帮助。


-4

使用SHOW ENGINE INNODB STATUS来确定最新死锁的原因。这可以帮助您调整应用程序以避免死锁。

如果交易由于死锁而失败,请随时准备重新发起该交易。死锁并不危险,只需再试一次即可。


2
这不是一个答案,而是对MySQL手册中14.2.7.9章节“如何处理死锁”(https://dev.mysql.com/doc/refman/5.0/en/innodb-deadlocks.html)的简单复述。更糟糕的是,它没有解决提问者的问题。如果我有downvote的权限,我会downvote它。 - dohpaz42

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接