Detaillierte Erklärung des Parameters slave_exec_mode in MySQL

Detaillierte Erklärung des Parameters slave_exec_mode in MySQL

Heute habe ich zufällig den Parameter slave_exec_mode gesehen. Aus der Beschreibung im Handbuch weiß ich, dass dieser Parameter mit der MySQL-Replikation zusammenhängt und eine Variable ist, die dynamisch geändert werden kann. Der Standardmodus ist STRICT (strenger Modus) und der optionale Wert ist der IDEMPOTENT-Modus (idempotenter Modus). Durch Einstellen des Slaves auf den IDEMPOTENT-Modus können die Fehler 1032 (Schlüssel, der auf dem Slave nicht vorhanden ist) und 1062 (doppelter Schlüssel, Primärschlüssel oder eindeutiger Schlüssel muss vorhanden sein) verhindert werden. Dieser Modus ist nur im Binlog-Modus von ROW EVENT wirksam und im Binlog-Modus von STATEMENT EVENT ungültig. Der IDEMPOTENT-Modus wird hauptsächlich in Multi-Master-Replikations- und NDB CLUSTER-Situationen verwendet und wird in anderen Situationen nicht empfohlen. Aus der obigen Einführung geht hervor, dass dieser Parameter es der Slave-Bibliothek ermöglicht, die angegebenen Fehler zu überspringen. Die Frage lautet also:

1: Was sind die Vorteile im Vergleich zu sql_slave_skip_counter?

2: Was sind die Vorteile im Vergleich zu Slave-Skip-Errors = N?

Zu diesen beiden Fragen werden in diesem Artikel entsprechende Tests und Erklärungen durchgeführt.

Umfeld:

MySQL-Version: Percona MySQL 5.7

Replikationsmodus: ROW, GTID nicht aktiviert

prüfen:

① 1062 Fehler: Konnte nicht ausgeführt werden … Ereignis auf Tabelle db.x; Doppelter Eintrag „xx“ für Schlüssel „PRIMARY“, Fehlercode: 1062;

Testtabellenstruktur auf Master und Slave:

