2 개의 간단한 삽입 쿼리를위한 MySQL InnoDB 교착 상태


10

이 두 삽입 쿼리에 대한 교착 상태가 있습니다.

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)

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)

이 테이블에서 유일한 foriegn 키는 "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

교착 상태에 도달하기 전에 각 트랜잭션에서 무엇을 했습니까?
Michael-sqlbot

각 삽입 후 커밋을 실행 한 다음 시도하면 어떻게됩니까? 알려주세요 ..
Nawaz Sohail

SHOW CREATE TABLE PlayerClub부디. 이것은 일반적으로 인덱스와 관련이 있습니다.
Jehad Keriaki

답변:


13

사실이 있습니다

다음은 두 개의 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)

다음은 두 줄입니다. 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

관찰

두 개의 다른 account_ids로 INSERT를 수행합니다 (561 및 563).

그들은 독특하고 문제가 없어야합니다. 잘못된 !!!

InnoDB의 Clustered Index로 인해 교착 상태가 여전히 발생할 수 있습니다. 왜 ?

두 개의 INSERT를 다시 살펴보십시오. PRIMARY KEY지정되지에서의 ID입니다. 자동 생성되어야합니다. PRIMARY KEY (고유 또는 고유하지 않은) 이외의 키에는 PRIMARY KEY가 첨부됩니다.

보조 인덱스와 기본 키가 얽혀있는 방법에 대한 MySQL 설명서를 참고하십시오 .

클러스터형 인덱스 이외의 모든 인덱스를 보조 인덱스라고합니다. 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테이블을 가질 수 있습니다.idUK_cagoa3q409gsukj51ltiokjoh


1
제거 후에 만이 테이블에서 유일한 foriegn 키는 교착 상태 중지가 발생하는 "account_id"입니다.
Urbanleg
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.