本节描述如何在线启用GTID事务,并可选地启用自动定位,在已经在线并使用匿名事务的服务器上。这一过程不需要将服务器离线,并适合生产环境中使用。然而,如果您有可能在启用GTID事务时将服务器离线,那么该过程将更容易。
您可以设置复制通道,以将GTID分配给已经复制的不带GTID的事务。这一功能使得从不使用GTID复制的源服务器到使用GTID复制的副本服务器的复制成为可能。如果可能,在源服务器上启用GTID,如本过程所述,那么请使用这种方法。将GTID分配给不带GTID的事务是为那些无法启用GTID的源服务器设计的。有关这项功能的更多信息,请参见第 19.1.3.6 节,“从不带GTID的源服务器到带GTID的副本服务器的复制”。
在开始之前,请确保gtid_mode
在所有服务器上均为 OFF
。
以下过程可以在任何时候暂停,然后在中断的地方继续,或者通过跳转到第 19.1.4.3 节,“在线禁用GTID事务”的相应步骤来逆转。这使得过程具有容错性,因为在过程中出现的任何无关问题都可以像通常那样处理,然后继续从中断的地方继续。
要启用GTID事务,您必须完成每个步骤,然后继续下一个步骤。
-
在每个服务器上,执行以下语句:
SET @@GLOBAL.enforce_gtid_consistency = WARN;
让服务器在正常工作负载下运行一段时间,并监控日志。如果这步骤在日志中引发任何警告,请调整应用程序,以便它仅使用GTID兼容的功能,不生成任何警告。
-
在每个服务器上,执行以下语句:
SET @@GLOBAL.enforce_gtid_consistency = ON;
-
在每个服务器上,执行以下语句:
SET @@GLOBAL.gtid_mode = OFF_PERMISSIVE;
服务器执行该语句的顺序无关紧要,但所有服务器必须在开始下一步骤之前执行该语句。
-
在每个服务器上,执行以下语句:
SET @@GLOBAL.gtid_mode = ON_PERMISSIVE;
与前一步骤一样,服务器执行该语句的顺序无关紧要,只要每个服务器在继续下一步骤之前执行该语句。
-
在每个服务器上,等待
Ongoing_anonymous_transaction_count
为0
。您可以使用SHOW STATUS
语句来检查其值,如下所示:mysql> SHOW STATUS LIKE 'Ongoing%'; +-------------------------------------+-------+ | Variable_name | Value | +-------------------------------------+-------+ | Ongoing_anonymous_transaction_count | 0 | +-------------------------------------+-------+ 1 row in set (0.00 sec)
在副本服务器上,理论上可能出现这种情况,即该值先为
0
,然后再变为非零值。这不是问题,只要该值至少有一次为0
。 -
等待所有在前一步骤生成的交易复制到所有服务器。您可以在不停止更新的情况下执行此操作;重要的是所有匿名交易都复制到所有服务器之前继续下一步骤。
请参见第 19.1.4.4 节,“验证匿名交易的复制”,以获取验证所有匿名交易都已复制到所有服务器的一种方法。
-
如果您使用二进制日志来执行其他操作,而不仅仅是复制,例如点时间备份和恢复,请等待您不再需要包含无GTID事务的旧二进制日志。
例如,在所有交易都已复制到所有服务器后,您可以在备份服务器上执行
FLUSH LOGS
。然后,或者明确地执行备份,或者等待下一个周期性的备份routine。理想情况下,您应该等待服务器清除所有在前一步骤完成时存在的二进制日志,并等待在那之前采取的备份到期。
请注意,包含匿名交易(即不带GTID的事务)的二进制日志不能在下一步骤后使用,因此您必须确保在任何服务器上都没有未提交的匿名交易。
-
在每个服务器上,执行以下语句:
SET @@GLOBAL.GTID_MODE = ON;
-
在每个服务器上,添加
gtid-mode=ON
和enforce-gtid-consistency=ON
到my.cnf
。这保证了所有未处理的事务都使用 GTID。要开始使用 GTID 协议,以便后续执行自动故障转移,请在每个副本上执行下一组语句。如果您使用多源复制,请为每个通道执行此操作,包括FOR CHANNEL
子句:channel
STOP REPLICA [FOR CHANNEL 'channel']; CHANGE REPLICATION SOURCE TO SOURCE_AUTO_POSITION = 1 [FOR CHANNEL 'channel']; START REPLICA [FOR CHANNEL 'channel'];