Documentation Home
MySQL 8.0 参考手册  / 第 23 章 MySQL NDB Cluster 8.0  / 23.7 NDB 集群复制  /  21.7.10 NDB Cluster 复制:双向和循环复制

21.7.10 NDB Cluster 复制:双向和循环复制

可以使用 NDB Cluster 在两个集群之间进行双向复制,也可以在任意数量的集群之间进行循环复制。

循环复制示例。  在接下来的几段中,我们考虑涉及三个编号为 1、2 和 3 的 NDB 集群的复制设置示例,其中集群 1 作为集群 2 的复制源,集群 2 作为集群 3 的源,集群3 作为集群 1 的源。每个集群有两个 SQL 节点,SQL 节点 A 和 B 属于集群 1,SQL 节点 C 和 D 属于集群 2,SQL 节点 E 和 F 属于集群 3。

只要满足以下条件,就支持使用这些集群的循环复制:

  • 所有源和副本上的 SQL 节点都相同。

  • 所有充当源和副本的 SQL 节点都在log_slave_updates启用系统变量的情况下启动。

这种类型的循环复制设置如下图所示:

图 21.17 NDB Cluster 循环复制所有源作为副本

一些内容在周围的文本中描述。 该图显示了三个集群,每个集群有两个节点。 连接不同集群中 SQL 节点的箭头说明所有源也是副本。

在这个场景中,Cluster 1 中的 SQL 节点 A 复制到 Cluster 2 中的 SQL 节点 C;SQL节点C复制到Cluster 3中的SQL节点E;SQL节点E复制到SQL节点A,即复制线(图中弯箭头所示)直接连接所有作为复制源和副本的SQL节点。

也可以以并非所有源 SQL 节点都是副本的方式设置循环复制,如下所示:

图 21.18 并非所有源都是副本的 NDB Cluster 循环复制

一些内容在周围的文本中描述。 该图显示了三个集群,每个集群有两个节点。 连接不同集群中的 SQL 节点的箭头说明并非所有源都是副本。

在这种情况下,每个集群中的不同 SQL 节点用作复制源和副本。您 不得log_slave_updates在启用系统变量的情况下启动任何 SQL 节点 。NDB Cluster 的这种循环复制方案,其中复制线(再次由图中的弯曲箭头指示)是不连续的,应该是可能的,但应该注意的是,它尚未经过彻底测试,因此必须仍然被认为是实验性的。

使用 NDB-native 备份和恢复来初始化副本集群。  设置循环复制时,可以通过 START BACKUP在一个 NDB Cluster 上使用管理客户端命令来初始化副本集群以创建备份,然后使用ndb_restore在另一个 NDB Cluster 上应用此备份。这不会在充当副本的第二个 NDB Cluster 的 SQL 节点上自动创建二进制日志;为了创建二进制日志,您必须 SHOW TABLES在该 SQL 节点上发出一条语句;这应该在运行之前完成 START SLAVE。这是一个已知的问题。

多源故障转移示例。  在本节中,我们讨论多源 NDB Cluster 复制设置中的故障转移,其中三个 NDB Clusters 的服务器 ID 为 1、2 和 3。在这种情况下,Cluster 1 复制到 Clusters 2 和 3;集群 2 也复制到集群 3。这种关系如下所示:

图 21.19 具有 3 个源的 NDB Cluster 多主复制

具有服务器 ID 1、2 和 3 的三个 NDB 集群的多源 NDB 集群复制设置; 集群 1 复制到集群 2 和 3; 集群 2 也复制到集群 3。

换句话说,数据通过 2 条不同的路径从集群 1 复制到集群 3:直接复制和通过集群 2。

并非所有参与多源复制的 MySQL 服务器都必须同时充当源和副本,并且给定的 NDB Cluster 可能对不同的复制通道使用不同的 SQL 节点。此处显示了这种情况:

图 21.20 NDB Cluster 多源复制,使用 MySQL 服务器

概念在周围的文本中进行了描述。 显示三个节点:Cluster 1中的SQL节点A复制到Cluster 3中的SQL节点F; 集群 1 中的 SQL 节点 B 复制到集群 2 中的 SQL 节点 C; 集群 3 中的 SQL 节点 E 复制到集群 3 中的 SQL 节点 G。集群 1 中的 SQL 节点 A 和 B 具有 --log-slave-updates=0; Cluster 2中的SQL节点C,Cluster 3中的SQL节点F和G都有--log-slave-updates=1; 集群 2 中的 SQL 节点 D 和 E 具有 --log-slave-updates=0。

作为副本的 MySQL 服务器必须在 log_slave_updates启用系统变量的情况下运行。上图中还显示了 哪些mysqld进程需要此选项。

笔记

使用log_slave_updates 系统变量对不作为副本运行的服务器没有影响。

当其中一个复制集群出现故障时,就会出现故障转移的需要。在此示例中,我们考虑 Cluster 1 丢失服务的情况,因此 Cluster 3 丢失来自 Cluster 1 的 2 个更新源。因为 NDB Clusters 之间的复制是异步的,所以不能保证 Cluster 3 的更新直接来自 Cluster 1比通过集群 2 收到的更新更新。您可以通过确保集群 3 在集群 1 的更新方面赶上集群 2 来处理此问题。就 MySQL 服务器而言,这意味着您需要从 MySQL 复制任何未完成的更新服务器C到服务器F。

在服务器 C 上,执行以下查询:

mysqlC> SELECT @latest:=MAX(epoch)
     ->     FROM mysql.ndb_apply_status
     ->     WHERE server_id=1;

mysqlC> SELECT
     ->     @file:=SUBSTRING_INDEX(File, '/', -1),
     ->     @pos:=Position
     ->     FROM mysql.ndb_binlog_index
     ->     WHERE orig_epoch >= @latest
     ->     AND orig_server_id = 1
     ->     ORDER BY epoch ASC LIMIT 1;
笔记

您可以通过向表中添加适当的索引来提高此查询的性能,从而可能显着加快故障转移时间ndb_binlog_index。有关更多信息,请参阅 第 21.7.4 节,“NDB Cluster 复制模式和表”

@file将和 的值@pos手动从服务器 C 复制到服务器 F(或让您的应用程序执行等效操作)。然后在服务器F上,执行如下CHANGE MASTER TO语句:

mysqlF> CHANGE MASTER TO
     ->     MASTER_HOST = 'serverC'
     ->     MASTER_LOG_FILE='@file',
     ->     MASTER_LOG_POS=@pos;

完成后,您可以 START SLAVE在 MySQL 服务器 F 上发出一条语句;这会导致将源自服务器 B 的任何缺失更新复制到服务器 F。

CHANGE MASTER TO语句还支持一个IGNORE_SERVER_IDS选项,该选项采用逗号分隔的服务器 ID 列表,并导致忽略来自相应服务器的事件。有关详细信息,请参阅第 13.4.2.1 节,“CHANGE MASTER TO 语句”第 13.7.5.34 节,“SHOW SLAVE STATUS 语句”。有关此选项如何与 ndb_log_apply_status变量交互的信息,请参阅第 21.7.8 节,“使用 NDB Cluster 复制实现故障转移”