it-swarm.com.de

Wie geht Wordpress mit MySQL-Zeilensperrfehlern um?

Was passiert, wenn es ein WordPress-Plugin gibt, das Zeilen in einer benutzerdefinierten Tabelle aktualisiert, bei dem jedoch eine Zeilensperre festgestellt wird? Z.B. Zwei Benutzer lösen gleichzeitig ein Update für TABLE1 aus, wobei einer die Einstellung AGE = 1 und der andere die Einstellung AGE = 2 hat:

  • Wird es überhaupt eine Reihensperre geben?
  • Wird MySQL dies "anmutig" handhaben und eines der 2 Updates einfach "verloren" gehen?
  • Geht Wordpress damit zierlich um?
  • Muss ich mich im Plugin darum kümmern?

Die Daten sind nicht sehr wichtig, da ich nicht jede Änderung verfolgen muss. Aber ich muss mit möglichen Fehlern umgehen.

5
Samudra

Streng aus Sicht von MySQL

KURZE VERSION

MyISAM Storage Engine

  • Tischschlösser
  • Schreiben heißt wer zuerst kommt, mahlt zuerst
  • Liest langsame Schreibvorgänge vom Initiieren

InnoDB Storage Engine

  • Zeilensperren
  • Transaktionen (nicht blockierend)
  • Beim Aktualisieren von Indizes kann ein Deadlock auftreten

LANGE VERSION

Wenn die zugrunde liegenden Tabellen die MyISAM Storage Engine verwenden, sind Zeilensperren nicht möglich. Jede DML-Anweisung (INSERT, UPDATE und DELETE) bewirkt eine vollständige Tabellensperre.

Wenn 50 DB-Verbindungen versuchen, eine Zeile in mydb.mytable zu aktualisieren

  • 1 Tabellensperre, 1 Update, 49 DB-Verbindungen warten
  • 1 Tabellensperre, 1 Update, 48 DB-Verbindungen warten
  • 1 Tabellensperre, 1 Update, 47 DB-Verbindungen warten
  • ...
  • 1 Tabellensperre, 1 Update, 02 DB-Verbindungen warten
  • 1 Tabellensperre, 1 Update, 01 DB Connections wartet

Verstehe? Sie können sehen, wo ein Engpass in nur einer Tabelle auftreten kann. Stellen Sie sich jetzt eine stark frequentierte WordPress-Site vor. SELECTs haben Vorrang vor DML-Anweisungen (Ausnahme sind gleichzeitige INSERTs in MyISAM-Tabellen, vorausgesetzt, in der MyISAM-Tabelle werden nur SELECTs und INSERTs ausgeführt, ohne dass dazwischen Lücken bestehen). Hunderte oder sogar Dutzende von SELECT-Anweisungen zwischen DML-Anweisungen können den oben genannten Engpass noch weiter verlangsamen.

Die Rettung von MyISAM in einer stark frequentierten WordPress-Site besteht darin, dass niemals Deadlocks auftreten können.

Wenn die zugrunde liegenden Tabellen InnoDB Storage Engine verwenden, können Zeilensperren (auch in derselben Zeile) niemals Lesevorgänge blockieren, während Schreibvorgänge sind jedoch weiterhin Deadlocks möglich. Wenn AUTOCOMMIT=0 in /etc/my.cnf festgelegt ist, wird jede DML-Anweisung (INSERT, UPDATE und DELETE) als einzeilige Transaktion ausgeführt. Einzelne Zeilensperren werden ausgegeben. Somit können 50 DB-Verbindungen nach 50 verschiedenen Zeilen verlaufen, und es passiert nichts Tragisches.

Wo können Deadlocks hereinkommen?

Da der PRIMARY KEY von InnoDB-Tabellen im Clustered Index (intern als gen_clust_index bezeichnet) enthalten ist, sind die Zeilendaten eng mit den Indexeinträgen verbunden. Jeder Index, der für Spalten erstellt wird, die nicht Teil des PRIMARY KEY sind, wird mit zwei grundlegenden Elementen katalogisiert: 1) dem Spaltenwert und 2) dem Schlüssel gen_clust_index. Manchmal kann das Aktualisieren indizierter Spalten in InnoDB zu einer von mir im Scherz als Indexverstopfung bezeichneten Verstopfung führen. Dies tritt auf, wenn zwei oder mehr Sperren für nahe beieinander gespeicherte Indexeinträge generiert werden. Dies ist in einer stark frequentierten Website möglich.

Ich habe einmal einem Entwickler geholfen, herauszufinden, warum dies in DBA StackExchange passieren kann. Dieser Entwickler hat danach Codeänderungen vorgenommen. Hier waren diese Beiträge:

IHRE FRAGE

Eines der Updates geht unabhängig von der Storage Engine verloren. Nur das letzte UPDATE in einer Spalte legt den endgültigen Wert fest.

SCHLUSSFOLGERUNG

Dieser Beitrag bevorzugt weder Storage Engine. Dies sind einfach die Fakten darüber, was beim Schreiben auf Tabellen passieren kann und wird.

9
RolandoMySQLDBA