Crmgo Блог

MySQL, проблеми з реплікацією.

MySQL, проблеми з реплікацією.

При використанні MySQL Master-Slave (або ж Master-Master) реплікації буває ситуація, що з різних причин версія слейва нижча за версію мастера. Якщо при цьому використовується опція binlog_format=MIXED, в результаті можлива ситуація, коли мастер запише у свій binlog запис виду: BINLOG 'XMawShMEAAAARwAAAEp5UwUAAGkAAAAAAAAACHNhblahblahblah'…

MySQL, проблеми з реплікацією.

При використанні MySQL Master-Slave (або ж Master-Master) реплікації буває ситуація що з різних причин версія слейва нижча ніж версія мастера.
Якщо при цьому використовується опція binlog_format=MIXED, в результаті можлива ситуація коли мастер запише у свій binlog запис виду:
BINLOG 'XMawShMEAAAARwAAAEp5UwUAAGkAAAAAAAAACHNhblahblahblah'

Яку слейв не зможе виконати, бо він її просто “ще не вміє”.

Першою ластівкою того, що це сталося, стане повідомлення “SLAVE DOWN” від моніторингової системи та запис у MySQL-лозі слейва на кшталт цього:

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

Спроби пропустити небажані записи старим добрим методом:
slave stop;
set global sql_slave_skip_counter=1;
slave start;

у даному випадку не допомагають.

Як варіант рішення пропоную:
Зупиняємо slave: “SLAVE STOP;”
“Витягуємо” з тексту помилки ім'я бінлога та позицію, на якій сталася помилка.
У даному випадку це bin-us1.000022 та позиція 17007149
На мастері виконуємо запит “FLUSH LOGS;”
Робимо дамп бінлога починаючи зі знайденої позиції:
mysqlbinlog --start-position=17007149 bin-us1.000022 > bin-us1-from17007149.sql
Завантажуємо отриманий дамп на слейві з ключем “–force”
mysql --force -uuser -ppassword database < bin-us1-from17007149.sql
Виконуємо на слейві “FLUSH LOGS;”
У data-директорії знаходимо relay-log з максимальним номером і розміром близько 100 байт (у моєму випадку це mysqld-relay-bin.000037)
У тій самій директорії у файлі relay-log.info
перший рядок замінюємо на ім'я щойно знайденого relay-log-а, у другий вписуємо 0, у третій – наступний після “зіпсованого” бінлог, у четвертий – 0
Вийде щось на кшталт:
/var/lib/mysql/mysqld-relay-bin.000037
0
bin-us1.000023
0
Далі на слейві виконуємо:
CHANGE MASTER TO MASTER_LOG_FILE='bin-us1.000023', MASTER_LOG_POS=0;
SLAVE START;
Ну і потім щоб упевнитися що все “завелося”
SHOW SLAVE STATUS\G

Примітка: матеріал міг бути створений за підтримки ШІ з подальшою людською редакцією. Відповідальний за зміст: Dmytro Lomaka, Kaltenkirchen.