16.4.1.33 Репликация и транзакции
Смешивание транзакционных и не транзакционных операторов в одной транзакции. В общем случае, следует избегать транзакций, которые обновляют как транзакционные, так и не транзакционные таблицы в среде репликации. Также следует избегать использования операторов, которые обращаются к транзакционным (или временным) и не транзакционным таблицам и записывают данные в любую из них.
Сервер использует следующие правила для двоичного протоколирования:
Если начальные операторы в транзакции являются не транзакционными, они записываются в двоичный журнал немедленно. Остальные операторы в транзакции кэшируются и не записываются в двоичный журнал, пока транзакция не будет подтверждена. (Если транзакция откатывается, кэшированные операторы записываются в двоичный журнал только в случае, если они производят не транзакционные изменения, которые нельзя отменить. В противном случае они отбрасываются.)
Для протоколирования на основе операторов, протоколирование не транзакционных операторов зависит от системной переменной
binlog_direct_non_transactional_updates. Когда эта переменная равнаOFF(значение по умолчанию), протоколирование происходит, как описано выше. Когда эта переменная равнаON, протоколирование происходит немедленно для не транзакционных операторов, встречающихся где-либо в транзакции (а не только для начальных не транзакционных операторов). Другие операторы хранятся в кэше транзакции и протоколируются при подтверждении транзакции.binlog_direct_non_transactional_updatesне имеет эффекта для двоичного протоколирования в формате строк или смешанном формате.
Транзакционные, не транзакционные и смешанные операторы. Для применения этих правил сервер считает оператор не транзакционным, если он изменяет только не транзакционные таблицы, и транзакционным, если он изменяет только транзакционные таблицы. Оператор, который ссылается на обе не транзакционные и транзакционные таблицы и обновляет любую из вовлеченных таблиц, считается “смешанным” оператором. (В некоторых предыдущих версиях MySQL, смешанным считался только оператор, обновляющий и не транзакционные, и транзакционные таблицы.) Смешанные операторы, как и транзакционные операторы, кэшируются и протоколируются при подтверждении транзакции.
Смешанный оператор, обновляющий транзакционную таблицу, считается небезопасным, если он также выполняет одно из следующих действий:
Обновляет или считывает временную таблицу
Считывает не транзакционную таблицу, а уровень изоляции транзакции меньше REPEATABLE_READ
Смешанный оператор, следующий за обновлением транзакционной таблицы в рамках транзакции, считается небезопасным, если он выполняет одно из следующих действий:
Обновляет любую таблицу и считывает из любой временной таблицы
Обновляет не транзакционную таблицу и
binlog_direct_non_transactional_updatesвыключен
Для получения дополнительной информации см. Раздел 16.2.1.3, «Определение безопасных и небезопасных операторов в двоичном протоколировании».
Смешанный оператор не связан со смешанным форматом двоичного протоколирования.
В ситуациях, когда транзакции смешивают обновления транзакционных и не транзакционных таблиц, порядок операторов в двоичном журнале правильный, и все необходимые операторы записываются в двоичный журнал даже в случае ROLLBACK. Однако, когда второй подключение обновляет не транзакционную таблицу до завершения транзакции первого подключения, операторы могут быть залогированы в неправильном порядке, потому что обновление второго подключения записывается немедленно после выполнения, независимо от состояния транзакции, выполняемой первым подключением.
Использование разных движков хранения на источнике и реплике. Возможно реплицировать транзакционные таблицы на источнике с использованием не транзакционных таблиц на реплике. Например, вы можете реплицировать таблицу InnoDB источника в качестве таблицы MyISAM реплики. Однако, если вы это делаете, могут возникнуть проблемы, если реплика остановится посреди блока BEGIN ... COMMIT, потому что реплика перезапустится в начале блока BEGIN.
Также безопасно реплицировать транзакции из таблиц MyISAM на источнике в транзакционные таблицы, такие как таблицы, использующие движок хранения InnoDB, на реплике. В таких случаях, оператор AUTOCOMMIT=1, выпущенный на источнике, реплицируется, тем самым обеспечивая режим AUTOCOMMIT на реплике.
Когда тип движка хранения реплики является не транзакционным, следует избегать транзакций на источнике, которые смешивают обновления транзакционных и не транзакционных таблиц, так как они могут привести к несогласованности данных между транзакционной таблицей источника и не транзакционной таблицей реплики. То есть, такие транзакции могут привести к поведению, специфичному для движка хранения источника, с возможным эффектом потери синхронизации репликации. В настоящее время MySQL не выдает предупреждений об этом, поэтому при репликации транзакционных таблиц с источника на не транзакционные таблицы на репликах следует проявлять особую осторожность.
Изменение формата двоичного протоколирования в рамках транзакций. Системные переменные binlog_format и binlog_checksum являются только для чтения, пока транзакция находится в процессе выполнения.
Каждая транзакция (включая транзакции с autocommit) записывается в двоичный журнал так, как будто она начинается с оператора BEGIN, и заканчивается либо оператором COMMIT, либо оператором ROLLBACK. Это справедливо даже для операторов, влияющих на таблицы, использующие не транзакционный движок хранения (такой как MyISAM).
Ограничения, которые применяются конкретно к транзакциям XA, см. в Разделе 13.3.7.3, «Ограничения на транзакции XA».
© 2025 Oracle
Licensed under the GPLv2 License.