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 Пропуск транзакций без GTIDs
Для пропуска транзакций, которые завершаются ошибкой, когда GTIDs не используются или находятся в стадии ввода в действие (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-запросу.
Одна транзакция может содержать изменения в таблицах как с транзакциями, так и без них.
Когда вы используете оператор 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.