Urb*_*leg 13 mysql innodb deadlock
对于这两个插入查询,我有一个死锁:
insert into PlayerClub (modifiedBy, timeCreated, currentClubId, endingLevelPosition, nextClubId, account_id) values (0, '2014-12-23 15:47:11.596', 180, 4, 181, 561)
insert into PlayerClub (modifiedBy, timeCreated, currentClubId, endingLevelPosition, nextClubId, account_id) values (0, '2014-12-23 15:47:11.611', 180, 4, 181, 563)
Run Code Online (Sandbox Code Playgroud)
这是 InnoDB 状态:
------------------------
LATEST DETECTED DEADLOCK
------------------------
2014-12-23 15:47:11 1f4c
*** (1) TRANSACTION:
TRANSACTION 19896526, ACTIVE 0 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 5 lock struct(s), heap size 1248, 3 row lock(s), undo log entries 1
MySQL thread id 17988, OS thread handle 0x17bc, query id 5701353 localhost 127.0.0.1 root update
insert into PlayerClub (modifiedBy, timeCreated, currentClubId, endingLevelPosition, nextClubId, account_id) values (0, '2014-12-23 15:47:11.596', 180, 4, 181, 561)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 49735 page no 4 n bits 72 index `UK_cagoa3q409gsukj51ltiokjoh` of table `db`.`playerclub` trx id 19896526 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;
*** (2) TRANSACTION:
TRANSACTION 19896542, ACTIVE 0 sec inserting, thread declared inside InnoDB 5000
mysql tables in use 1, locked 1
5 lock struct(s), heap size 1248, 3 row lock(s), undo log entries 1
MySQL thread id 17979, OS thread handle 0x1f4c, query id 5701360 localhost 127.0.0.1 root update
insert into PlayerClub (modifiedBy, timeCreated, currentClubId, endingLevelPosition, nextClubId, account_id) values (0, '2014-12-23 15:47:11.611', 180, 4, 181, 563)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 49735 page no 4 n bits 72 index `UK_cagoa3q409gsukj51ltiokjoh` of table `db`.`playerclub` trx id 19896542 lock_mode X
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 49735 page no 4 n bits 72 index `UK_cagoa3q409gsukj51ltiokjoh` of table `db`.`playerclub` trx id 19896542 lock_mode X insert intention waiting
Record lock, heap no 1 PHYSICAL RECORD: n_fields 1; compact format; info bits 0
0: len 8; hex 73757072656d756d; asc supremum;;
*** WE ROLL BACK TRANSACTION (2)
Run Code Online (Sandbox Code Playgroud)
该表上唯一的外键是“account_id”。
有任何想法吗?
编辑:这是我的 PlayerClub 信息:
CREATE TABLE `PlayerClub` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`modifiedBy` bigint(20) DEFAULT NULL,
`timeCreated` datetime NOT NULL,
`account_id` bigint(20) DEFAULT NULL,
`currentClubId` bigint(20) DEFAULT NULL,
`endingLevelPosition` int(11) NOT NULL,
`nextClubId` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `UK_cagoa3q409gsukj51ltiokjoh` (`account_id`),
KEY `FK_cagoa3q409gsukj51ltiokjoh` (`account_id`),
CONSTRAINT `FK_cagoa3q409gsukj51ltiokjoh` FOREIGN KEY (`account_id`) REFERENCES `PlayerAccount` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1
Run Code Online (Sandbox Code Playgroud)
Rol*_*DBA 15
这是两个 INSERT
insert into PlayerClub (modifiedBy, timeCreated, currentClubId, endingLevelPosition, nextClubId, account_id) values (0, '2014-12-23 15:47:11.596', 180, 4, 181, 561)
insert into PlayerClub (modifiedBy, timeCreated, currentClubId, endingLevelPosition, nextClubId, account_id) values (0, '2014-12-23 15:47:11.611', 180, 4, 181, 563)
Run Code Online (Sandbox Code Playgroud)
这是你的两行 SHOW ENGINE INNODB STATUS\G
RECORD LOCKS space id 49735 page no 4 n bits 72 index `UK_cagoa3q409gsukj51ltiokjoh` of table `db`.`playerclub` trx id 19896526 lock_mode X insert intention waiting
RECORD LOCKS space id 49735 page no 4 n bits 72 index `UK_cagoa3q409gsukj51ltiokjoh` of table `db`.`playerclub` trx id 19896542 lock_mode X
Run Code Online (Sandbox Code Playgroud)
您使用两个不同的 account_id 执行 INSERT:561 和 563。
它们是独一无二的,不应该有问题,对吗?错误的 !!!
由于 InnoDB 的聚集索引,仍然可能存在死锁。为什么 ?
回头看看你的两个 INSERT。在PRIMARY KEY
对ID中没有规定。它必须是自动生成的。除 PRIMARY KEY(唯一或非唯一)之外的任何键都将附加 PRIMARY KEY。
除聚集索引外的所有索引都称为二级索引。在 InnoDB 中,二级索引中的每条记录都包含该行的主键列,以及为二级索引指定的列。InnoDB 使用这个主键值来搜索聚集索引中的行。
如果主键很长,二级索引会占用更多的空间,所以主键短是有利的。
尽管您插入的是 account_id 561 和 563,但实际上您是插入561-(id)
并563-(id)
插入UK_cagoa3q409gsukj51ltiokjoh
索引中。将PRIMARY KEY
成为瓶颈,因为直到二级索引必须等待id
列AUTO_GENERATED。
您有一个包含两个候选键的表
PRIMARY KEY
在 id
UNIQUE KEY
在 UK_cagoa3q409gsukj51ltiokjoh
由于两者都是BIGINT
,您可以PlayerClub
通过摆脱id
并仍然保持唯一性来提高性能并拥有更小的表,因为UK_cagoa3q409gsukj51ltiokjoh
以及避免这种死锁情况。