CREATE TABLE `x` (
 `id` int(11) NICHT NULL AUTO_INCREMENT,
 PRIMÄRSCHLÜSSEL (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

Tabelleneinträge auf dem Master und Slave:

M:

wähle * aus x;
+----+
|Ich würde|
+----+
| 2 |
| 3 |
+----+
2 Zeilen im Satz (0,01 Sek.)

S:

wähle * aus x;
+----+
|Ich würde|
+----+
| 1 |
| 2 |
| 3 |
+----+
3 Zeilen im Satz (0,00 Sek.)

Die Tabellendatensätze auf dem Master und dem Slave sind inkonsistent und der Datensatz mit der ID=1 fehlt auf dem Master.

Derzeit ist der Slave_exec_mode auf dem Slave der standardmäßige STRICT-Modus:

Variablen wie „slave_exec_mode“ anzeigen;
+-----------------+--------+
| Variablenname | Wert |
+-----------------+--------+
| Slave-Exec-Modus | STRENG |
+-----------------+--------+
1 Zeile im Satz (0,00 Sek.)

Der Binlog-Modus auf M ist:

Variablen wie „binlog_format“ anzeigen; +---------------+-------+
| Variablenname | Wert |
+---------------+-------+
| binlog_format | REIHE |
+---------------+-------+
1 Zeile im Satz (0,00 Sek.)

Auf M ausführen:

in x-Werte einfügen(1),(4),(5);
Abfrage OK, 3 Zeilen betroffen (0,00 Sek.)
Datensätze: 3 Duplikate: 0 Warnungen: 0

Da der Datensatz mit der ID=1 bereits auf dem Slave vorhanden ist, meldet die Slave-Replikation den Fehler 1062:

Last_SQL_Errno: 1062
Last_SQL_Error: Write_rows-Ereignis konnte für Tabelle dba_test.x nicht ausgeführt werden; Doppelter Eintrag „1“ für Schlüssel „PRIMARY“, Fehlercode: 1062; Handler-Fehler HA_ERR_FOUND_DUPP_KEY; Hauptprotokoll des Ereignisses mysql-bin-3306.000006, end_log_pos 7124

Wenn dieser Fehler auftritt, besteht der konsistente Ansatz darin, Folgendes auszuführen: sql_slave_skip_counter=N.

1. setze global sql_slave_skip_counter=N, wobei N bedeutet, dass N Ereignisse übersprungen werden
2. Merken Sie sich am besten: Wenn N auf 1 gesetzt ist, wird die nächste Transaktion übersprungen.
3. Wenn nach dem Überspringen des N-ten Ereignisses die Position zufällig in eine Transaktion fällt, wird die gesamte Transaktion übersprungen. 4. Ein Einfügen/Aktualisieren/Löschen entspricht nicht notwendigerweise nur einem Ereignis, das durch die Engine und das Protokollformat bestimmt wird.

Die Einheit von sql_slave_skip_counter ist „Ereignis“. Viele Leute denken, dass die Einheit dieses Parameters „Transaktion“ ist, was eigentlich falsch ist, da eine Transaktion mehrere Ereignisse enthält und das Überspringen von N Ereignissen immer noch in derselben Transaktion erfolgen kann. Beim oben genannten Fehler 1062 hat das Setzen von N auf 1 bis 4 den gleichen Effekt, nämlich das Überspringen einer Transaktion. Weil das ausgeführte SQL 4 Ereignisse generiert:

Binlog-Ereignisse in „mysql-bin-3306.000006“ ab 6950 anzeigen;
+-----------------------+------+------------+-----------+-------------+---------------------------------+
| Logname | Pos | Ereignistyp | Server-ID | End_log_pos | Info |
+-----------------------+------+------------+-----------+-------------+---------------------------------+
| mysql-bin-3306.000006 | 6950 | Abfrage | 169 | 7026 | BEGIN |
| mysql-bin-3306.000006 | 7026 | Table_map | 169 | 7074 | table_id: 707 (dba_test.x) |
| mysql-bin-3306.000006 | 7074 | Zeilen schreiben | 169 | 7124 | table_id: 707 Flags: STMT_END_F |
| mysql-bin-3306.000006 | 7124 | Xid | 169 | 7155 | COMMIT /* xid=74803 */ |
+-----------------------+------+------------+-----------+-------------+---------------------------------+
4 Zeilen im Satz (0,00 Sek.)

Die folgenden Möglichkeiten zur Behandlung dieses Fehlers sind:

1: skip_slavesql_slave_skip_counter

Slave stoppen; Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)
Setzen Sie den globalen sql_slave_skip_counter=[1-4];
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)
Slave starten;
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)

2: Geben Sie slave-skip-errors=1062 in der Konfigurationsdatei an (erfordert Neustart)

Beide Methoden können die Replikation wieder normalisieren, verursachen jedoch Inkonsistenzen zwischen den Master- und Slave-Daten (mit Vorsicht verwenden), wodurch die Slave-Datenbank Datensätze mit den IDs 4 und 5 verliert. Und auch die zweite Methode erfordert einen Neustart der Datenbank. An diesem Punkt ist der in diesem Artikel vorgestellte Parameter slave_exec_mode praktisch. Legen Sie diesen Parameter in der Slave-Bibliothek fest:

Setzen Sie den globalen Slave_exec_mode='IDEMPOTENT'.
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)
Slave stoppen; Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)
Slave starten;
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)

Führen Sie es auch auf dem Master aus:

in x-Werte einfügen(1),(4),(5);

Es ist überraschend, dass die Master- und Slave-Daten synchronisiert sind und keine Replikationsanomalien vorliegen:

M:
wähle * aus x; +----+
|Ich würde|
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
5 Zeilen im Satz (0,00 Sek.)

S:
wähle * aus x; +----+
|Ich würde|
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+----+
5 Zeilen im Satz (0,01 Sek.)

Aus dem obigen Test können wir ersehen, dass nach dem Setzen des Parameters auf slave_exec_mode='IDEMPOTENT' ein Fehlerereignis übersprungen werden kann.

