Триггеры MySQL + репликация с несколькими базами данных

Я использую пару баз данных в MySQL 5.0.45 и пытаюсь синхронизировать свою устаревшую базу данных с пересмотренной схемой, поэтому я могу работать одновременно с обеими. Я делаю это, добавляя триггеры в новую базу данных, но у меня возникают проблемы с репликацией. Моя установка выглядит следующим образом.

Сервер "мастер"

  • База данных «legacydb» реплицируется на «подчиненный» сервер.
  • База данных «newdb» имеет триггеры, которые обновляют «legacydb», и не имеет репликации.

Сервер "раб"

  • База данных "legacydb"

Мои обновления для "newdb" работают нормально и запускают мои триггеры. Они обновляют "legacydb" на "главном" сервере. Однако изменения не реплицируются на ведомые устройства. В документации MySQL говорится, что для простоты репликация смотрит на текущий контекст базы данных (например, "SELECT DATABASE();") при принятии решения, какие запросы реплицировать, а не на продукт запроса. Мой триггер запускается из контекста базы данных newdb, поэтому репликация игнорирует обновления.

Я попытался переместить оператор обновления в хранимую процедуру в «legacydb». Это работает нормально (т.е. данные реплицируются на подчиненное устройство), когда я подключаюсь к «мастеру» и вручную запускаю "USE newdb; CALL legacydb.do_update('Foobar', 1, 2, 3, 4);". Однако, когда эта процедура вызывается из триггера, она не реплицируется.

Пока что я думал о том, как это исправить, был одним из следующих.

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

  • Реплицируйте обе базы данных и используйте триггеры как на главном, так и на подчиненном устройстве. Это было бы возможно, но сложно настроить.

  • Заставить репликацию принимать все изменения в «legacydb», независимо от текущего контекста базы данных.

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

Любая помощь о том, как этого добиться, будет принята с благодарностью.


person Josh    schedule 19.09.2008    source источник


Ответы (1)


Возможно, это как-то связано с этим:

Сохраненная функция получает блокировки таблицы перед выполнением, чтобы избежать несогласованности в двоичном журнале из-за несоответствия порядка выполнения операторов и времени их появления в журнале. Записываются операторы, которые вызывают функцию, а не операторы, выполняемые внутри функции. Следовательно, сохраненные функции, которые обновляют одни и те же базовые таблицы, не выполняются параллельно.

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

Кроме того, существует целый список проблем с триггерами: http://dev.mysql.com/doc/refman/5.0/en/routine-restrictions.html

person Chris    schedule 19.09.2008
comment
По сути, надежный способ - обновить базу данных, и если есть триггеры в реплицированной базе данных или сохраненные функции, они также должны существовать в подчиненной базе данных. Также существуют ограничения на то, как писать триггеры и функции, чтобы они сами воспроизводились. - person Chris; 19.09.2008