MySQL InnoDB Deadlock Dla 2 prostych zapytań o wstawienie

10

Mam impas dla tych dwóch zapytań dotyczących wstawiania:

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)

Oto status 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)

Jedynym kluczem foriegn w tej tabeli jest „account_id”.

Jakieś pomysły?

EDYCJA: Oto moje informacje o 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
Urbanleg
źródło
Co jeszcze robiłeś w każdej transakcji przed wejściem w impas?
Michael - sqlbot
co jeśli wydasz zatwierdzenie po każdej wstawce, a następnie spróbujesz? Daj nam znać ..
Nawaz Sohail
SHOW CREATE TABLE PlayerClubProszę. Jest to zwykle związane z indeksami.
Jehad Keriaki

Odpowiedzi:

13

TUTAJ SĄ FAKTY

Oto dwa WSTAWKI

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)

Oto dwie linie z twojego 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

UWAGI

Wykonujesz INSERT z dwoma różnymi identyfikatorami konta: 561 i 563.

Są wyjątkowe i nie powinny mieć problemów, prawda? ŹLE !!!

Ze względu na Indeks klastrowy InnoDB wciąż może istnieć impas. Dlaczego ?

Spójrz wstecz na swoje dwa WSTAWKI. PRIMARY KEYNa id w nie podano. Musi być wygenerowany automatycznie. Do każdego klucza innego niż KLUCZ PODSTAWOWY (unikalny lub niepowtarzalny) będzie dołączony KLUCZ PODSTAWOWY.

Proszę zwrócić uwagę na dokumentację MySQL na temat tego, w jaki sposób indeks wtórny i klucz podstawowy są ze sobą powiązane :

Wszystkie indeksy inne niż indeks klastrowany są znane jako indeksy wtórne. W InnoDB każdy rekord w indeksie wtórnym zawiera kolumny klucza podstawowego dla wiersza, a także kolumny określone dla indeksu dodatkowego. InnoDB używa tej wartości klucza podstawowego do wyszukiwania wiersza w indeksie klastrowym.

Jeśli klucz podstawowy jest długi, indeksy wtórne zajmują więcej miejsca, więc dobrze jest mieć krótki klucz podstawowy.

Chociaż wstawiasz account_id 561 i 563, pod maską jesteś wstawiany 561-(id)i 563-(id)do UK_cagoa3q409gsukj51ltiokjohindeksu. PRIMARY KEYStaje się wąskim gardłem, ponieważ indeks wtórny musi czekać, aż idkolumna auto_generated.

REKOMENDACJE

Masz stół z dwoma kluczami kandydującymi

  • PRIMARY KEY na id
  • UNIQUE KEY na UK_cagoa3q409gsukj51ltiokjoh

Ponieważ oba są BIGINT, możesz zwiększyć wydajność i mieć mniejszy PlayerClubstół, pozbywając się idi nadal zachowując wyjątkowość, UK_cagoa3q409gsukj51ltiokjoha także unikając tej impasu.

RolandoMySQLDBA
źródło
1
Dopiero po usunięciu Jedynym kluczem foriegn w tej tabeli jest „account_id” zatrzymanie impasu.
Urbanleg