Spec-Zone.ru › MySQL 5.7

16.1.7.3 Пропуск транзакций

  • 16.1.7.3.1 Пропуск транзакций с GTID
  • 16.1.7.3.2 Пропуск транзакций без GTID

Если репликация прервалась из-за проблемы с событием в реплицируемой транзакции, вы можете возобновить репликацию, пропустив ошибочную транзакцию на реплике. Перед пропуском транзакции убедитесь, что репликационный I/O-поток и репликационный SQL-поток остановлены.

Сначала необходимо определить реплицированное событие, вызвавшее ошибку. Сведения об ошибке и последней успешно применённой транзакции записываются в таблицу Performance Schema replication_applier_status_by_worker. Вы можете использовать mysqlbinlog для извлечения и отображения событий, которые были записаны около времени ошибки. Инструкции по этому вопросу см. в разделе 7.5, «Восстановление по состоянию на определённую точку времени (инкрементное)». В качестве альтернативы вы можете выполнить SHOW RELAYLOG EVENTS на реплике или SHOW BINLOG EVENTS на источнике.

Перед пропуском транзакции и перезапуском реплики проверьте следующие моменты:

  • Является ли транзакция, прервавшая репликацию, из неизвестного или недоверенного источника? Если да, проверьте причину, на случай, если есть какие-либо соображения безопасности, которые указывают на то, что реплику не следует перезапускать.

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

  • Нужно ли применять транзакцию, прервавшую репликацию, на источнике? Если нет, вручную откатайте транзакцию на сервере, где она изначально произошла.

Для пропуска транзакции выберите один из следующих методов:

  • При использовании GTID (gtid_mode равно ON), см. раздел 16.1.7.3.1, «Пропуск транзакций с GTID».

  • При отсутствии GTID или при их поэтапном внедрении (gtid_mode равно OFF, OFF_PERMISSIVE или ON_PERMISSIVE), см. раздел 16.1.7.3.2, «Пропуск транзакций без GTID».

Для перезапуска репликации после пропуска транзакции выполните START SLAVE, с клаузой FOR CHANNEL, если реплика является репликой с несколькими источниками.

16.1.7.3.1 Пропуск транзакций с GTID

При использовании GTID (gtid_mode равно ON), GTID завершённой транзакции сохраняется на реплике, даже если содержимое транзакции отфильтровано. Эта функция предотвращает получение репликой ранее отфильтрованных транзакций при повторном подключении к источнику с помощью автоматического позиционирования по GTID. Её также можно использовать для пропуска транзакции на реплике, выполнив вместо нее пустую транзакцию.

Если неисправная транзакция сгенерировала ошибку в потоке обработки, её 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 SLAVE для перезапуска репликации, реплика использует функцию автоматического пропуска, чтобы пропустить неисправную транзакцию, потому что видит, что транзакция с этим GTID уже применена. Если реплика является репликой с несколькими источниками, вам не нужно указывать имя канала при выполнении коммита пустой транзакции, но вам нужно указать имя канала при выполнении START SLAVE.

Обратите внимание, что если на этой реплике используется двоичное протоколирование, пустая транзакция попадет в поток репликации, если реплика станет источником или главным в будущем. Если вам нужно предотвратить такую возможность, рассмотрите возможность очистки и удаления двоичных логов реплики, как в этом примере:

FLUSH LOGS;
PURGE BINARY LOGS TO 'binlog.000146';

GTID пустой транзакции сохраняется, но сама транзакция удаляется путем очистки файлов двоичных логов.

16.1.7.3.2 Пропуск транзакций без GTIDs
  • 16.1.7.3.2.1 Пропуск транзакций с SET GLOBAL sql_slave_skip_counter
  • 16.1.7.3.2.2 Пропуск транзакций с CHANGE MASTER TO

Для пропуска некорректных транзакций, когда GTIDs не используются или находятся в процессе внедрения (gtid_mode имеет значение OFF, OFF_PERMISSIVE или ON_PERMISSIVE), можно пропустить определённое количество событий, выполнив оператор SET GLOBAL sql_slave_skip_counter. Также можно пропустить событие или несколько событий, выполнив оператор CHANGE MASTER TO для продвижения позиции двоичного лога источника вперёд.

При использовании этих методов важно понимать, что вы не обязательно пропускаете полную транзакцию, как это всегда происходит при использовании метода на основе GTID, описанного ранее. Эти методы, не основанные на GTID, не осознают транзакции как таковые, а вместо этого работают с событиями. Двоичный лог организован как последовательность групп, известных как группы событий, и каждая группа событий состоит из последовательности событий.

  • Для таблиц транзакций группа событий соответствует транзакции.

  • Для нетранзакционных таблиц группа событий соответствует одному оператору SQL.

