Při použití replikace MySQL Master-Slave (nebo Master-Master) se může stát, že z různých důvodů je verze slave nižší než verze master.
Pokud je přitom použita možnost binlog_format=MIXED, může dojít k situaci, kdy master zapíše do svého binlog záznam ve tvaru:
BINLOG 'XMawShMEAAAARwAAAEp5UwUAAGkAAAAAAAAACHNhblahblahblah'
Kterou slave nebude schopen provést, protože ho prostě „ještě neumí“.
Prvním signálem, že k tomu došlo, bude zpráva „SLAVE DOWN“ od monitorovacího systému a záznam v logu MySQL slave podobný tomuto:
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
Pokusy o přeskočení nepřípustných záznamů starou osvědčenou metodou:
slave stop;
set global sql_slave_skip_counter=1;
slave start;
v tomto případě nepomáhají.
Jako řešení navrhuji:
Zastavíme slave: „SLAVE STOP;“
Z textu chyby „vytáhneme“ jméno binlogu a pozici, na které došlo k chybě.
V tomto případě je to bin-us1.000022 a pozice 17007149
Na masteru provedeme dotaz „FLUSH LOGS;“
Vytvoříme dump binlogu počínaje nalezenou pozicí:
mysqlbinlog --start-position=17007149 bin-us1.000022 > bin-us1-from17007149.sql
Na slave načteme získaný dump s přepínačem „–force“
mysql --force -uuser -ppassword database < bin-us1-from17007149.sql
Na slave provedeme „FLUSH LOGS;“
V data-adresáři najdeme relay-log s maximálním číslem a velikostí kolem 100 bajtů (v mém případě je to mysqld-relay-bin.000037)
Ve stejném adresáři v souboru relay-log.info
první řádek nahradíme jménem právě nalezeného relay-logu, do druhého zapíšeme 0, do třetího – následující binlog po „poškozeném“ a do čtvrtého – 0
Výsledek bude vypadat nějak takto:
/var/lib/mysql/mysqld-relay-bin.000037
0
bin-us1.000023
0
Dále na slave provedeme:
CHANGE MASTER TO MASTER_LOG_FILE='bin-us1.000023', MASTER_LOG_POS=0;
SLAVE START;
A pak pro ověření, že vše „naběhlo“
SHOW SLAVE STATUS\G
