Задавайте вопросы, мы ответим
Вы не зашли.
Как радостно начиналось, как печально зашла в тупик (
У меня у каждой таблицы, есть её копия для логирования, если в таблице происходят изменения, то в логирующую для начала перед изменением сносится предыдущий вариант. Всё было прекрасно, пока я не решила перевязать все таблицы внешними ключами по логике приложения. Внесла смысл в хаос, но радость длилась не долго, так как большинство действий по внешним ключам были наследственными. Поняла, что теряется логирование, что раньше было всегда при изменениях прописано в ПХП скриптах. Ну хорошо, задумалась над автоматизацией, изучила феномен триггеров. Обрадовалась. Накидала на таблицы триггеров для логирования во вторую таблице ПЕРЕД вносом изменений. А теперь тестируя наткнулась на печальную реальность. Когда в таблице А удаляется/изменяется строка, к которой привязана строка из таблицы Б, триггер таблицы А делает копию строки в таблицу А_лог, внешний ключ как и прописано наследует изменения и производит их в таблице Б, но триггер таблицы Б игнорирует эти изменения и ничего не оставляет в таблице Б_лог ..... это лечится?
Неактивен
Перелопатила интернет и выяснила, что это проблема висит в багах разработчиков аж с 2005-го года. Исходя из этого пришла к выводу, что имеет смысл заменить внешние ключи триггерами, которые их имитируют. А вот последние примером найти не смогла . Ведь по сути это схоже с транзакциями, то есть нужно прописывать откаты и всё это в процедурном виде. Не совсем в этом понимаю пока ещё. Если есть уже готовые решения и знаете ссылочку на них, буду рада и благодарна.
Неактивен
Триггеры в MySQL не срабатывают при апдейте по внешнему ключу. Но можно повесить триггер на запрос UPDATE, который вызывает такое изменение.
Неактивен
rgbeast написал:
Триггеры в MySQL не срабатывают при апдейте по внешнему ключу. Но можно повесить триггер на запрос UPDATE, который вызывает такое изменение.
Ну я сейчас в принципе так и переделываю, отказалась от внешних ключей, вместо них всё перевожу на триггеры. Испытания прошли успешно, триггеры друг друга запускают.
Единственное, вчера задумалась, а что будет при переносе на боевой сервер, там стоит репликация в модусе MIXED. Если на реплику передадутся триггеры(что вроде бы как делать верно, ибо реплика будет может быть сама мастером если надо), то будут ли команды триггеров записаны в файл для репликации, и если да, то не выйдет ли так, что там будет всё ходить по нескольку кругов, сначала прямая запись от триггера, потом ещё и триггер на месте?
Неактивен
Проблем не будет, если одинаковые триггеры есть и на мастере и на слейве. mixed значит, что для каждого запроса это или row или statement. Если row, то триггеры на слейве не будут срабатывать, на него просто попадут все изменения, уже сделанные триггерами на мастере. Если statement, то триггеры отработают на слейве.
http://dev.mysql.com/doc/refman/5.1/en/ … ggers.html
Неактивен
rgbeast написал:
Проблем не будет, если одинаковые триггеры есть и на мастере и на слейве. mixed значит, что для каждого запроса это или row или statement. Если row, то триггеры на слейве не будут срабатывать, на него просто попадут все изменения, уже сделанные триггерами на мастере. Если statement, то триггеры отработают на слейве.
http://dev.mysql.com/doc/refman/5.1/en/ … ggers.html
Мда, решила аккуратно протестировать на сервере на тестовых таблицах - обвалила реплику.
Таблицы:
Неактивен
Пользователь, который является создателем триггера root@% не существует. Убедитесь, что пользователи также одинаковые на мастере и слейве.
Неактивен
Спасибо, не ожидала такого момента. Хммм, но это не есть хорошо. Так как юзера 'root'@'%' я хотела прикрыть, он не вызывает у меня особого доверия.
Неактивен
rgbeast написал:
Проблем не будет, если одинаковые триггеры есть и на мастере и на слейве. mixed значит, что для каждого запроса это или row или statement. Если row, то триггеры на слейве не будут срабатывать, на него просто попадут все изменения, уже сделанные триггерами на мастере. Если statement, то триггеры отработают на слейве.
http://dev.mysql.com/doc/refman/5.1/en/ … ggers.html
Эксперимент прошёл вроде как удачно. Но вот этот момент меня всё ещё немного тревожит. И так, ещё раз для закрепления:
Если на мастере сработает триггер, то данные в логфайл запишутся как row-based replication и на слэйве триггеры не сработают - верно?
Если на мастере не сработает триггер, то данные в логфайл запишутся как statement-based replication и в случае если триггеры и там и там идентичны, то на слэйве, тоже ничего не сработает - верно?
Неактивен
См. SHOW CREATE TRIGGER
http://dev.mysql.com/doc/refman/5.1/en/ … igger.html
У каждого триггера, функции или процедуры есть создатель (definer). Он должен присутствовать на обоих машинах. Это не обязательно root.
Правильнее так. MySQL решит какую репликацию использовать.
1. Если это row, то на слейве триггер не срабатывает, но все изменения передаются на слейв.
2. Если это statement, то реплицируется запросы, на слейве срабатывают триггеры.
Неактивен
rgbeast написал:
См. SHOW CREATE TRIGGER
http://dev.mysql.com/doc/refman/5.1/en/ … igger.html
У каждого триггера, функции или процедуры есть создатель (definer). Он должен присутствовать на обоих машинах. Это не обязательно root.
Правильнее так. MySQL решит какую репликацию использовать.
1. Если это row, то на слейве триггер не срабатывает, но все изменения передаются на слейв.
2. Если это statement, то реплицируется запросы, на слейве срабатывают триггеры.
2. Так, а существует вероятность того, что MySQL решит передать репликацию, как statement, тем самым выйдет двойная запись, из-за двойного срабатывания триггера?
Неактивен
Может передать как statement. Statement выполнится на мастере и слейве. На мастере и слейве независимо сработает триггер, но результат триггера на мастере не будет реплицирован, поэтому двойного срабатывания не будет.
Неактивен
rgbeast написал:
У каждого триггера, функции или процедуры есть создатель (definer). Он должен присутствовать на обоих машинах. Это не обязательно root.
А пароли тоже должны совпадать или там только имя важно? (Кстати зачем это сделано?)
Неактивен
Пароли не обязаны совпадать. Функция по-умолчанию распоряжается базой с правами своего создателя. Это нужно, так как функция может иметь больше привилегий, чем тот, кто ее вызывает.
Неактивен