Bei der Verwendung von MySQL Master-Slave- (oder Master-Master-) Replikation kommt es manchmal vor, dass die Version des Slaves aus verschiedenen Gründen niedriger ist als die des Masters.
Wenn dabei die Option binlog_format=MIXED verwendet wird, kann es dazu kommen, dass der Master einen Eintrag in seinem Binärprotokoll (binlog) in folgender Form schreibt:
BINLOG 'XMawShMEAAAARwAAAEp5UwUAAGkAAAAAAAAACHNhblahblahblah'
Diesen Eintrag kann der Slave nicht ausführen, da er diese Funktionalität noch nicht unterstützt.
Das erste Anzeichen dafür, dass dies geschehen ist, ist die Meldung „SLAVE DOWN“ des Monitoring-Systems sowie ein Eintrag im MySQL-Log des Slaves, der diesem ähnelt:
090917 14:55:51 [ERROR] Error in Log_event::read_log_event(): 'Found invalid event in binary log', data_len: 71, event_type: 19
090917 14:55:51 [ERROR] Error reading relay log event: slave SQL thread aborted because of I/O error
090917 14:55:51 [ERROR] Slave: Could not parse relay log event entry. The possible reasons are: the master's binary log is corrupted (you can check this by running 'mysqlbinlog' o
n the binary log), the slave's relay log is corrupted (you can check this by running 'mysqlbinlog' on the relay log), a network problem, or a bug in the master's or slave's MySQL
code. If you want to check the master's binary log or slave's relay log, you will be able to know their names by issuing 'SHOW SLAVE STATUS' on this slave. Error_code: 0
090917 14:55:51 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'bin-us1.000022' position 17007149
Versuche, unerwünschte Einträge mit der bewährten Methode zu überspringen:
slave stop;
set global sql_slave_skip_counter=1;
slave start;
helfen in diesem Fall nicht.
Als Lösungsvorschlag empfehle ich Folgendes:
Stoppen Sie den Slave: „SLAVE STOP;“
„Entnehmen“ Sie dem Fehlertext den Namen des Binärprotokolls und die Position, an der der Fehler auftrat.
In diesem Fall sind dies bin-us1.000022 und die Position 17007149.
Führen Sie auf dem Master die Abfrage „FLUSH LOGS;“ aus.
Erstellen Sie einen Dump des Binärprotokolls beginnend mit der gefundenen Position:
mysqlbinlog --start-position=17007149 bin-us1.000022 > bin-us1-from17007149.sql
Laden Sie den erstellten Dump auf dem Slave mit dem Parameter „–force“:
mysql --force -uuser -ppassword database < bin-us1-from17007149.sql
Führen Sie auf dem Slave „FLUSH LOGS;“ aus.
Suchen Sie im data-Verzeichnis nach der Relay-Log-Datei mit der höchsten Nummer und einer Größe von etwa 100 Byte (in meinem Fall ist dies mysqld-relay-bin.000037).
Ersetzen Sie in der Datei relay-log.info im selben Verzeichnis die erste Zeile durch den Namen der gerade gefundenen Relay-Log-Datei, schreiben Sie in die zweite Zeile eine 0, in die dritte Zeile den Namen des Binärprotokolls, das auf das „beschädigte“ folgt, und in die vierte Zeile eine 0.
Das Ergebnis sieht etwa so aus:
/var/lib/mysql/mysqld-relay-bin.000037
0
bin-us1.000023
0
Führen Sie anschließend auf dem Slave Folgendes aus:
CHANGE MASTER TO MASTER_LOG_FILE='bin-us1.000023', MASTER_LOG_POS=0;
SLAVE START;
Und um sicherzustellen, dass alles wieder funktioniert:
SHOW SLAVE STATUS\G
