Documentation Home

17.1.4.2 在线启用 GTID 事务

本节介绍如何在已经在线并使用匿名事务的服务器上启用 GTID 事务和可选的自动定位。此过程不需要使服务器脱机,适合在生产中使用。但是,如果您有可能在启用 GTID 事务时使服务器脱机,则该过程会更容易。

从 MySQL 8.0.23 开始,您可以设置复制通道以将 GTID 分配给还没有复制事务的复制事务。此功能支持从不使用基于 GTID 的复制的源服务器复制到使用的副本。如果可以在复制源服务器上启用 GTID,如本过程中所述,请改用此方法。分配 GTID 是为无法启用 GTID 的复制源服务器设计的。有关此选项的更多信息,请参阅 第 17.1.3.6 节,“从没有 GTID 的源复制到具有 GTID 的副本”

在开始之前,请确保服务器满足以下先决条件:

  • 拓扑中的所有服务器都必须使用 MySQL 5.7.6 或更高版本。除非拓扑中的所有 服务器都使用此版本, 否则您不能在任何单个服务器上在线启用 GTID 事务

  • 所有服务器都gtid_mode 设置为默认值OFF

以下过程可以随时暂停,稍后可以在原处恢复,或者通过跳转到 第 17.1.4.3 节,“在线禁用 GTID 事务”的相应步骤(禁用 GTID的在线过程)来反转。这使得程序具有容错性,因为任何可能出现在程序中间的不相关问题都可以照常处理,然后程序从中断处继续。

笔记

在继续下一步之前完成每个步骤至关重要。

要启用 GTID 事务:

  1. 在每台服务器上,执行:

    SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = WARN;

    让服务器以您的正常工作负载运行一段时间并监视日志。如果此步骤导致日志中出现任何警告,请调整您的应用程序,使其仅使用与 GTID 兼容的功能并且不会生成任何警告。

    重要的

    这是重要的第一步。在进行下一步之前,您必须确保错误日志中没有生成任何警告。

  2. 在每台服务器上,执行:

    SET @@GLOBAL.ENFORCE_GTID_CONSISTENCY = ON;
  3. 在每台服务器上,执行:

    SET @@GLOBAL.GTID_MODE = OFF_PERMISSIVE;

    哪个服务器先执行这个语句并不重要,重要的是所有服务器在任何服务器开始下一步之前完成这个步骤。

  4. 在每台服务器上,执行:

    SET @@GLOBAL.GTID_MODE = ON_PERMISSIVE;

    哪个服务器先执行这条语句并不重要。

  5. 在每台服务器上,等待状态变量 ONGOING_ANONYMOUS_TRANSACTION_COUNT为零。这可以使用以下方法检查:

    SHOW STATUS LIKE 'ONGOING_ANONYMOUS_TRANSACTION_COUNT';
    笔记

    在副本上,理论上可能显示为零,然后再次显示为非零。这不是问题,它显示一次零就足够了。

  6. 等待直到第 5 步生成的所有事务复制到所有服务器。您可以在不停止更新的情况下执行此操作:唯一重要的是所有匿名事务都会被复制。

    有关检查所有匿名事务是否已复制到所有服务器的一种方法, 请参见 第 17.1.4.4 节,“验证匿名事务的复制”。

  7. 如果您将二进制日志用于除复制之外的任何其他用途,例如时间点备份和恢复,请等到您不需要旧的二进制日志具有没有 GTID 的事务。

    例如,在第 6 步完成后,您可以 FLUSH LOGS在要进行备份的服务器上执行。然后明确地进行备份或等待您可能已设置的任何定期备份例程的下一次迭代。

    理想情况下,等待服务器清除在第 6 步完成时存在的所有二进制日志。还要等待在第 6 步之前进行的任何备份过期。

    重要的

    这是第二个重点。重要的是要了解包含匿名事务的二进制日志,没有 GTIDs 不能在下一步之后使用。在此步骤之后,您必须确保没有 GTID 的事务不存在于拓扑中的任何位置。

  8. 在每台服务器上,执行:

    SET @@GLOBAL.GTID_MODE = ON;
  9. 在每台服务器上,添加gtid_mode=ONenforce_gtid_consistency=ONmy.cnf.

    您现在可以保证所有事务都有一个 GTID(在步骤 5 或之前生成的事务除外,它们已经被处理)。要开始使用 GTID 协议以便稍后可以执行自动故障转移,请在每个副本上执行以下操作。或者,如果您使用多源复制,请为每个通道执行此操作并包括以下 子句: FOR CHANNEL channel

    STOP SLAVE [FOR CHANNEL 'channel'];
    CHANGE MASTER TO MASTER_AUTO_POSITION = 1 [FOR CHANNEL 'channel'];
    START SLAVE [FOR CHANNEL 'channel'];
    
    Or from MySQL 8.0.22 / 8.0.23:
    STOP REPLICA [FOR CHANNEL 'channel'];
    CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION = 1 [FOR CHANNEL 'channel'];
    START REPLICA [FOR CHANNEL 'channel'];