19.1.7.3 Пропуск транзакций
Если репликация прервана из-за проблемы с событием в реплицированной транзакции, вы можете возобновить репликацию, пропустив ошибочную транзакцию на реплике. Перед пропуском транзакции убедитесь, что поток ввода/вывода репликации (приёмник) и поток SQL (применитель) остановлены.
Сначала необходимо определить реплицированное событие, вызвавшее ошибку. Подробности об ошибке и последней успешно применённой транзакции записываются в таблицу Performance Schema replication_applier_status_by_worker. Вы можете использовать mysqlbinlog для получения и отображения событий, которые были записаны около времени возникновения ошибки. Инструкции по этому вопросу см. в разделе 9.5 «Восстановление по состоянию на определённый момент времени (инкрементное)». В качестве альтернативы, вы можете выполнить SHOW RELAYLOG EVENTS на реплике или SHOW BINLOG EVENTS на источнике.
Перед пропуском транзакции и перезапуском реплики проверьте следующие моменты:
Является ли транзакция, которая остановила репликацию, из неизвестного или недоверенного источника? Если да, проверьте причину, чтобы убедиться, что нет каких-либо соображений безопасности, которые указывают, что реплика не должна перезапускаться.
Нужно ли применить транзакцию, которая остановила репликацию, на реплике? Если да, либо внесите необходимые исправления и повторно примените транзакцию, либо вручную согласуйте данные на реплике.
Нужно ли применить транзакцию, которая остановила репликацию, на источнике? Если нет, отмены транзакцию вручную на сервере, где она первоначально произошла.
Для пропуска транзакции выберите один из следующих методов:
Если используются GTID (
gtid_modeравноON), см. раздел 19.1.7.3.1 «Пропуск транзакций с использованием GTID».Если GTID не используются или внедряются (
gtid_modeравноOFF,OFF_PERMISSIVEилиON_PERMISSIVE), см. раздел 19.1.7.3.2 «Пропуск транзакций без использования GTID».Если вы включили назначение GTID на канале репликации, используя параметр
ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONSоператораCHANGE REPLICATION SOURCE TO, см. раздел 19.1.7.3.2 «Пропуск транзакций без использования GTID». ИспользованиеASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONSна канале репликации не то же самое, что введение репликации, основанной на GTID, для канала, и вы не можете использовать метод пропуска транзакций для репликации на основе GTID с такими каналами.
Для перезапуска репликации после пропуска транзакции выполните оператор START REPLICA с клаузой FOR CHANNEL, если реплика является репликой с несколькими источниками.
19.1.7.3.1 Пропуск транзакций с использованием GTID
Если используются GTID (gtid_mode равно ON), GTID для завершённой транзакции сохраняется на реплике, даже если содержимое транзакции отфильтровано. Это свойство предотвращает получение репликой ранее отфильтрованных транзакций при повторном подключении к источнику с помощью автоматического позиционирования по GTID. Также его можно использовать для пропуска транзакции на реплике, выполнив пустую транзакцию вместо ошибочной транзакции.
Этот метод пропуска транзакций не подходит, если вы включили назначение GTID на канале репликации с помощью параметра ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS оператора CHANGE REPLICATION SOURCE
TO.
Если ошибочная транзакция сгенерировала ошибку в потоке обработчика, её GTID можно получить напрямую из поля APPLYING_TRANSACTION в таблице Performance Schema replication_applier_status_by_worker. Чтобы увидеть, что представляет собой транзакция, выполните SHOW RELAYLOG EVENTS на реплике или SHOW BINLOG
EVENTS на источнике и найдите в выводе транзакцию, предваряемую этим GTID.
После оценки ошибочной транзакции на предмет других необходимых действий (таких как соображения безопасности) для пропуска транзакции выполните пустую транзакцию на реплике, имеющую тот же GTID, что и ошибочная транзакция. Например:
SET GTID_NEXT='aaa-bbb-ccc-ddd:N';
BEGIN;
COMMIT;
SET GTID_NEXT='AUTOMATIC';
Наличие этой пустой транзакции на реплике означает, что при выполнении оператора START
REPLICA для перезапуска репликации реплика использует функцию автоматического пропуска для игнорирования ошибочной транзакции, поскольку она видит, что транзакция с этим GTID уже применена. Если реплика является репликой с несколькими источниками, вам не нужно указывать имя канала при выполнении пустой транзакции, но вам нужно указать имя канала при выполнении START
REPLICA.
Обратите внимание, что если на этой реплике используется двоичное протоколирование, пустая транзакция попадает в поток репликации, если реплика становится источником или главным в будущем. Если вам нужно избежать этой возможности, рассмотрите возможность очистки и удаления двоичных журналов реплики, как в этом примере:
FLUSH LOGS;
PURGE BINARY LOGS TO 'binlog.000146';
GTID пустой транзакции сохраняется, но сама транзакция удаляется путём очистки двоичных файлов журнала.
19.1.7.3.2 Пропуск транзакций без GTID
Для пропуска транзакций с ошибками, когда GTID не используются или внедряются постепенно (gtid_mode имеет значение OFF, OFF_PERMISSIVE или ON_PERMISSIVE), можно пропустить указанное количество событий, выполнив SET GLOBAL
sql_replica_skip_counter. В качестве альтернативы, можно пропустить событие или события, выполнив оператор CHANGE REPLICATION SOURCE TO для перемещения позиции исходного двоичного журнала вперёд.
Эти методы также подходят, когда вы включили назначение GTID на канале репликации с помощью опции ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS оператора CHANGE REPLICATION SOURCE
TO.
При использовании этих методов важно понимать, что вы не обязательно пропускаете полную транзакцию, как это всегда происходит с методом, основанным на GTID, описанным ранее. Эти методы, не основанные на GTID, не знают о транзакциях как таковых, а вместо этого работают с событиями. Двоичный журнал организован как последовательность групп, известных как группы событий, а каждая группа событий состоит из последовательности событий.
Для таблиц с транзакциями группа событий соответствует транзакции.
Для не транзакционных таблиц группа событий соответствует одному SQL-запросу.
Хотя одна транзакция может содержать изменения как в транзакционных, так и в не транзакционных таблицах, поддержка таких транзакций устарела, и вы должны ожидать её удаления в будущих версиях MySQL. См. Раздел 19.5.1.36, «Репликация и транзакции». Некоторые причины этой устарелости см. в Раздел 19.1.3.7, «Ограничения репликации с GTID».
Когда вы используете оператор SET GLOBAL
sql_replica_skip_counter для пропуска событий, и полученная позиция находится в середине группы событий, реплика продолжает пропускать события до достижения конца группы. Затем выполнение начинается с следующей группы событий. У оператора CHANGE REPLICATION SOURCE
TO такой функции нет, поэтому нужно быть внимательным, чтобы определить правильное место для перезапуска репликации в начале группы событий. Однако, использование CHANGE REPLICATION SOURCE TO означает, что вам не нужно подсчитывать события, которые нужно пропустить, как это нужно с SET GLOBAL
sql_replica_skip_counter, а вместо этого вы можете указать место для перезапуска.
19.1.7.3.2.1 Пропуск транзакций с SET GLOBAL
sql_replica_skip_counter
После того, как вы оценили неисправную транзакцию на предмет других соответствующих действий (таких как соображения безопасности), подсчитайте количество событий, которые нужно пропустить. Одно событие обычно соответствует одному SQL-запросу в двоичном журнале, но обратите внимание, что запросы, использующие AUTO_INCREMENT или LAST_INSERT_ID(), учитываются как два события в двоичном журнале. При использовании сжатия транзакций двоичного журнала, сжатый фрагмент транзакции (Transaction_payload_event) учитывается как одно значение счётчика, поэтому все события внутри него пропускаются как единое целое.
Если вы хотите пропустить всю транзакцию, вы можете подсчитать события до конца транзакции или просто пропустить соответствующую группу событий. Помните, что с SET
GLOBAL sql_replica_skip_counter, реплика продолжает пропуск до конца группы событий. Убедитесь, что вы не пропускаете слишком далеко и не попадаете в следующую группу событий или транзакцию, чтобы она тоже не была пропущена.
Выполните оператор SET следующим образом, где N - количество событий из источника, которые нужно пропустить:
SET GLOBAL sql_replica_skip_counter = N
Этот оператор не может быть выполнен, если gtid_mode=ON установлено или если потоки репликации ВВОД/ВЫВОД (получатель) и SQL (применитель) работают.
Оператор SET GLOBAL sql_replica_skip_counter не имеет немедленного эффекта. При выполнении оператора START REPLICA в следующий раз после этого оператора SET, новое значение системной переменной sql_replica_skip_counter применяется, и события пропускаются. Данный оператор START REPLICA также автоматически устанавливает значение системной переменной обратно в 0. Если реплика является репликой с несколькими источниками, при выполнении оператора START REPLICA, необходим пункт FOR CHANNEL. Убедитесь, что вы указываете правильный канал, иначе события пропускаются на неправильном канале.
19.1.7.3.2.2 Пропуск транзакций с CHANGE REPLICATION SOURCE TO
После оценки неисправной транзакции на предмет других подходящих действий (таких как соображения безопасности), найдите координаты (файл и позицию) в двоичном журнале источника, представляющие подходящую позицию для перезапуска репликации. Это может быть начало группы событий, следующей за событием, вызвавшим проблему, или начало следующей транзакции. Поток репликации ВВОД/ВЫВОД (получатель) начинает чтение из источника по этим координатам в следующий раз при запуске потока, пропуская неисправное событие. Убедитесь, что вы точно определили позицию, потому что этот оператор не учитывает группы событий.
Выполните оператор CHANGE REPLICATION SOURCE
TO следующим образом, где source_log_name - файл двоичного журнала, содержащий позицию перезапуска, а source_log_pos - число, представляющее позицию перезапуска, как указано в файле двоичного журнала:
CHANGE REPLICATION SOURCE TO SOURCE_LOG_FILE='source_log_name', SOURCE_LOG_POS=source_log_pos;
Если реплика является репликой с несколькими источниками, необходимо использовать пункт FOR CHANNEL для указания соответствующего канала в операторе CHANGE
REPLICATION SOURCE TO.
Этот оператор не может быть выполнен, если SOURCE_AUTO_POSITION имеет значение 1, или если потоки репликации ВВОД/ВЫВОД (получатель) и SQL (применитель) работают. Если необходимо использовать этот метод пропуска транзакции, когда SOURCE_AUTO_POSITION=1, можно изменить это значение на SOURCE_AUTO_POSITION=0 при выполнении оператора, а затем вернуть его обратно.
CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION=0, SOURCE_LOG_FILE='binlog.000145', SOURCE_LOG_POS=235;
CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION=1;
© 2025 Oracle
Licensed under the GPLv2 License.