② 1032-Fehler: Konnte nicht ausgeführt werden … Ereignis in Tabelle db.x; Datensatz in „x“ nicht gefunden, Fehlercode: 1032;

Dieser Fehler tritt auf, weil die Replikation im ROW-Modus strenge Anforderungen an die Datenkonsistenz stellt.

Testtabellenstruktur auf Master und Slave:

CREATE TABLE `x` (
 `id` int(11) NICHT NULL AUTO_INCREMENT,
 PRIMÄRSCHLÜSSEL (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8

Tabelleneinträge auf dem Master und Slave:

M:

wähle * aus x; +----+
|Ich würde|
+----+
| 1 |
| 2 |
| 3 |
+----+
3 Zeilen im Satz (0,00 Sek.)

S:

wähle * aus x;
+----+
|Ich würde|
+----+
| 1 |
| 3 |
+----+
2 Zeilen im Satz (0,00 Sek.)

Die Tabellendatensätze auf dem Master und dem Slave sind inkonsistent und der Datensatz mit der ID=2 fehlt auf dem Slave. Derzeit ist der Slave_exec_mode auf dem Slave der standardmäßige STRICT-Modus:

Variablen wie „slave_exec_mode“ anzeigen;
+-----------------+--------+
| Variablenname | Wert |
+-----------------+--------+
| Slave-Exec-Modus | STRENG |
+-----------------+--------+
1 Zeile im Satz (0,00 Sek.)

Der Binlog-Modus auf M ist:

Variablen wie „binlog_format“ anzeigen; +---------------+-------+
| Variablenname | Wert |
+---------------+-------+
| binlog_format | REIHE |
+---------------+-------+
1 Zeile im Satz (0,00 Sek.)

Auf M ausführen:

BEGINNEN;
EINFÜGEN IN x AUSWÄHLEN 4;
LÖSCHEN VON x, WO id = 2;
EINFÜGEN IN x AUSWÄHLEN 5;
BEGEHEN;

Da der Datensatz mit der ID=2 auf dem Slave nicht existiert, meldet die Slave-Replikation den Fehler 1032:

Last_SQL_Errno: 1032
Last_SQL_Error: Das Ereignis „Delete_rows“ konnte für die Tabelle „dba_test.x“ nicht ausgeführt werden. Datensatz in „x“ kann nicht gefunden werden. Fehlercode: 1032. Handler-Fehler HA_ERR_KEY_NOT_FOUND. Das Hauptprotokoll des Ereignisses lautet mysql-bin-3306.000006, end_log_pos 12102.

Ebenso können die beiden im obigen Test beschriebenen Methoden dazu führen, dass die Replikation funktioniert, die Daten gehen jedoch verloren. Die Datensätze mit den IDs 4 und 5 gehen verloren. Fahren Sie mit der Parametereinstellung in der Slave-Bibliothek fort:

Setzen Sie den globalen Slave_exec_mode='IDEMPOTENT'.
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)
Slave stoppen; Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)
Slave starten;
Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)

Machen Sie dasselbe auf M:

BEGINNEN;
EINFÜGEN IN x AUSWÄHLEN 4;
LÖSCHEN VON x, WO id = 2;
EINFÜGEN IN x AUSWÄHLEN 5;
BEGEHEN;

Möglicherweise werden Sie auch angenehm überrascht sein, dass die Master-Slave-Daten synchronisiert sind und keine Replikationsanomalien auftreten.

Hinweis: slave_exec_mode='IDEMPOTENT' kann DDL-Operationen nicht idempotent machen und kann auch keine durch unterschiedliche Feldlängen verursachten Fehler idempotent machen, wie etwa das Ändern des ID-Feldtyps der Slave-Tabelle im Beispiel von int in bigint. Es kann nur verwendet werden, wenn binlog_format im ROW-Modus ist, und kann nur im idempotenten Modus für 1032 und 1062 verwendet werden.

Zusammenfassen:

Für die obige Testzusammenfassung gilt, dass für den Parameter slave_exec_mode die Fehler 1062 und 1032 übersprungen werden können und die normale Datenausführung in derselben Transaktion nicht beeinträchtigt wird. Wenn die Transaktion aus mehreren SQL-Anweisungen besteht, kann das problematische Ereignis übersprungen werden.

