16.4.1.34 复制和触发器

使用基于语句的复制时,在源上执行的触发器也将在副本上执行。使用基于行的复制时,在源上执行的触发器不会在副本上执行。取而代之的是,源于触发器执行的源行更改将被复制并应用于副本。

此行为是设计使然。如果在基于行的复制下副本使用触发器以及由触发器引起的行更改,则更改实际上将在副本上应用两次,从而导致源和副本上的数据不同。

如果希望触发器在源和副本上均执行,则可能是因为在源和副本上具有不同的触发器,所以必须使用基于语句的复制。但是,要启用副本端触发器,不必专门使用基于语句的复制。仅对需要这种效果的那些语句切换到基于语句的复制就足够了,并在其余时间使用基于行的复制就足够了。

不能使用基于语句的复制正确地复制调用触发器(或函数)导致对AUTO_INCREMENT列进行更新的语句。 MySQL 5.7 将此类语句标记为不安全。错误 45677)

触发器可以具有触发器事件(INSERTUPDATEDELETE)和动作时间(BEFOREAFTER)的不同组合的触发器,但是在 MySQL 5.7.2 之前不能有多个触发器具有相同的触发器事件和动作时间。 MySQL 5.7.2 取消了此限制,并且允许多个触发器。此更改对升级和降级具有复制影响。

为简便起见,“多个触发器”是“具有相同触发事件和动作时间的多个触发器”的简写。

升级. 假设您将不支持多个触发器的旧服务器升级到 MySQL 5.7.2 或更高版本。如果新服务器是复制源服务器,并且具有不支持多个触发器的旧副本,那么如果在源上为已经具有具有相同触发器事件和动作时间的触发器的 table 创建触发器,则这些副本上会发生错误。 。为避免此问题,请先升级副本,然后再升级源。

降级. 如果将支持多个触发器的服务器降级为不支持的触发器,则降级会产生以下影响:

  • 对于每个具有触发器的 table,所有触发器定义都保留在该 table 的.TRG文件中。但是,如果有多个具有相同触发事件和动作时间的触发,则当触发事件发生时,服务器仅执行其中一个。有关.TRG文件的信息,请参见 MySQL 服务器 Doxygen 文档的“table 触发器存储”部分,该文件位于https://dev.mysql.com/doc/index-other.html

  • 如果在降级之后添加或删除了 table 的触发器,则服务器将重写 table 的.TRG文件。每次触发事件和动作时间的组合,重写的文件仅保留一个触发;其他人迷路了。

为避免这些问题,请在降级之前修改触发器。对于每个具有触发事件和动作时间组合的多个触发器的 table,将每个这样的一组触发器转换为单个触发器,如下所示:

  • 对于每个触发器,创建一个存储的例程,其中包含触发器中的所有代码。可以使用参数将使用NEWOLD访问的值传递给例程。如果触发器需要代码中的单个结果值,则可以将代码放入存储的函数中,并使该函数返回该值。如果触发器需要代码中的多个结果值,则可以将代码放入存储过程中,并使用OUT参数返回值。

  • 删除 table 的所有触发器。

  • 为 table 创建一个新的触发器,该触发器调用刚刚创建的存储例程。因此,此触发器的效果与其替换的多个触发器相同。