Hi,
I'm using the following tables:
CREATE TABLE `ASSIGNMENTS` (
`ASSIGNMENTS_ID` char(36) NOT NULL,
`REQUEST_ID` varchar(40) NOT NULL,
`ARCHIVE_ID` decimal(22,0) NOT NULL,
`PLANNING_DATE` datetime NOT NULL,
`IS_ACTIVE` char(1) DEFAULT NULL,
`ORDER_ID` varchar(256) DEFAULT NULL,
PRIMARY KEY (`ASSIGNMENTS_ID`),
KEY `REQUEST_ID_IDX` (`REQUEST_ID`),
KEY `ORDER_ID_IDX` (`ORDER_ID`),
KEY `ARCHIVE_IDX` (`ARCHIVE_ID`),
KEY `PLANNING_DATE_IDX` (`PLANNING_DATE`),
KEY `IS_ACTIVE_IDX` (`IS_ACTIVE`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
CREATE TABLE `RESULTS` (
`RESULTS_ID` char(36) NOT NULL,
`REQUEST_ID` varchar(40) NOT NULL,
`ARCHIVE_ID` decimal(22,0) NOT NULL,
`PLANNING_DATE` datetime NOT NULL,
`IS_ACTIVE` char(1) DEFAULT NULL,
PRIMARY KEY (`RESULTS_ID`),
KEY `REQUEST_ID_IDX` (`REQUEST_ID`),
KEY `ARCHIVE_ID_IDX` (`ARCHIVE_ID`),
KEY `PLANNING_DATE_IDX` (`PLANNING_DATE`),
KEY `IS_ACTIVE_IDX` (`IS_ACTIVE`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
ASSIGNMENTS_ID and RESULTS_ID are generated by the application (using Hibernate's uuid2 generator).
I encounter a deadlock quite often and the result of SHOW ENGINE INNODB STATUS is:
LATEST DETECTED DEADLOCK
------------------------
2014-03-31 19:36:51 2baadfe10700
*** (1) TRANSACTION:
TRANSACTION 28210872, ACTIVE 1 sec fetching rows
mysql tables in use 3, locked 3
LOCK WAIT 10 lock struct(s), heap size 3112, 17 row lock(s), undo log entries 4
MySQL thread id 23181, OS thread handle 0x2baae0c48700, query id 195087118 72.21.217.130 fom updating
update ASSIGNMENTS set IS_ACTIVE=0 where REQUEST_ID='XX3-4444476-5557715' and ORDER_ID='107-1180933-9757019'
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 28 page no 192851 n bits 336 index `REQUEST_ID_IDX` of table `db`.`ASSIGNMENTS` trx id 28210872 lock_mode X waiting
Record lock, heap no 162 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 19; hex 464e332d363832383437362d36323237373135; asc XX3-4444476-5557715;;
1: len 30; hex 31306335643136642d383539652d346534302d613666362d373564383062; asc 10c5d16d-859e-4e40-a6f6-75d80b; (total 36 bytes);
*** (2) TRANSACTION:
TRANSACTION 28210851, ACTIVE 1 sec inserting
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 10
MySQL thread id 23418, OS thread handle 0x2baadfe10700, query id 195087560 72.21.217.134 fom update
insert into ASSIGNMENTS (REQUEST_ID, ARCHIVE_ID, PLANNING_DATE, ORDER_ID, IS_ACTIVE, ASSIGNMENTS_ID) values ('XX3-4444476-5557715', 367996451758, '2014-03-31 19:36:46', '999-0925757-2957556', 1, '0f81b648-2d1d-4f81-accf-f37d905ca377')
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 28 page no 192851 n bits 336 index `REQUEST_ID_IDX` of table `db`.`ASSIGNMENTS` trx id 28210851 lock_mode X locks rec but not gap
Record lock, heap no 162 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 19; hex 464e332d363832383437362d36323237373135; asc XX3-4444476-5557715;;
1: len 30; hex 31306335643136642d383539652d346534302d613666362d373564383062; asc 10c5d16d-859e-4e40-a6f6-75d80b; (total 36 bytes);
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 28 page no 192851 n bits 336 index `REQUEST_ID_IDX` of table `db`.`ASSIGNMENTS` trx id 28210851 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 123 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 19; hex 464e332d363832383437362d36323237373135; asc XX3-4444476-5557715;;
1: len 30; hex 31303163383964622d373631372d346237382d393536392d643964613362; asc 101c89db-7617-4b78-9569-d9da3b; (total 36 bytes);
*** WE ROLL BACK TRANSACTION (2)
Those insert and update statements come from the following concurrent transactions:
beginTransaction();
"update ASSIGNMENTS a set a.active = :active where a.requestId = :requestId and a.orderId = :orderId";
"update RESULTS r set r.active = :active where r.requestId = :requestId and exists (select 1 from ASSIGNMENTS a where r.requestId = a.requestId and r.archiveId = a.archiveId and a.orderId = :orderId)";
commitTransaction();
beginTransaction();
"insert into ASSIGNMENTS (REQUEST_ID, ARCHIVE_ID, PLANNING_DATE, ORDER_ID, IS_ACTIVE, ASSIGNMENTS_ID) values (?, ?, ?, ?, ?, ?)";
"insert into RESULTS (REQUEST_ID, ARCHIVE_ID, PLANNING_DATE, IS_ACTIVE, RESULTS_ID) values (?, ?, ?, ?, ?)";
commitTransaction();
Do you guys know what’s the problem here? We retry each transaction 3 times, but I’d like to know what is the exact issue and if it can be avoided. I read about InnoDb locks (http://dev.mysql.com/doc/refman/5.6/en/innodb-deadlocks.html, http://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html), but I still couldn’t figure the root cause.
As a side question, is it preferable to have auto-increment on the primary keys, so that inserts are ordered and thus would not create deadlocks? (http://thushw.blogspot.com/2010/11/mysql-deadlocks-with-concurrent-inserts.html)
I'm using the following tables:
CREATE TABLE `ASSIGNMENTS` (
`ASSIGNMENTS_ID` char(36) NOT NULL,
`REQUEST_ID` varchar(40) NOT NULL,
`ARCHIVE_ID` decimal(22,0) NOT NULL,
`PLANNING_DATE` datetime NOT NULL,
`IS_ACTIVE` char(1) DEFAULT NULL,
`ORDER_ID` varchar(256) DEFAULT NULL,
PRIMARY KEY (`ASSIGNMENTS_ID`),
KEY `REQUEST_ID_IDX` (`REQUEST_ID`),
KEY `ORDER_ID_IDX` (`ORDER_ID`),
KEY `ARCHIVE_IDX` (`ARCHIVE_ID`),
KEY `PLANNING_DATE_IDX` (`PLANNING_DATE`),
KEY `IS_ACTIVE_IDX` (`IS_ACTIVE`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
CREATE TABLE `RESULTS` (
`RESULTS_ID` char(36) NOT NULL,
`REQUEST_ID` varchar(40) NOT NULL,
`ARCHIVE_ID` decimal(22,0) NOT NULL,
`PLANNING_DATE` datetime NOT NULL,
`IS_ACTIVE` char(1) DEFAULT NULL,
PRIMARY KEY (`RESULTS_ID`),
KEY `REQUEST_ID_IDX` (`REQUEST_ID`),
KEY `ARCHIVE_ID_IDX` (`ARCHIVE_ID`),
KEY `PLANNING_DATE_IDX` (`PLANNING_DATE`),
KEY `IS_ACTIVE_IDX` (`IS_ACTIVE`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
ASSIGNMENTS_ID and RESULTS_ID are generated by the application (using Hibernate's uuid2 generator).
I encounter a deadlock quite often and the result of SHOW ENGINE INNODB STATUS is:
LATEST DETECTED DEADLOCK
------------------------
2014-03-31 19:36:51 2baadfe10700
*** (1) TRANSACTION:
TRANSACTION 28210872, ACTIVE 1 sec fetching rows
mysql tables in use 3, locked 3
LOCK WAIT 10 lock struct(s), heap size 3112, 17 row lock(s), undo log entries 4
MySQL thread id 23181, OS thread handle 0x2baae0c48700, query id 195087118 72.21.217.130 fom updating
update ASSIGNMENTS set IS_ACTIVE=0 where REQUEST_ID='XX3-4444476-5557715' and ORDER_ID='107-1180933-9757019'
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 28 page no 192851 n bits 336 index `REQUEST_ID_IDX` of table `db`.`ASSIGNMENTS` trx id 28210872 lock_mode X waiting
Record lock, heap no 162 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 19; hex 464e332d363832383437362d36323237373135; asc XX3-4444476-5557715;;
1: len 30; hex 31306335643136642d383539652d346534302d613666362d373564383062; asc 10c5d16d-859e-4e40-a6f6-75d80b; (total 36 bytes);
*** (2) TRANSACTION:
TRANSACTION 28210851, ACTIVE 1 sec inserting
mysql tables in use 1, locked 1
4 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 10
MySQL thread id 23418, OS thread handle 0x2baadfe10700, query id 195087560 72.21.217.134 fom update
insert into ASSIGNMENTS (REQUEST_ID, ARCHIVE_ID, PLANNING_DATE, ORDER_ID, IS_ACTIVE, ASSIGNMENTS_ID) values ('XX3-4444476-5557715', 367996451758, '2014-03-31 19:36:46', '999-0925757-2957556', 1, '0f81b648-2d1d-4f81-accf-f37d905ca377')
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 28 page no 192851 n bits 336 index `REQUEST_ID_IDX` of table `db`.`ASSIGNMENTS` trx id 28210851 lock_mode X locks rec but not gap
Record lock, heap no 162 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 19; hex 464e332d363832383437362d36323237373135; asc XX3-4444476-5557715;;
1: len 30; hex 31306335643136642d383539652d346534302d613666362d373564383062; asc 10c5d16d-859e-4e40-a6f6-75d80b; (total 36 bytes);
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 28 page no 192851 n bits 336 index `REQUEST_ID_IDX` of table `db`.`ASSIGNMENTS` trx id 28210851 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 123 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 19; hex 464e332d363832383437362d36323237373135; asc XX3-4444476-5557715;;
1: len 30; hex 31303163383964622d373631372d346237382d393536392d643964613362; asc 101c89db-7617-4b78-9569-d9da3b; (total 36 bytes);
*** WE ROLL BACK TRANSACTION (2)
Those insert and update statements come from the following concurrent transactions:
beginTransaction();
"update ASSIGNMENTS a set a.active = :active where a.requestId = :requestId and a.orderId = :orderId";
"update RESULTS r set r.active = :active where r.requestId = :requestId and exists (select 1 from ASSIGNMENTS a where r.requestId = a.requestId and r.archiveId = a.archiveId and a.orderId = :orderId)";
commitTransaction();
beginTransaction();
"insert into ASSIGNMENTS (REQUEST_ID, ARCHIVE_ID, PLANNING_DATE, ORDER_ID, IS_ACTIVE, ASSIGNMENTS_ID) values (?, ?, ?, ?, ?, ?)";
"insert into RESULTS (REQUEST_ID, ARCHIVE_ID, PLANNING_DATE, IS_ACTIVE, RESULTS_ID) values (?, ?, ?, ?, ?)";
commitTransaction();
Do you guys know what’s the problem here? We retry each transaction 3 times, but I’d like to know what is the exact issue and if it can be avoided. I read about InnoDb locks (http://dev.mysql.com/doc/refman/5.6/en/innodb-deadlocks.html, http://dev.mysql.com/doc/refman/5.6/en/innodb-locks-set.html), but I still couldn’t figure the root cause.
As a side question, is it preferable to have auto-increment on the primary keys, so that inserts are ordered and thus would not create deadlocks? (http://thushw.blogspot.com/2010/11/mysql-deadlocks-with-concurrent-inserts.html)