Kategorien
MySQL

MySQL Update Deadlock InnoDB

Ein kniffeliges Problem ist letztens aufgetreten bei einer partitionierten MySQL Datenbank. Es kam immer wieder bei hoher Last zu Deadlock Meldungen seitens MySQL. Immer waren 2 Queries davon betroffen, die dieselbe Form hatten:

--Query1:
UPDATE myTable SET createdOn='2016-05-23 16:08:29', foo='y' WHERE id=1
--Query2:
UPDATE myTable SET createdOn='2016-05-23 16:08:29', foo='x' WHERE id=2

Im MySQL Error Log war ein solcher Eintrag zu finden:

mysql tables in use 1, locked 1
LOCK WAIT 106 lock struct(s), heap size 8400, 53 row lock(s)

Tip: Mit der Systemvariablen innodb_print_all_deadlocks (ab MySQL 5.5) kann man Deadlocks in InnoDB in das MySQL Error Log loggen und besser debuggen.

Eigentlich sollte es bei den beiden Queires nicht zu einem Deadlock kommen, da beide nur jeweils ein Row-Level Lock auf ihrer jeweilige Zeile haben sollten.

Dies ist auch der Fall, wenn es einen Index auf der Spalte id gibt. In diesem Fall allerdings war durch die Partitionierung der Primary (Unique) Index auf  2 Spalten gelegt worden (kombinierten Index): id und createdOn.

Dadurch, dass der Index auf beiden Soalten gelegt worden ist, kam es zu den dem Dealocks. Die Lösung war, das createdOn aus dem Update Statement zu entfernen, weil es an der Stelle auch keinen Sinn gemacht hat.