MySQL InnoDB Deadlock para 2 consultas de inserción simples

10

Tengo un punto muerto para estas dos consultas de inserción:

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)

Aquí está el estado de 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)

La única clave extranjera en esta tabla es el "account_id".

¿Algunas ideas?

EDITAR: Aquí está la información de mi 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
fuente
¿Qué más hiciste en cada transacción antes de llegar al punto muerto?
Michael - sqlbot
¿Qué pasa si emite commit después de cada inserción y luego intenta? Háganos saber ..
Nawaz Sohail
SHOW CREATE TABLE PlayerClubPor favor. Esto generalmente está relacionado con los índices.
Jehad Keriaki

Respuestas:

13

AQUÍ ESTÁN LOS HECHOS

Aquí están los dos INSERTOS

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)

Aquí están las dos líneas de su 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

OBSERVACIONES

Estás haciendo un INSERT con dos cuentas_id diferentes: 561 y 563.

Son únicos y no deberían tener problemas, ¿verdad? INCORRECTO !!!

Debido al índice agrupado de InnoDB, todavía puede haber un punto muerto. Por qué ?

Mire hacia atrás a sus dos INSERTOS. La PRIMARY KEYidentificación de encendido no está especificada. Debe ser generado automáticamente. Cualquier clave que no sea la PRIMARY KEY (única o no única) tendrá adjunta la PRIMARY KEY.

Tenga en cuenta la documentación de MySQL sobre cómo se entrelazan un índice secundario y una clave primaria :

Todos los índices que no sean el índice agrupado se conocen como índices secundarios. En InnoDB, cada registro en un índice secundario contiene las columnas de clave principal para la fila, así como las columnas especificadas para el índice secundario. InnoDB usa este valor de clave principal para buscar la fila en el índice agrupado.

Si la clave primaria es larga, los índices secundarios usan más espacio, por lo que es ventajoso tener una clave primaria corta.

Aunque está insertando account_id 561 y 563, debajo del capó está insertando 561-(id)y 563-(id)en el UK_cagoa3q409gsukj51ltiokjohíndice. El se PRIMARY KEYconvierte en el cuello de botella porque el índice secundario tiene que esperar hasta que la idcolumna se autogenere.

RECOMENDACIÓN

Tienes una mesa con dos claves candidatas

  • PRIMARY KEY en id
  • UNIQUE KEY en UK_cagoa3q409gsukj51ltiokjoh

Dado que ambos lo son BIGINT, podría aumentar el rendimiento y tener una PlayerClubtabla más pequeña al deshacerse de idy mantener la unicidad UK_cagoa3q409gsukj51ltiokjoh, además de evitar esta situación de bloqueo.

RolandoMySQLDBA
fuente
1
Solo después de eliminar La única clave extranjera en esta tabla es el "account_id", el punto muerto se detiene.
Urbanleg