MySQL InnoDB Deadlock Für 2 einfache Einfügeabfragen

10

Ich habe einen Deadlock für diese beiden Einfügeabfragen:

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)

Hier ist der InnoDB-Status:

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

Der einzige Foriegn-Schlüssel in dieser Tabelle ist die "account_id".

Irgendwelche Ideen?

EDIT: Hier sind meine PlayerClub-Informationen:

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
quelle
Was haben Sie bei jeder Transaktion noch getan, bevor Sie den Deadlock erreicht haben?
Michael - sqlbot
Was ist, wenn Sie nach jeder Einfügung ein Commit ausgeben und es dann versuchen? Lassen Sie es uns wissen ..
Nawaz Sohail
SHOW CREATE TABLE PlayerClubBitte. Dies hängt normalerweise mit Indizes zusammen.
Jehad Keriaki

Antworten:

13

HIER SIND DIE FAKTEN

Hier sind die beiden INSERTs

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)

Hier sind die beiden Zeilen von Ihrem 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

BEMERKUNGEN

Sie führen ein INSERT mit zwei verschiedenen account_ids aus: 561 und 563.

Sie sind einzigartig und sollten keine Probleme haben, oder? FALSCH !!!

Aufgrund des Clustered Index von InnoDB kann es immer noch zu einem Deadlock kommen. Warum ?

Schau zurück auf deine beiden INSERTs. Die Ein- PRIMARY KEYID ist nicht angegeben. Es muss automatisch generiert werden. An jeden anderen Schlüssel als den PRIMARY KEY (eindeutig oder nicht eindeutig) wird der PRIMARY KEY angehängt.

Bitte beachten Sie die MySQL-Dokumentation darüber, wie ein Sekundärindex und ein Primärschlüssel miteinander verflochten sind :

Alle Indizes außer dem Clustered-Index werden als Sekundärindizes bezeichnet. In InnoDB enthält jeder Datensatz in einem Sekundärindex die Primärschlüsselspalten für die Zeile sowie die für den Sekundärindex angegebenen Spalten. InnoDB verwendet diesen Primärschlüsselwert, um nach der Zeile im Clustered-Index zu suchen.

Wenn der Primärschlüssel lang ist, belegen die Sekundärindizes mehr Speicherplatz. Daher ist es vorteilhaft, einen kurzen Primärschlüssel zu haben.

Obwohl Sie account_id 561 und 563 einfügen, fügen Sie unter der Haube 561-(id)und 563-(id)in den UK_cagoa3q409gsukj51ltiokjohIndex ein. Das PRIMARY KEYwird der Engpass , da der Sekundärindex warten muss , bis die idSpalte auto_generated wird.

EMPFEHLUNG

Sie haben eine Tabelle mit zwei Kandidatenschlüsseln

  • PRIMARY KEY auf id
  • UNIQUE KEY auf UK_cagoa3q409gsukj51ltiokjoh

Da dies beide der Fall sind BIGINT, können Sie die Leistung steigern und einen kleineren PlayerClubTisch haben, indem Sie iddie Eindeutigkeit beseitigen und dennoch beibehalten, da UK_cagoa3q409gsukj51ltiokjohdiese Deadlock-Situation vermieden wird.

RolandoMySQLDBA
quelle
1
Erst nach dem Entfernen Der einzige falsche Schlüssel in dieser Tabelle ist die "account_id", bei der der Deadlock beendet wird.
Urbanleg