Неоднократно приходилось восстанавливать репликацию базы данных MySQL/MariaDB, теперь записываю в инструкцию чтобы при столкновении с аналогичной задачей был исчерпывающий справочник.
Инструкция не окончательная и будет дополняться по мере обнаружения новых проблем или вариантов решения.
Для начала узнаем статус репликации на реплицируемой ноде:
SHOW SLAVE STATUS \G;
В документации приведен пример вывода и описаны данные. Нас интересует следующее:
Last_Error
- текстовое описание ошибкиRelay_Master_Log_File
- название файла binlog
Exec_Master_Log_Pos
- позиция начала проблемной записи в файле binlog
, из которого можно взять эту записьУзнать файловый путь хранения binlog на master-ноде
:
SELECT @@GLOBAL.log_bin_basename
У нас есть описание, название файла бинлога с проблемным запросом и начальное смещение, теперь нам нужно понять ошибку и исправить.
Если в Last_Error
есть что-то подобное, то это значит что команда просто не смогла выполниться:
Could not execute Update_rows_v1 event on table my_database.my_table; ...
Error_code 1032; handler error HA_ERR_END_OF_FILE;
the event's master log mysql-bin.012563, end_log_pos 5491403
Вытаскиваем из binlog на master-ноде
информацию о неудачной операции и записываем в файл:
$ sudo mysqlbinlog -v \
--start-position=5490888 \
--stop-position=5491403 \
/var/log/mysql/mysql-bin.110157 > temp.log
Здесь:
--start-position
из Exec_Master_Log_Pos
--stop-position
из Last_Error
(где end_log_pos
)/var/log/mysql/mysql-bin.110157
первую часть можно узнать на мастер ноде, а вторую часть берем либо из Last_Error
либо из Relay_Master_Log_File
Теперь открываем файл temp.log
, идем до раздела BEGIN
и находим запрос с имитированным приглашением ввода #Q>
:
BEGIN
/*!*/;
# at 5491100
# at 5491403
#231114 9:10:57 server id 10 end_log_pos 5491350 CRC32 0x653ee440 Annotate_rows:
#Q> UPDATE my_database.my_table t SET t.status = 'checking' WHERE t.id = 22
#231114 9:10:57 server id 10 end_log_pos 5491403 CRC32 0xe4c8ce40 Table_map: `my_database`.`my_table` mapped to number 27560
Выполняем запрос на реплике.
Теперь имея синхронное состояние master-ноды
и реплики на момент выполнения этого запроса, нужно запустить репликацию (имея SUPER права):
STOP SLAVE; SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; START SLAVE;
Смотрим еще раз статус репликации и убеждаемся что она запустилась.
Репликация может часто падать из-за отсутствия primary key в таблицах.
Если в Last_Error
есть упоминание Lock wait
без каких либо подробностей, то это говорит о том что во время выполнения запроса на реплике возникли deadlock'и.
Скорее всего перезапуск репликации поможет:
STOP SLAVE; START SLAVE;