MySQL: Slave could not parse relay log event entry

Рубрика: Development, MySQL | 17 September 2009, 10:09 | Vadim Voituk

При использованиии 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;

в данном случае не помогают.

Как вариант решения предлагаю:

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

Должно работать.
Подозреваю что пункты 4 и 5 можно обьеденить в один, более простой и элегантный.
Но как это сделать – не гуглил.

Комментариев: 8

8 Responses to “MySQL: Slave could not parse relay log event entry”

Комментарии:

  1. Andy

    Так?
    mysqlbinlog –start-position=17007149 bin-us1.000022 | mysql –force -uuser -ppassword database

  2. disserman

    она еще и слетает без видимых причин периодически. ставьте Oracle, mysql игрушки для студентов

  3. Vadim Voituk

    Andy,
    Можно и так, если есть доступ с мастера на слейв (только с указанием -hslave.host.com)

    disserman,
    Мне еще не хватало решать проблемы с Ораклом, какой тоже без видимых причин слетает.

  4. crypto5

    Оракл конечно крутая база, но и денег она хочет тоже очень не мало.

  5. Владимир Бутков

    Спасибо, за три дня выбило слейв 2 раза, причем первый раз пришлось останавливать базу и копировать всё на слейв.Понятно, начальство было недовольно! Провел операции по Вашей подсказке- все работает!!!!Респект и уважуха!=))))

  6. Vladimir

    Спасибо за инструкцию!
    Но ведь каждый раз не будешь так делать.
    Тогда получается поставить лучше binlog_format=STATEMENT
    ?

  7. Vadim Voituk

    А у вас часто происходит разсинхронизация версий MySQL?
    Если да, то наверное надо делать не так как написано, а исправлять что-то более глобально.

  8. сисадмин

    По-моему, иметь на слейве версию ниже мастера – это всё равно, что сидеть на пороховой бочке. Даже мануалы на dev.mysql.com очень не рекомендуют так делать. Предыдущим комментаторам, постоянно наступающим на одни и те же грабли, я бы посоветовал один раз построить заново слейв с правильной версией mysql и спать дальше спокойно. Тем более, что слейв можно сделать на лету без какого-либо downtime-а на master-е.

Leave a Reply