Mysql transaction waiting for lock which is already granted .. This is causing deadlock
If following situation a bug in mysql?.
Mysql Version: mysql.x86_64 5.0.77-4.el5_4.1
Kernel: 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)
------------
Sometimes the SHOW ENGINE INNODB STATUS can be hard to decipher because it only shows the current statement in the transaction. It does not show statements that occurred previously in the same transaction that may have acquired the locks that are actually being held.
In your case, a previous statement in transaction 2 acquired a shared lock on the row in question.
Then, transaction 1 attempted to acquire an exclusive lock on the same row, and is happily waiting for the shared lock to be removed.
Then, transaction 2, in another statement, attempted to acquire an exclusive lock on the same row. Classic deadlock. Neither transaction can finish.
One solution to help avoid such a deadlock would be to grab an exclusive lock on the row in transaction 2 with a SELECT FOR UPDATE
statement, prior to the statement that's acquiring the shared lock.
I read something long ago, and not sure if it MIGHT be what you are running into as a result or not... without seeing code of the transaction of the current vs what it is conflicting with.
When processing your transactions, you should try to have them always do any locking in the same sequence... For an order / order detail / payments system, do the activities in the order listed as example here for all similar. If you have another process that tries its transaction in order of "Order detail / order", that CAN cause a deadlock.
One transaction is locking the order # first, then working the order detail. The other transaction locking the order detail first, then trying to get the order header.
HTH
Use SHOW ENGINE INNODB STATUS to determine the cause of the latest deadlock. That can help you to tune your application to avoid deadlocks.
Always be prepared to re-issue a transaction if it fails due to deadlock. Deadlocks are not dangerous. Just try again.
精彩评论