Wie behebe ich dieses MySQL / InnoDB Deadlocks Problem in einer nicht-blockierende Umgebung?

StackOverflow https://stackoverflow.com/questions/870097

  •  22-08-2019
  •  | 
  •  

Frage

Wir verwenden MySQL mit InnoDB-Engine Speicher. Wir haben eine „evented“ Umgebung, die mehrere gleichzeitige Zugriffe auf eine Tabelle sendet. Grundsätzlich funktioniert es wie folgt aus: Wir haben eine find_or_insert Funktion, die das tut: - finden() -> auf das Ergebnis, wenn leer -> Einsatz -> auf Ergebnis find ()

Wir verwenden einen nicht-blockierende MySQL-Treiber, so dass im Grunde, wenn wir diesen kleinen Algorithmus mehr als einmal zur gleichen Zeit starten, läuft es alle Funde, bevor Sie das erste Ergebnisses Einfügen ... etc.

Leider bekommen wir diese Fehler: „Deadlock gefunden, wenn sie versuchen Sperre zu bekommen, versuchen Transaktion neu zu starten“

Jeder kann dabei helfen?

[EDIT]: Auch, ich verstehe wirklich nicht, warum würde MySQL braucht die Tabelle zu sperren gerade hier ein neues Element einzufügen. Am Anfang, obwohl ich das Auto-Inkrement die Täter hier war, so nahm ich es ... bu ich noch die Störung. Gibt es eine Möglichkeit MySQL zu verhindern, dass in der Tabelle auf Einsätze zu sperren?

War es hilfreich?

Lösung

Versuchen Sie, das mysql-Referenzhandbuch zur Diagnose und zu lösen. Es klingt wie Sie einen Cache machen. Ein möglicher Grund könnte sein, dass viele Clients gleichzeitig die Tabelle, die die ‚erste Version‘ versucht, treffen zu erstellen (das heißt traf die ‚wenn leer Einlage‘). Vielleicht könnten Sie eine pseudo-zufällige Verzögerung hinzufügen oder die Schöpfer koordinieren, so dass Sie viele gleichzeitige schaffen nicht bekommen Anrufe an die db?

EDIT: Haben Sie gesehen diese Seite? Scheint, als ob Sie eine my.cnf Einstellung pro-Tabelle deaktivieren Schlösser mit innodb einstellen müssen. Was ich vor allem wurde darauf hindeutet, war aber, dass Ihr Test nicht darstellbar sein könnte, da sie einen viel höheren Prozentsatz Autoren als in einer realistischen Situation enthalten. Wenn Sie 100 Threads mit einer leeren Tabelle beginnen sie alle sofort auf blockieren würden erstellen (auch für den gleichen Wert vielleicht). Das ist viel schlimmer als in einer durchschnittlichen Situation, wo Sie eine bessere Verteilung über die Tasten haben, wenige Fehlschüsse und einen viel höheren Prozentsatz von liest. Wenn dieses Verhalten erwartet wird (das heißt Sie dieses Verhalten leben haben würde), würde ich vorschlagen, eine Backoff-Strategie in den erstellen Aussagen hinzufügen.

Andere Tipps

Sie müssen diese Anforderungen einen passieren zu einer Zeit, vielleicht so nicht mehr verwenden, dass nicht-blockierenden Treiber. Oder Ihren eigenen Sperrmechanismus implementieren. Warten Sie ein, bevor sie zu dem nächsten zu beenden.

Du hast gesagt haben, dass dies nicht vertretbar ist, oder dass Sie aus irgendeinem Grund müssen diese Dinge so schnell bewegen sich entlang.

Ich ändere meine Antwort zu reflektieren, dass die Frage überarbeitet. Es klingt nun wie folgt nur ein Problem mit den gleichzeitigen Einsätzen ist, nicht eine Abhängigkeit von der Entdeckung Verhalten.

Es ist mein Verständnis, dass InnoDB auf Einsätze nicht Zeilensperren und Sie können dies nicht ausschalten. Jedoch Sie [Bearbeiten] sind nicht in der Lage INSERT DELAYED zu verwenden. Ich habe gerade gelesen das auf InnoDB nicht verfügbar ist.

http://dev.mysql.com/doc /refman/5.0/en/insert-delayed.html

Vielleicht eine explizite LOCK TABLES um alle Ihre schreibt kollektiv die Standardsperrverhalten außer Kraft setzen. Wenn es keine andere Operationen auf dem Tisch während des Intervalls, wenn die Schreib Ereignisse eintreten, könnte dies funktionieren.

http://dev.mysql.com/doc /refman/5.0/en/lock-tables.html

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top