Dieser Parameter sieht gut aus, aber im Handbuch heißt es, dass seine Aktivierung in einer normalen Replikationsumgebung nicht empfohlen wird. Für andere Speicher-Engines als NDB sollte der IDEMPOTENT-Modus nur verwendet werden, wenn Sie sicher sind, dass Fehler aufgrund doppelter Schlüssel und fehlender Schlüssel ignoriert werden können. Dieser Parameter ist speziell für NBD-Cluster vorgesehen. Im NBD-Clustermodus kann dieser Parameter nur auf den IDEMPOTENT-Modus eingestellt werden. Sie müssen also basierend auf Ihrem eigenen Anwendungsszenario entscheiden. Unter normalen Umständen sind Master und Slave konsistent und jeder Fehler wird gemeldet. Bei speziellen Verarbeitungen kann es jedoch vorübergehend aktiviert werden.

Darüber hinaus wird sql_slave_skip_counter bei der Replikation im GTID-Modus nicht unterstützt. Die Replikation in diesem Modus können Sie selbst testen.

Das könnte Sie auch interessieren:
  • Optimierungsmethode für das MySQL-Synchronisierungsproblem mit großer Slave-Verzögerung
  • Grundlegendes Tutorial zum Lösen von Slave-Latenzproblemen in MySQL
  • Analyse von Verzögerungen bei der Slave-Überwachung in MySQL
  • MySQL Master-Slave-Daten sind inkonsistent, Eingabeaufforderung: Slave_SQL_Running: Keine Lösung
  • Ein praktischer Bericht über die Wiederherstellung einer MySQL Slave-Bibliothek
  • Konfiguration der MySQL-Master/Slave-Datenbanksynchronisierung und häufige Fehler
  • Installations- und Konfigurationsdetails zur Master-Slave-Synchronisierung der MySQL5.6-Datenbank (Master/Slave)
  • Lösung für MySQL Slave, der Oom-Killer auslöst
  • MySQL-Slave verzögert die Fremdschlüsselprüfung und die automatische Inkrementsperre für eine Spalte

<<:  Detaillierte Erklärung der Verwendung der Compose-Funktion und der Pipe-Funktion in JS

>>:  8 Beispiele für die Verwendung des Killall-Befehls zum Beenden von Prozessen in Linux

Artikel empfehlen

JavaScript implementiert Produktdetails der E-Commerce-Plattform

In diesem Artikel wird ein allgemeines Beispiel f...

Richtige Schritte zur Installation von Nginx unter Linux

Vorwort Wenn Sie wie ich ein fleißiger Java-Backe...

Detaillierte Erklärung zur Verwendung von Scoped Slots in Vue.js-Slots

Inhaltsverzeichnis Keine Slots Vue2.x-Steckplätze...

Eine detaillierte Einführung in den wget-Befehl in Linux

Inhaltsverzeichnis Installieren Sie zuerst wget H...

Vue implementiert eine einfache Timer-Komponente

Bei der Durchführung eines Projekts stößt man unw...

Warum wird in MySQL keine UTF-8-Kodierung verwendet?

MySQL UTF-8-Kodierung MySQL unterstützt UTF-8 sei...

Einführung in ApplicationHost.config (IIS-Speicherkonfigurationsbereichsdatei)

Nehmen Sie für eine neu erstellte Website ASP.NET...

Detaillierte Erklärung zur Überwachung von MySQL-Anweisungen

Schnelles Lesen Warum müssen wir SQL-Anweisungen ...

So verwenden Sie Docker zum Erstellen eines privaten pypi-Repositorys

1. Konstruktion 1. Bereiten Sie die Datei htpassw...

MYSQL Eine Frage zur Verwendung von Zeichenfunktionen zum Filtern von Daten

Problembeschreibung: Struktur: test hat zwei Feld...

MySQL-Fehlernummer 1129 – Lösung

SQLyog stellt eine Verbindung zu MySQL her, Fehle...

HTML-Tutorial, HTML-Standardstil

html , Adresse , Blockzitat , Text , dd , div , d...