如果主集群复制过程发生故障,则可以切换到辅助复制通道。以下步骤描述了完成此操作所需的步骤。
获取最近一次全局检查点 (GCP) 的时间。也就是说,您需要确定副本集群中
ndb_apply_status
表中的最新纪元,可以使用以下查询找到它mysqlR'> SELECT @latest:=MAX(epoch) -> FROM mysql.ndb_apply_status;
在循环复制拓扑中,当您使用
ndb_log_apply_status=1
时,每个主机上都运行着源和副本,NDB Cluster 纪元被写入副本的二进制日志。这意味着ndb_apply_status
表包含有关此主机上的副本以及充当运行在此主机上的复制源服务器的副本的任何其他主机的信息。在这种情况下,您需要确定此副本上的最新纪元,排除其二进制日志中任何其他副本的任何纪元,这些纪元未在用于设置此副本的
CHANGE REPLICATION SOURCE TO
语句的IGNORE_SERVER_IDS
选项中列出。排除这些纪元的原因是,在mysql.ndb_apply_status
表中,其服务器 ID 与用于准备此副本源的CHANGE REPLICATION SOURCE TO
语句中的IGNORE_SERVER_IDS
列表中的服务器 ID 相匹配的行的服务器 ID 除了拥有副本的服务器 ID 之外,也被视为来自本地服务器。您可以从SHOW REPLICA STATUS
的输出中检索此列表为Replicate_Ignore_Server_Ids
。我们假设您已经获得了此列表,并将它替换为此处显示的查询中的ignore_server_ids
,它与之前版本的查询类似,将最大纪元选择到名为@latest
的变量中mysqlR'> SELECT @latest:=MAX(epoch) -> FROM mysql.ndb_apply_status -> WHERE server_id NOT IN (ignore_server_ids);
在某些情况下,使用要包含的服务器 ID 列表和
server_id IN
在之前查询的server_id_list
WHERE
条件中可能更简单或更高效(或两者兼而有之)。使用从步骤 1 中的查询获得的信息,从源集群的
ndb_binlog_index
表中获取相应的记录。您可以使用以下查询从源的
ndb_binlog_index
表中获取所需的记录mysqlS'> SELECT -> @file:=SUBSTRING_INDEX(next_file, '/', -1), -> @pos:=next_position -> FROM mysql.ndb_binlog_index -> WHERE epoch = @latest;
这些是自主复制通道发生故障以来在源上保存的记录。我们在这里使用了一个用户变量
@latest
来表示在步骤 1 中获得的值。当然,一个 mysqld 实例无法直接访问在另一个服务器实例上设置的用户变量。这些值必须手动或通过应用程序“插入”到第二个查询中。重要您必须确保副本 mysqld 在执行
START REPLICA
之前使用--replica-skip-errors=ddl_exist_errors
启动。否则,复制可能会因重复的 DDL 错误而停止。现在可以通过在辅助副本服务器上运行以下查询来同步辅助通道
mysqlR'> CHANGE REPLICATION SOURCE TO -> SOURCE_LOG_FILE='@file', -> SOURCE_LOG_POS=@pos;
我们再次使用用户变量(在本例中为
@file
和@pos
)来表示在步骤 2 中获得的值并在步骤 3 中应用的值;实际上,这些值必须手动插入或使用可以访问这两个服务器的应用程序插入。注意@file
是一个字符串值,例如'/var/log/mysql/replication-source-bin.00001'
,因此在 SQL 或应用程序代码中使用时必须加引号。但是,@pos
表示的值必须不加引号。虽然 MySQL 通常尝试将字符串转换为数字,但本例除外。您现在可以在辅助副本 mysqld 上发出适当的命令,在辅助通道上启动复制
mysqlR'> START REPLICA;
辅助复制通道激活后,您可以调查主通道的故障并进行修复。执行此操作所需的具体操作取决于主通道发生故障的原因。
只有在主复制通道发生故障时才应启动辅助复制通道。同时运行多个复制通道会导致副本上意外创建重复记录。
如果故障仅限于单个服务器,理论上应该可以从 S
复制到 R'
,或者从 S'
复制到 R
。