Одна транзакция может содержать изменения в обеих типах таблиц — транзакционных и нетранзакционных.

Если вы используете оператор SET GLOBAL sql_slave_skip_counter для пропуска событий, и полученная позиция находится в середине группы событий, реплика продолжает пропускать события до достижения конца группы. Затем выполнение начинается с следующей группы событий. Оператор CHANGE MASTER TO не имеет этой функции, поэтому необходимо тщательно определить правильное место для возобновления репликации в начале группы событий. Однако использование CHANGE MASTER TO означает, что вам не нужно считать события, которые необходимо пропустить, как это делается с SET GLOBAL sql_slave_skip_counter, а вместо этого можно просто указать место для возобновления.

16.1.7.3.2.1 Пропуск транзакций с помощью SET GLOBAL sql_slave_skip_counter

После оценки некорректной транзакции и принятия соответствующих мер (например, учитывая соображения безопасности), подсчитайте количество событий, которые необходимо пропустить. Одно событие обычно соответствует одному оператору SQL в двоичном логе, но обратите внимание, что операторы, использующие AUTO_INCREMENT или LAST_INSERT_ID(), считаются двумя событиями в двоичном логе.

Если вы хотите пропустить всю транзакцию, вы можете подсчитать события до конца транзакции или просто пропустить соответствующую группу событий. Помните, что при использовании SET GLOBAL sql_slave_skip_counter реплика продолжает пропускать события до конца группы событий. Убедитесь, что вы не пропускаете слишком далеко вперёд и не переходите в следующую группу событий или транзакцию, так как это приведёт к пропуску и этой транзакции.

Выполните оператор SET следующим образом, где N — количество событий, которые необходимо пропустить на источнике:

SET GLOBAL sql_slave_skip_counter = N

Этот оператор нельзя выполнить, если gtid_mode=ON установлено или если потоки реплики работают.

Оператор SET GLOBAL sql_slave_skip_counter не оказывает немедленного эффекта. Когда вы выполните оператор START SLAVE в следующий раз после выполнения этого оператора SET, новое значение системной переменной sql_slave_skip_counter будет применено, и события будут пропущены. Оператор START SLAVE также автоматически устанавливает значение системной переменной обратно к 0. Если реплика является репликой с несколькими источниками, когда вы выполняете оператор START SLAVE, необходима фраза FOR CHANNEL. Убедитесь, что вы указали правильный канал, иначе события будут пропущены на неправильном канале.

16.1.7.3.2.2 Пропуск транзакций с помощью CHANGE MASTER TO

После оценки некорректной транзакции и принятия соответствующих мер (например, учитывая соображения безопасности), определите координаты (файл и позицию) в двоичном логе источника, представляющие подходящую позицию для возобновления репликации. Это может быть начало группы событий, следующей за событием, вызвавшим проблему, или начало следующей транзакции. Поток ввода/вывода репликации начинает чтение у источника по этим координатам в следующий раз, когда поток запускается, пропуская некорректное событие. Убедитесь, что вы точно определили позицию, так как этот оператор не учитывает группы событий.

Выполните оператор CHANGE MASTER TO следующим образом, где source_log_name — двоичный лог-файл, содержащий позицию возобновления, а source_log_pos — число, представляющее позицию возобновления, как указано в файле двоичного лога:

CHANGE MASTER TO MASTER_LOG_FILE='source_log_name', MASTER_LOG_POS=source_log_pos;

Если реплика является репликой с несколькими источниками, вы должны использовать фразу FOR CHANNEL для указания соответствующего канала в операторе CHANGE MASTER TO.

Этот оператор нельзя выполнить, если MASTER_AUTO_POSITION=1 установлено, или если потоки репликации работают. Если вам нужно использовать этот метод пропуска транзакции, когда MASTER_AUTO_POSITION=1 обычно установлено, можно изменить значение на MASTER_AUTO_POSITION=0 при выполнении оператора, а затем изменить его обратно после этого. Например:

CHANGE MASTER TO MASTER_AUTO_POSITION=0, MASTER_LOG_FILE='binlog.000145', MASTER_LOG_POS=235;
CHANGE MASTER TO MASTER_AUTO_POSITION=1;

© 2025 Oracle
Licensed under the GPLv2 License.
https://docs.oracle.com/cd/E17952_01/mysql-5.7-en/replication-administration-skip.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API