Skip to content


Ошибка mysql: Got fatal error 1236 from master

После аварийного рестарта mysql-сервера, исполняющего роль master-а, на slave-е вылезла вот такая проблемка:

[ERROR] Slave I/O: Got fatal error 1236 from master when reading data from binary log: 'Client requested master to start replication from position > file size', Error_code: 1236

Ну и процесс репликации, естественно, остановился.

Как можно догадаться из сообщения об ошибке, slave захотел выполнить команды из такого места бинлога, которого на мастере не оказалось после рестарта последнего (наверное, потому, что часть бинлога не успела записаться на диск мастера за мгновение до того, как он был перезагружен по питанию).

Смотрим позицию, до которой дошел slave:

[slave]$ echo "show slave status \G" | mysql | grep -E "[[:space:]]Master_Log_File|Read_Master_Log_Pos"
  Master_Log_File: s10-bin.000253
  Exec_Master_Log_Pos: 783374391

Смотрим последнюю позицию, которая реально присутствует в этом бинлоге мастера:

[master]$ mysqlbinlog s10-bin.000253 | tail -n 9
/*!*/;
# at 783367615
#150704 18:12:45 server id 62 end_log_pos 783367646 CRC32 0x2be04f67 Xid = 22088173
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

И видим, что последняя позиция - 783367646. В то время как slave пытается исполнить позицию 783374391, которая, очевидно, дальше, чем 783367646. Вывод – надо "отмотать" slave немного назад:

[slave] mysql> stop slave;
[slave] mysql> change master to master_log_pos=783367646;
[slave] mysql> start slave;

В логе видим:

[Note] 'CHANGE MASTER TO executed'. Previous state master_host='10.10.10.10', master_port= 3306, master_log_file='s10-bin.000253', master_log_pos=783374391, master_bind=''. New state master_host='10.10.10.10', master_port= 3306, master_log_file='s10-bin.000253', master_log_pos=783367646, master_bind=''.
[Note] Slave I/O thread: connected to master '[email protected]:3306',replication started in log 's10-bin.000253' at position 783367646

Ну и далее show slave status нам говорит, что slave начал догонять master.

Happy end.

P.S. Альтерантивным вариантом посмотреть бинлог является команда SHOW BINLOG EVENTS. Например:

mysql> show binlog events in 's9-bin.000125' from 24084942 limit 10;
+---------------+----------+-------------+-----------+-------------+------------------+
| Log_name      | Pos      | Event_type  | Server_id | End_log_pos | Info             |
+---------------+----------+-------------+-----------+-------------+------------------+
| s9-bin.000125 | 24084942 | Write_rows  |         8 |    24085025 | table_id: 244461 |
| s9-bin.000125 | 24085025 | Update_rows |         8 |    24086045 | table_id: 244461 |
| s9-bin.000125 | 24086045 | Write_rows  |         8 |    24086128 | table_id: 244461 |
| s9-bin.000125 | 24086128 | Update_rows |         8 |    24086518 | table_id: 244461 |
| s9-bin.000125 | 24086518 | Write_rows  |         8 |    24086600 | table_id: 244461 |
| s9-bin.000125 | 24086600 | Update_rows |         8 |    24086876 | table_id: 244461 |
| s9-bin.000125 | 24086876 | Write_rows  |         8 |    24087008 | table_id: 244461 |
| s9-bin.000125 | 24087008 | Update_rows |         8 |    24087138 | table_id: 244461 |
| s9-bin.000125 | 24087138 | Write_rows  |         8 |    24087221 | table_id: 244461 |
| s9-bin.000125 | 24087221 | Update_rows |         8 |    24087611 | table_id: 244461 |
+---------------+----------+-------------+-----------+-------------+------------------+
10 rows in set (0.00 sec)

Posted in Howto.

Tagged with , .


6 Responses

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. buggy says

    Но ведь при переключении слейва на позицию в прошлом, разница между позициями будет записана повторно, что вызовет Duplicate entry.

  2. Admin says

    buggy, в данном случае не будет она записана повторно. Потому что на мастере кусок бинлога n потерялся с конца. После ребута мастер начинает новый бинлог n+1. Слейв в старом бинлоге выполнит тольку одну позицию 783367646 и перескочит на следующий бинлог, данных из которого он еще не выполнял.

    То есть слейв выполнит только одну 783367646, а не разницу между 783367646 и 783374391.

  3. buggy says

    Admin, спасибо. Если лог действительно был поврежден и записи потерялись, тогда да.

  4. Петровский says

    Кстати, если тип репликации row-based (по умолчанию mixed), то чтобы увидеть SQL-операторы, нужно для mysqlbinlog добавить опции --base64-output=DECODE-ROWS --verbose

  5. Петровский says

    Заметил прикольную фичу - если на слейве поменять тип репликации (например, добавив в my.cnf binlog_format = row), то мастер автоматически подстраивается, меняя у себя тоже на тот же тип.

  6. Василий says

    Петровский, да реально так и есть.

You must be logged in to post a comment.