21.6.8 使用 NDB 群集复制实现故障转移
如果主群集复制过程失败,则可以切换到辅助复制通道。以下过程描述了完成此操作所需的步骤。
mysqlR'> SELECT @latest:=MAX(epoch)
-> FROM mysql.ndb_apply_status;
在循环复制拓扑中,在每个主机上运行源和副本的情况下,当您使用ndb_log_apply_status=1
时,会将 NDB 群集纪元写入副本的二进制日志中。这意味着ndb_apply_status
table 包含此主机上的副本以及充当此主机上运行的复制源服务器的副本的任何其他主机的信息。
在这种情况下,您需要确定此副本上的最新纪元,以排除此副本的二进制日志中任何其他副本中未用于设置此副本的更改为主语句的IGNORE_SERVER_IDS
选项中未列出的任何纪元。排除此类时期的原因是,mysql.ndb_apply_status
table 中其服务器 ID 与用于准备此副本的源的CHANGE MASTER TO
语句中的IGNORE_SERVER_IDS
列 table 中的服务器 ID 匹配的行也被视为来自本地服务器,除了那些拥有副本自身的服务器之外。服务器 ID。您可以从显示从站状态的输出中以Replicate_Ignore_Server_Ids
的形式检索此列 table。我们假定您已获得此列 table,并在此处显示的查询中将其替换为* ignore_server_ids
*,该查询与先前版本的查询一样,将最大的纪元选择为名为@latest
的变量:
mysqlR'> SELECT @latest:=MAX(epoch)
-> FROM mysql.ndb_apply_status
-> WHERE server_id NOT IN (ignore_server_ids);
在某些情况下,使用要包含的服务器 ID 的列 table 和先前查询的WHERE
条件中的server_id IN server_id_list
可能更简单或更有效(或两者兼有)。
您可以使用以下查询从源上的ndb_binlog_index
table 获取所需的记录:
mysqlS'> SELECT
-> @file:=SUBSTRING_INDEX(next_file, '/', -1),
-> @pos:=next_position
-> FROM mysql.ndb_binlog_index
-> WHERE epoch >= @latest
-> ORDER BY epoch ASC LIMIT 1;
这些是自主复制通道故障以来保存在源上的记录。我们在这里采用了一个用户变量@latest
来 table 示在步骤 1 中获得的值。当然,一个mysqld实例不可能直接访问在另一个服务器实例上设置的用户变量。这些值必须手动或通过应用程序“插入”到第二个查询中。
Important
在执行START SLAVE之前,必须确保副本mysqld以--slave-skip-errors=ddl_exist_errors开头。否则,复制可能会因重复的 DDL 错误而停止。
- 现在可以通过在辅助副本服务器上运行以下查询来同步辅助通道:
mysqlR'> CHANGE MASTER TO
-> MASTER_LOG_FILE='@file',
-> MASTER_LOG_POS=@pos;
同样,我们使用了用户变量(在这种情况下为@file
和@pos
)来 table 示在步骤 2 中获得并在步骤 3 中应用的值;实际上,必须手动插入这些值,或者使用可以访问所涉及的两个服务器的应用程序插入这些值。
Note
@file
是字符串值,例如'/var/log/mysql/replication-source-bin.00001'
,因此在 SQL 或应用程序代码中使用时必须加引号。但是,由@pos
table 示的值必须*不被引用。尽管 MySQL 通常会尝试将字符串转换为数字,但是这种情况是一个 exception。
- 现在,您可以通过在辅助副本mysqld上发布适当的语句来在辅助通道上启动复制:
mysqlR'> START SLAVE;
一旦辅助复制通道处于活动状态,您就可以调查主复制失败并影响修复。为此所需的确切操作将取决于主通道失败的原因。
Warning
仅当主复制通道发生故障时,才可以启动辅助复制通道。同时运行多个复制通道可能导致在副本上创建不必要的重复记录。
如果故障仅限于单个服务器,则从理论上讲应该可以从* S
复制到 R'
,或从 S'
复制到 R
*。