MySQL InnoDB Deadlock Per 2 semplici query di inserimento


10

Ho un deadlock per queste due query di inserimento:

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)

Ecco lo stato di 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)

L'unica chiave foriegn in questa tabella è "account_id".

Qualche idea?

EDIT: Ecco le mie informazioni su 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

Cos'altro hai fatto in ogni transazione prima di colpire il deadlock?
Michael - sqlbot,

cosa succede se si esegue il commit dopo ogni inserimento e quindi si prova? Facci sapere ..
Nawaz Sohail,

SHOW CREATE TABLE PlayerClubper favore. Questo di solito è correlato agli indici.
Jehad Keriaki,

Risposte:


13

QUI SONO I FATTI

Ecco i due INSERTI

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)

Ecco le due linee dal tuo 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

OSSERVAZIONI

Stai facendo un INSERT con due account_ids diversi: 561 e 563.

Sono unici e non dovrebbero avere problemi, giusto? SBAGLIATO !!!

A causa dell'indice cluster di InnoDB, può esserci ancora un deadlock. Perché ?

Guarda indietro ai tuoi due INSERTI. L' PRIMARY KEYID attivo non è specificato. Deve essere generato automaticamente. Qualsiasi chiave diversa dalla PRIMARY KEY (unica o non univoca) avrà la PRIMARY KEY allegata.

Si prega di notare la documentazione di MySQL su come un indice secondario e una chiave primaria si intrecciano :

Tutti gli indici diversi dall'indice cluster sono noti come indici secondari. In InnoDB, ogni record in un indice secondario contiene le colonne chiave primaria per la riga, nonché le colonne specificate per l'indice secondario. InnoDB utilizza questo valore di chiave primaria per cercare la riga nell'indice cluster.

Se la chiave primaria è lunga, gli indici secondari utilizzano più spazio, quindi è vantaggioso disporre di una chiave primaria breve.

Anche se si sta inserendo account_id 561 e 563, sotto il cofano si è inserto 561-(id)e 563-(id)in UK_cagoa3q409gsukj51ltiokjohindice. Il PRIMARY KEYdiventa il collo di bottiglia perché l'indice secondario deve attendere fino a quando la idcolonna viene generata automaticamente.

RACCOMANDAZIONE

Hai un tavolo con due chiavi candidate

  • PRIMARY KEY su id
  • UNIQUE KEY su UK_cagoa3q409gsukj51ltiokjoh

Dal momento che entrambi lo sono BIGINT, è possibile aumentare le prestazioni e disporre di una PlayerClubtabella più piccola eliminando ide mantenendo comunque l'unicità a causa UK_cagoa3q409gsukj51ltiokjohe evitando questa situazione di deadlock.


1
Solo dopo aver rimosso L'unica chiave foriegn in questa tabella è "account_id" che si verifica quando si verifica un deadlock.
Urbanleg,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.