3 Stimmen

Gibt es eine Möglichkeit, blockierungsfreie Lesevorgänge in MySQL zu GARANTIEREN?

Ich habe das offensichtliche "SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED" ausprobiert, aber meine einfache gespeicherte Prozedur wird immer noch blockiert, wenn ich ein SELECT MAX auf einem PRIMARY KEY ausführe, während Aktualisierungen stattfinden (wenn sie gleichzeitig mit bestimmten komplexen Aktualisierungstransaktionen ausgeführt werden, die ich nicht ändern möchte), und gerät schließlich in Deadlocks und Lock Timeouts.

Es muss doch eine Möglichkeit geben, ein nicht-blockierendes Lesen zu GARANTIEREN... Und ich dachte, das sei der Zweck von READ-UNCOMMITTED. Aber ich habe mich geirrt... Ist das ein MySQL-Fehler? Gibt es einen Workaround?

Ich bin mir all der Gefahren und der akademisch unhaltbaren Eigenschaften von READ-UNCOMMITTED bewusst, aber das spielt keine Rolle, denn für meine spezielle Anwendung ist eine gelegentliche Phantomzeile oder eine fehlende Zeile hier und da wirklich keine große Sache, aber die Verzögerung oder der Fehler, der durch die Lesesperren verursacht wird, ist eine viel ernstere Sache.

Alle Tabellen in der Datenbank sind InnoDB. Die Serverversion ist 5.0.67. Die Plattform ist Linux 32-bit.

UPDATE Hier ist eine vereinfachte "Hallo Welt"-Version der Problembeschreibung (meine tatsächlichen Abfragen sind zu komplex und hässlich, um sie zu posten):

KONSOLE 1:

mysql> create table t1(a int primary key) engine=innodb;
Query OK, 0 rows affected (0.20 sec)

mysql> insert into t1 values (1),(2),(3);
Query OK, 3 rows affected (0.03 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t1 values (4);
Query OK, 1 row affected (0.01 sec)

mysql> update t1 set a=5 where a=4;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

KONSOLE 2 (in separatem Fenster, KONSOLE 1 nicht schließen)

mysql> select max(a) from t1;
+--------+
| max(a) |
+--------+
|      3 | 
+--------+
1 row in set (0.00 sec)

mysql> set @test = (select max(a) from t1);
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X