19.5.1.36 Репликация и транзакции
Смешивание транзакционных и не транзакционных операторов в рамках одной транзакции. В MySQL 9.2 (и более поздних версиях) транзакции, обновляющие как транзакционные таблицы, так и таблицы, не являющиеся транзакционными или несоставными, устарели и вызывают предупреждение об устаревании как для клиента, так и для журнала ошибок. В MySQL 9.2 только InnoDB и BLACKHOLE двигатели хранения являются транзакционными и составными; NDBCLUSTER является транзакционным, но не составным. Это означает, что только сочетания двигателей хранения, которые не вызывают предупреждение об устаревании, указаны здесь:
InnoDBиBLACKHOLEMyISAMиMergeperformance_schemaи любой другой двигатель храненияTempTableи любой другой двигатель хранения
В общем случае следует избегать транзакций, обновляющих как транзакционные, так и не транзакционные таблицы в среде репликации. Также следует избегать использования операторов, которые обращаются к как транзакционным (или временным), так и не транзакционным таблицам и записывают в любую из них.
Сервер использует следующие правила для двоичного протоколирования:
Если начальные операторы в транзакции не транзакционные, они записываются в двоичный журнал немедленно. Остальные операторы в транзакции кэшируются и не записываются в двоичный журнал до тех пор, пока транзакция не будет подтверждена. (Если транзакция откатывается, кэшированные операторы записываются в двоичный журнал только в том случае, если они вносят не транзакционные изменения, которые нельзя отменить. В противном случае они отбрасываются.)
Для протоколирования на уровне операторов, протоколирование не транзакционных операторов зависит от системной переменной
binlog_direct_non_transactional_updates. Когда эта переменная имеет значениеOFF(по умолчанию), протоколирование происходит как описано выше. Когда эта переменная имеет значениеON, протоколирование происходит немедленно для не транзакционных операторов, встречающихся где угодно в транзакции (не только начальные не транзакционные операторы). Другие операторы сохраняются в кэше транзакции и протоколируются при подтверждении транзакции.binlog_direct_non_transactional_updatesне оказывает никакого эффекта для двоичного протоколирования в формате строк или смешанном формате.
Транзакционные, не транзакционные и смешанные операторы. Для применения этих правил сервер рассматривает оператор как не транзакционный, если он изменяет только не транзакционные таблицы, и транзакционный, если он изменяет только транзакционные таблицы. Оператор, ссылающийся на как не транзакционные, так и транзакционные таблицы и обновляющий любую из затронутых таблиц, считается оператором “смешанным”. Смешанные операторы, как и транзакционные операторы, кэшируются и протоколируются при подтверждении транзакции.
Смешанный оператор, обновляющий транзакционную таблицу, считается небезопасным, если он также выполняет одно из следующих действий:
Обновляет или читает временную таблицу
Читает не транзакционную таблицу, и уровень изоляции транзакции меньше REPEATABLE_READ
Смешанный оператор, следующий за обновлением транзакционной таблицы в рамках транзакции, считается небезопасным, если он выполняет одно из следующих действий:
Обновляет любую таблицу и считывает из любой временной таблицы
Обновляет не транзакционную таблицу, и
binlog_direct_non_transactional_updatesвыключено
Дополнительную информацию см. в Разделе 19.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, см. в Разделе 15.3.8.3, «Ограничения на транзакции XA».
© 2025 Oracle
Licensed under the GPLv2 License.