16.4.1.34 Репликация и триггеры
При репликации на основе инструкций триггеры, выполняемые на источнике, также выполняются на реплике. При репликации на основе строк триггеры, выполняемые на источнике, не выполняются на реплике. Вместо этого изменения строк на источнике, вызванные выполнением триггера, реплицируются и применяются на реплике.
Это поведение является заданным по умолчанию. Если при репликации на основе строк реплика также применяла бы триггеры, а также изменения строк, вызванные ими, изменения фактически применялись бы дважды на реплике, что приводило бы к разным данным на источнике и реплике.
Если вы хотите, чтобы триггеры выполнялись как на источнике, так и на реплике, возможно, потому что у вас разные триггеры на источнике и реплике, вы должны использовать репликацию на основе инструкций. Однако, для активации триггеров на стороне реплики не обязательно использовать исключительно репликацию на основе инструкций. Достаточно переключиться на репликацию на основе инструкций только для тех инструкций, где вы хотите этот эффект, и использовать репликацию на основе строк в остальное время.
Инструкция, вызывающая триггер (или функцию), которая вызывает обновление AUTO_INCREMENT столбца, не реплицируется правильно при использовании репликации на основе инструкций. MySQL 5.7 помечает такие инструкции как небезопасные. (Ошибка #45677)
Триггер может иметь триггеры для различных комбинаций события триггера (INSERT, UPDATE, DELETE) и времени действия (BEFORE, AFTER), но до MySQL 5.7.2 не может иметь несколько триггеров с одинаковым событием триггера и временем действия. MySQL 5.7.2 снимает это ограничение, и разрешается использование нескольких триггеров. Это изменение имеет последствия для репликации при обновлении и переходе к более старой версии.
Для краткости, “несколько триггеров” здесь используется как сокращение для “несколько триггеров с одинаковым событием триггера и временем действия.”
Обновления. Предположим, что вы обновляете старый сервер, не поддерживающий несколько триггеров, до MySQL 5.7.2 или выше. Если новый сервер является сервером-источником репликации и имеет старые реплики, не поддерживающие несколько триггеров, на этих репликах возникает ошибка, если на источнике создается триггер для таблицы, которая уже имеет триггер с тем же событием триггера и временем действия. Чтобы избежать этой проблемы, сначала обновите реплики, а затем обновите источник.
Переходы к более старой версии. Если вы переходите к более старой версии сервера, поддерживающего несколько триггеров, на версию, которая не поддерживает это, понижение версии имеет следующие последствия:
Для каждой таблицы, имеющей триггеры, все определения триггеров остаются в файле
.TRGдля таблицы. Однако, если есть несколько триггеров с одинаковым событием триггера и временем действия, сервер выполняет только один из них при возникновении события триггера. Сведения о файлах.TRGсм. в разделе «Хранение триггеров таблиц» документации MySQL Server Doxygen, доступной по адресу https://dev.mysql.com/doc/index-other.html.Если триггеры для таблицы добавляются или удаляются после перехода к более старой версии, сервер перезаписывает файл
.TRGтаблицы. Перезаписанный файл сохраняет только один триггер на каждую комбинацию события триггера и времени действия; остальные теряются.
Чтобы избежать этих проблем, измените свои триггеры перед переходом к более старой версии. Для каждой таблицы, имеющей несколько триггеров на каждую комбинацию события триггера и времени действия, преобразуйте каждый такой набор триггеров в один триггер следующим образом:
Для каждого триггера создайте хранимую процедуру, которая содержит весь код в триггере. Значения, получаемые с помощью
NEWиOLD, могут быть переданы в процедуру с помощью параметров. Если триггеру требуется единственное значение результата из кода, вы можете поместить код в хранимую функцию, и функция вернёт значение. Если триггеру требуются несколько значений результата из кода, вы можете поместить код в хранимую процедуру и вернуть значения с помощью параметровOUT.Удалите все триггеры для таблицы.
Создайте один новый триггер для таблицы, который вызывает только что созданные хранимые процедуры. Эффект для этого триггера будет таким же, как и для нескольких триггеров, которые он заменяет.
© 2025 Oracle
Licensed under the GPLv2 License.