Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

19.5.1.36 复制和触发器

使用基于语句的复制,源上的触发器也将在副本上执行。使用基于行的复制,源上的触发器不会在副本上执行。相反,源上的触发器执行所导致的行更改将被复制并应用于副本。

这是设计的结果。如果在基于行的复制中副本也应用触发器,那么更改将在副本上被应用两次,导致源和副本上的数据不同。

如果您想在源和副本上都执行触发器,可能是因为您在源和副本上有不同的触发器,那么您必须使用基于语句的复制。但是,要启用副本侧触发器,不需要完全使用基于语句的复制。只需在您想要这种效果的语句中切换到基于语句的复制,并在其他时间使用基于行的复制。

使用基于语句的复制时,触发器(或函数)导致自动递增列的更新语句不能正确复制。MySQL 8.3 将这些语句标记为不安全。(Bug #45677)

触发器可以具有不同的触发事件(INSERTUPDATEDELETE)和操作时间(BEFOREAFTER),并且允许多个触发器。

为简洁起见,多个触发器这里是指具有相同触发事件和操作时间的多个触发器。

升级。 在 MySQL 5.7 之前的版本中不支持多个触发器。如果您升级了复制拓扑结构中的服务器,首先升级副本,然后升级源。如果升级的复制源服务器仍然有使用早期 MySQL 版本的副本,那么在源上创建触发器时将在这些副本上出现错误,用于表已经有相同触发事件和操作时间的触发器。

降级。 如果您将支持多个触发器的服务器降级到不支持多个触发器的版本,那么降级将产生以下效果:

  • 对于每个具有触发器的表,所有触发器定义都在表的 .TRG 文件中。然而,如果有多个具有相同触发事件和操作时间的触发器,那么服务器在触发事件发生时只执行其中一个。有关 .TRG 文件的信息,请参阅 MySQL 服务器 Doxygen 文档中的表触发器存储部分,位于 https://dev.mysql.com/doc/index-other.html

  • 如果在降级后添加或删除表的触发器,服务器将重写表的 .TRG 文件。重写的文件将只保留每个组合的触发事件和操作时间的一个触发器;其他触发器将丢失。

要避免这些问题,请在降级前修改触发器。对于每个具有多个触发器的表,请将每个触发器组合转换为单个触发器,如下所示:

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

  2. 删除表的所有触发器。

  3. 创建一个新的触发器,用于调用刚刚创建的存储过程。这样,新的触发器的效果将与它所取代的多个触发器相同。