Ich erhalte Deadlocks von Lückenschlössern auf einer Tabelle, wenn ich sie häufig aus mehreren Quellen einfüge. Hier ist eine Übersicht meiner Prozesse.
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
Die Ausgabe von SHOW Create table vehicle_image;
ist:
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
Und der letzte Deadlock von 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)
Ich führe viele dieser Prozesse gleichzeitig aus, aber niemals zwei Prozesse, die denselben verwenden VehicleID
. Ich bin wirklich verwirrt, warum ich Deadlocks bekomme.
Ich habe das Problem vorübergehend mithilfe der Isolationsstufe gelöst READ COMMITTED
, aber ich habe gelesen, dass dies Änderungen an der Replikation erfordert, da Sie die Replikation auf Zeilenebene durchführen müssen.
Ich habe hier andere Fragen gelesen, die meinen ähnlich sind, aber ich bin etwas neu in SQL und kann immer noch nicht verstehen, warum dies geschieht.
Ähnliche Fragen:
- Deadlock bei MySQL-Insert-Anweisungen
- MySQL InnoDB Deadlock Für 2 einfache Insert-Abfragen
AKTUALISIEREN:
Ich fand heraus, dass die Verwendung READ COMMITTED
das Problem nicht wirklich gelöst hat. Ich habe immer noch nicht herausgefunden, warum die Deadlocks auftreten, und ich weiß wirklich nicht, wie ich weiter diagnostizieren soll, als ich es derzeit getan habe. Ich bekomme weiterhin Deadlocks in mein Produktionssystem. Jede Hilfe wäre dankbar.
VARCHARs
.
loop
nur ein Pseudocode ist, um darzustellen, was gerade stattfindet.
repeatable read
an read committed
dem eine untere Isolationsstufe dann wiederholbare lesen, aber leider hat es nicht die Deadlocks zu stoppen. Ich weiß, dass die Hardware den Server beeinflusst (es ist eine ec2-Instanz, ich müsste nach Einzelheiten suchen), aber ich denke nicht, dass diese Informationen notwendig wären, um zu verstehen, warum die Deadlocks auftreten. Die sporadische Natur macht es auch schwierig, die Ausgabe der Show-Prozessliste zu erfassen. wenn der Deadlock auftritt.
SHOW PROCESSLIST;
. MeistensREPEATABLE READ
ist dies die beste Isolationsstufe für die meisten Apps, daher würde ich mir keine Sorgen um die Verwendung machen. Gab es eine spürbare Leistungssteigerung, als Sie die Standardeinstellung geändert habenREPEATABLE READ
?