J'obtiens des verrous mortels à partir de verrous d'espacement sur une table lorsque j'insère fréquemment dedans à partir de plusieurs sources. Voici un aperçu de mes processus.
START TRANSACTION
UPDATE vehicle_image
SET active = 0
WHERE vehicleID = SOMEID AND active = 1
Loop:
INSERT INTO vehicle_image (vehicleID, vehicleImageFilePath, vehicleImageSplashFilePath
,vehicleImageThumbnailFilePath, vehicleImageMiniFilePath, mainVehicleImage, active)
VALUES (%s, %s, %s, %s, %s, %s, 1);
END TRANSACTION
La sortie de SHOW Create table vehicle_image;
est:
CREATE TABLE `vehicle_image` (
`vehicleImageID` int(11) NOT NULL AUTO_INCREMENT,
`vehicleID` int(11) DEFAULT NULL,
`vehicleImageFilePath` varchar(200) DEFAULT NULL,
`vehicleImageSplashFilePath` varchar(200) DEFAULT NULL,
`vehicleImageThumbnailFilePath` varchar(200) DEFAULT NULL,
`vehicleImageMiniFilePath` varchar(200) DEFAULT NULL,
`mainVehicleImage` bit(1) DEFAULT NULL,
`active` bit(1) DEFAULT b'1',
`userCreated` int(11) DEFAULT NULL,
`dateCreated` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`userModified` int(11) DEFAULT NULL,
`dateModified` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',
PRIMARY KEY (`vehicleImageID`),
KEY `active` (`active`),
KEY `mainvehicleimage` (`mainVehicleImage`),
KEY `vehicleid` (`vehicleID`)
) ENGINE=InnoDB AUTO_INCREMENT=22878102 DEFAULT CHARSET=latin1
Et le dernier Deadlock donné par SHOW engine innodb status
:
LATEST DETECTED DEADLOCK
------------------------
2018-03-27 12:31:15 11a58
*** (1) TRANSACTION:
TRANSACTION 5897678083, ACTIVE 2 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 3 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 1
MySQL thread id 873570, OS thread handle 0x124bc, query id 198983754 ec2-34-239-240-179.compute-1.amazonaws.com 34.239.240.179 image_processor update
INSERT INTO vehicle_image (vehicleID, vehicleImageFilePath, vehicleImageSplashFilePath, vehicleImageThumbnailFilePath, vehicleImageMiniFilePath, mainVehicleImage, active)
VALUES (70006176, 'f180928(1)1522168276.230837full.jpg', 'f180928(1)1522168276.230837splash.jpg', 'f180928(1)1522168276.230837thumb.jpg', 'f180928(1)1522168276.230837mini.jpg', 1, 1)
*** (1) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 875 page no 238326 n bits 472
index `vehicleid` of table `ipacket`.`vehicle_image` trx id 5897678083
lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 378 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 842c365a; asc ,6Z;;
1: len 4; hex 815d03bc; asc ] ;;
*** (2) TRANSACTION:
TRANSACTION 5897678270, ACTIVE 1 sec inserting, thread declared inside InnoDB 5000
mysql tables in use 1, locked 1
3 lock struct(s), heap size 1248, 2 row lock(s), undo log entries 1
MySQL thread id 873571, OS thread handle 0x11a58, query id 198983849 ec2-35-171-169-21.compute-1.amazonaws.com 35.171.169.21 image_processor update
INSERT INTO vehicle_image (vehicleID, vehicleImageFilePath, vehicleImageSplashFilePath, vehicleImageThumbnailFilePath, vehicleImageMiniFilePath, mainVehicleImage, active)
VALUES (70006326, '29709(1)1522168277.4443843full.jpg', '29709(1)1522168277.4443843splash.jpg', '29709(1)1522168277.4443843thumb.jpg', '29709(1)1522168277.4443843mini.jpg', 1, 1)
*** (2) HOLDS THE LOCK(S):
RECORD LOCKS space id 875 page no 238326 n bits 464
index `vehicleid` of table `ipacket`.`vehicle_image` trx id 5897678270
lock_mode X locks gap before rec
Record lock, heap no 378 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 842c365a; asc ,6Z;;
1: len 4; hex 815d03bc; asc ] ;;
*** (2) WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 875 page no 238326 n bits 472
index `vehicleid` of table `ipacket`.`vehicle_image` trx id 5897678270
lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 378 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
0: len 4; hex 842c365a; asc ,6Z;;
1: len 4; hex 815d03bc; asc ] ;;
*** WE ROLL BACK TRANSACTION (2)
J'exécute plusieurs de ces processus simultanément, mais je n'exécute jamais deux processus qui utilisent le même VehicleID
. Je ne comprends vraiment pas pourquoi je reçois des blocages.
J'ai résolu temporairement le problème en utilisant le niveau d'isolement READ COMMITTED
, mais j'ai lu que cela nécessite des modifications de réplication dans la mesure où vous devez effectuer une réplication au niveau des lignes.
J'ai lu d'autres questions ici qui sont similaires aux miennes, mais je suis un peu nouveau pour SQL et je ne comprends toujours pas pourquoi cela se produit.
Questions similaires:
- Blocage sur les insertions MySQL
- Blocage MySQL InnoDB Pour 2 requêtes d'insertion simples
MISE À JOUR:
J'ai découvert que l'utilisation READ COMMITTED
n'a pas vraiment résolu le problème. Je n'ai toujours pas compris pourquoi les blocages se produisent et je ne sais vraiment pas comment diagnostiquer plus loin que ce que j'ai actuellement. Je continue d'avoir des impasses dans mon système de production. Toute aide serait appréciée.
VARCHARs
.
loop
pseudocode est juste pour représenter ce qui se passe.
repeatable read
à read committed
qui est un niveau d'isolation plus faible puis de lecture répétée, mais malheureusement cela n'a pas empêché les blocages. Je sais que le matériel affectera le serveur (c'est une instance ec2, je devrais rechercher des détails) mais je ne pense pas que ces informations seraient nécessaires pour comprendre pourquoi les blocages se produisent. La nature sporadique de ceci rend également difficile la capture de la sortie de show processlist; lorsque l'impasse se produit.
SHOW PROCESSLIST;
. La plupart du temps,REPEATABLE READ
c'est le meilleur niveau d'isolement pour la plupart des applications, donc je ne serais pas trop préoccupé par son utilisation. Y a-t-il eu une augmentation notable des performances lorsque vous l'avez modifiée par défaut -REPEATABLE READ
?