I have faced a deadlock in my application between an Update and an Insert query and I am unable to understand why locks are given in a way which causes deadlock.
Environment-
Queries- Following two queries (Queries truncated to show only relevant columns)-
Update-
UPDATE `MSC` SET `m_id` = 110, `s_id` = 1234, `c_id` = '9b39cd', WHERE `MSC`.`id` = 54362
Insert-
INSERT INTO `MSC` (`m_id`, `s_id`, `c_id`) VALUES (110, 1235, '9b39cd')
Deadlock-
SHOW ENGINE INNODB STATUS\G;
shows that insert query initiated earlier.------------------------ LATEST DETECTED DEADLOCK ------------------------ 2017-03-17 15:41:03 0x7f8039550700 * (1) TRANSACTION: TRANSACTION 7784084, ACTIVE 2 sec inserting mysql tables in use 1, locked 1 LOCK WAIT 11 lock struct(s), heap size 1136, 46 row lock(s), undo log entries 25 MySQL thread id 493648, OS thread handle 140188693010176, query id 55263589 ip-10-198-7-203.ec2.internal 10.198.7.203 root update INSERT INTOMSC
(m_id
,s_id
,c_id
) VALUES (110, 1235, '9b39cd') * (1) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 1377 page no 10 n bits 152 index PRIMARY of table "db"."M" trx id 7784084 lock mode S locks rec but not gap waiting Record lock, heap no 67 PHYSICAL RECORD: n_fields 42; compact format; info bits 0 0: len 4; hex 800000ac; asc ;; 1: len 6; hex 00000076c69f; asc v ;; 2: len 7; hex 76000001cb24c5; asc v $ ;; 3: len 8; hex 999be72e2e07032e; asc .. .;; 4: len 8; hex 999c22fa43025221; asc " C R!;;*** (2) TRANSACTION: TRANSACTION 7784095, ACTIVE 0 sec starting index read mysql tables in use 1, locked 1 6 lock struct(s), heap size 1136, 3 row lock(s), undo log entries 2 MySQL thread id 493645, OS thread handle 140188694415104, query id 55263635 ip-10-198-3-73.ec2.internal 10.198.3.73 root updating UPDATE `MSC` SET `m_id` = 110, `s_id` = 1234, `c_id` = '9b39cd', WHERE `MSC`.`id` = 54362 *** (2) HOLDS THE LOCK(S): RECORD LOCKS space id 1377 page no 10 n bits 152 index PRIMARY of table "db"."M" trx id 7784095 lock_mode X locks rec but not gap Record lock, heap no 67 PHYSICAL RECORD: n_fields 42; compact format; info bits 0 0: len 4; hex 800000ac; asc ;; 1: len 6; hex 00000076c69f; asc v ;; 2: len 7; hex 76000001cb24c5; asc v $ ;; 3: len 8; hex 999be72e2e07032e; asc .. .;; 4: len 8; hex 999c22fa43025221; asc " C R!;; *** (2) WAITING FOR THIS LOCK TO BE GRANTED: RECORD LOCKS space id 1410 page no 261 n bits 104 index PRIMARY of table "db"."MSC" trx id 7784095 lock_mode X locks rec but not gap waiting Record lock, heap no 16 PHYSICAL RECORD: n_fields 16; compact format; info bits 0 0: len 4; hex 800038e2; asc 8 ;; 1: len 6; hex 00000076c694; asc v ;; 2: len 7; hex 6f0000055b2a0e; asc o [* ;; 3: len 8; hex 999c22fa0d08a51c; asc " ;; 4: len 8; hex 999c22fa3b0dffd8; asc " ; ;; *** WE ROLL BACK TRANSACTION (2)
Questions- I am unable to understand the followings- 1. Why did the update query have to wait and couldn't get the locks when insert query got one? 2. Why does the update query needs/takes exclusive(X) lock on M table.
Please share your thoughts here. Let me know if any extra info is required.
Usually Insert and Delete operations involve single relations. So they may not cause deadlock.
In SQL, i think inserting would be faster for the simple reason that while inserting you don't have to look up for anything, however for updating , first of all you would have to find the tuple of the data and then perform the update operation. Hence insert is better than update.
Deadlock frequency can sometimes be reduced by ensuring that all applications access their common data in the same order - meaning, for example, that they access (and therefore lock) rows in Table A, followed by Table B, followed by Table C, and so on.
Does the id value of 110 exist in the M table? Also it may be useful to wrap these individual transactions in START TRANSACTION;
and COMMIT;
commands to ensure the insert completes before the update tries to run.
Example:
START TRANSACTION;
INSERT INTO `MSC` (`m_id`, `s_id`, `c_id`) VALUES (110, 1235, '9b39cd')
COMMIT;
START TRANSACTION;
UPDATE `MSC` SET `m_id` = 110, `s_id` = 1234, `c_id` = '9b39cd', WHERE
`MSC`.`id` = 54362
COMMIT;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With