Spec-Zone.ru › MySQL 5.7

16.4.1.32 Несоответствия репликации и транзакций

Несоответствия в последовательности выполненных транзакций из лога репликации могут возникнуть в зависимости от вашей конфигурации репликации. В этом разделе объясняется, как избежать несоответствий и решить любые проблемы, которые они вызывают.

Могут существовать следующие типы несоответствий:

  • Неполностью примененные транзакции. Транзакция, обновляющая нетранзакционные таблицы, применила часть, но не все свои изменения.

  • Пропуски. Пропуск — это транзакция, которая не была полностью применена, даже если некоторые последующие транзакции в последовательности были применены. Пропуски могут появляться только при использовании многопоточной реплики. Чтобы предотвратить появление пропусков, установите slave_preserve_commit_order=1, что требует slave_parallel_type=LOGICAL_CLOCK, и что log-bin и log-slave-updates также включены. Обратите внимание, что slave_preserve_commit_order=1 не сохраняет порядок обновлений DML нетранзакционных данных, поэтому они могут быть выполнены до транзакций, которые предшествуют им в логе репликации, что может привести к пропускам.

  • Отставание позиции исходного бинарного лога. Даже при отсутствии пропусков возможно, что транзакции после Exec_master_log_pos были применены. То есть, все транзакции до позиции N были применены, и никакие транзакции после N не были применены, но Exec_master_log_pos имеет значение меньше, чем N. В этой ситуации, Exec_master_log_pos является “нижней границей” примененных транзакций и отстает от позиции последней применённой транзакции. Это может произойти только на многопоточных репликах. Включение slave_preserve_commit_order не предотвращает отставания позиции исходного бинарного лога.

Следующие сценарии имеют отношение к существованию неполностью примененных транзакций, пропусков и отставанию позиции исходного бинарного лога:

  1. Во время работы потоков репликации могут возникать пропуски и неполностью примененные транзакции.

  2. mysqld завершается. Как чистая, так и нечистая остановка прерывают текущие транзакции и могут привести к пропускам и неполностью примененным транзакциям.

  3. KILL потоков репликации (потока SQL при использовании однопоточной реплики, координационного потока при использовании многопоточной реплики). Это прерывает текущие транзакции и может привести к пропускам и неполностью примененным транзакциям.

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

  5. STOP SLAVE при использовании многопоточной реплики. После выдачи STOP SLAVE, реплика ждет заполнения любых пропусков, а затем обновляет Exec_master_log_pos. Это гарантирует, что она никогда не оставит пропусков или отставание позиции исходного бинарного лога, если не произошел ни один из вышеперечисленных случаев, другими словами, до того, как STOP SLAVE завершится, произошла ошибка, другой поток выдал KILL или сервер перезапущен. В этих случаях STOP SLAVE возвращает успех.

  6. Если последняя транзакция в логе репликации получена только наполовину, а координатор многопоточной реплики начал планировать транзакцию для рабочего потока, то STOP SLAVE ждет до 60 секунд получения транзакции. После истечения этого времени координатор отказывается и прерывает транзакцию. Если транзакция смешанная, она может остаться неполностью завершенной.

  7. STOP SLAVE, когда текущая транзакция обновляет только транзакционные таблицы, в этом случае она откатывается, и STOP SLAVE останавливается немедленно. Если текущая транзакция смешанная, STOP SLAVE ждет до 60 секунд завершения транзакции. После истечения этого времени она прерывает транзакцию, поэтому она может остаться неполностью завершенной.

Глобальная переменная rpl_stop_slave_timeout не связана с процессом остановки потоков репликации. Она только заставляет клиента, который выдает STOP SLAVE, вернуть результат клиенту, но потоки репликации продолжают пытаться остановиться.

Если канал репликации имеет пропуски, это имеет следующие последствия:

  1. База данных реплики находится в состоянии, которое могло никогда не существовать на источнике.

  2. Поле Exec_master_log_pos в SHOW SLAVE STATUS является лишь “нижней границей”. Другими словами, транзакции, появляющиеся до этой позиции, гарантированно были выполнены, но транзакции после этой позиции могут быть выполнены или нет.

  3. CHANGE MASTER TO операторы для этого канала завершаются с ошибкой, если потоки приложения не работают и оператор CHANGE MASTER TO устанавливает только параметры получателя.

  4. Если mysqld запускается с --relay-log-recovery, восстановление для этого канала не выполняется, и выводится предупреждение.

  5. Если mysqldump используется с --dump-slave, он не регистрирует наличие пропусков; таким образом, он выводит CHANGE MASTER TO с RELAY_LOG_POS, установленным в “нижнюю границу” позицию в Exec_master_log_pos.

    После применения дампа на другом сервере и запуска потоков репликации транзакции, появляющиеся после этой позиции, снова реплицируются. Обратите внимание, что это безопасно, если включены GTID (однако в этом случае не рекомендуется использовать --dump-slave).

Если в канале репликации есть отставание позиции исходного бинарного лога, но нет пропусков, то пункты 2-5 выше применяются, но пункт 1 нет.

Информация о позиции исходного бинарного лога сохраняется в двоичном формате во внутренней таблице mysql.slave_worker_info. START SLAVE [SQL_THREAD] всегда обращается к этой информации, чтобы применять только правильные транзакции. Это остается верным, даже если slave_parallel_workers было изменено на 0 до START SLAVE, и даже если START SLAVE используется с UNTIL фрагментами. START SLAVE UNTIL SQL_AFTER_MTS_GAPS применяет только столько транзакций, сколько необходимо для заполнения пропусков. Если START SLAVE используется с UNTIL фрагментами, которые говорят ему остановиться до того, как он обработает все пропуски, то оставшиеся пропуски остаются.

Предупреждение

RESET SLAVE удаляет лог репликации и сбрасывает позицию репликации. Таким образом, выдача RESET SLAVE на реплике с пропусками означает, что реплика теряет любую информацию о пропусках, не исправляя их.

При использовании репликации на основе GTID, начиная с MySQL 5.7.28, многопоточная реплика сначала проверяет, установлено ли MASTER_AUTO_POSITION на ON, и если да, пропускает этап вычисления транзакций, которые следует пропустить или нет. В этом случае старые лог репликации не требуются для процесса восстановления.

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

Spec-Zone.ru

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