25.7.10 NDB 集群复制:双向和环形复制
可以使用 NDB 集群进行双向复制之间的两个集群之间的复制,以及环形复制之间的任何数量的集群。
环形复制示例。 在下面几段中,我们考虑了三个 NDB 集群编号为 1、2 和 3 的复制设置,其中集群 1 作为集群 2 的复制源,集群 2 作为集群 3 的源,集群 3 作为集群 1 的源。每个集群都有两个 SQL 节点,SQL 节点 A 和 B 属于集群 1,SQL 节点 C 和 D 属于集群 2,SQL 节点 E 和 F 属于集群 3。
环形复制使用这些集群是支持的,只要满足以下条件:
-
所有源和副本的 SQL 节点相同。
-
所有作为源和副本的 SQL 节点都启动时启用系统变量
log_replica_updates
。
这种环形复制设置如以下图所示:
在这个场景中,SQL 节点 A 在集群 1 复制到 SQL 节点 C 在集群 2;SQL 节点 C 复制到 SQL 节点 E 在集群 3;SQL 节点 E 复制到 SQL 节点 A。换言之,复制线(由图中曲线箭头表示)直接连接所有用作复制源和副本的 SQL 节点。
也可以设置环形复制,以便不是所有源 SQL 节点都是副本,如下所示:
在这种情况下,每个集群中的 SQL 节点都用作复制源和副本。您不能启动任何 SQL 节点,以使系统变量log_replica_updates
启用。这类 NDB 集群圆形复制方案,在图中曲线箭头所示的复制链断续,但它应该是可行的,但是还没有经过充分测试,因此仍然需要被视为实验性质。
使用 NDB 本地备份和恢复来初始化副本集群。 在设置环形 replication 时,可以使用管理客户端START BACKUP
命令在一个 NDB 集群上创建备份,然后将该备份应用于另一个 NDB 集群使用ndb_restore。这不自动创建第二个 NDB 集群的 SQL 节点作为副本的二进制日志;为了使二进制日志被创建,您必须在该 SQL 节点上执行SHOW TABLES
语句,然后运行START REPLICA
。这是一个已知的问题。
多源故障转移示例。 在本节中,我们讨论了三个 NDB 集群(服务器 ID 为 1、2 和 3)的多源 NDB 集群复制设置。在这个场景中,集群 1 复制到集群 2 和 3;集群 2 也复制到集群 3。这关系如图所示:
换言之,数据从集群 1 复制到集群 3 通过两个不同的路线:直接和通过集群 2。
不一定所有参与多源复制的 MySQL 服务器都需要同时作为源和副本,一个 NDB 集群可能使用不同的 SQL 节点来处理不同 replication 通道。下面是一个示例:
作为副本的 MySQL 服务器必须使用系统变量 log_replica_updates
运行。前面的图表中还显示了需要启用该选项的 mysqld 进程。
启用 log_replica_updates
系统变量对非副本服务器没有影响。
在一个复制集群失去服务时,需要 failover。例如,我们假设 Cluster 1 失去服务,因此 Cluster 3 丢失了来自 Cluster 1 的两个更新源。由于 NDB 集群之间的复制是异步的,没有保证 Cluster 3 从 Cluster 1 直接收到的更新比通过 Cluster 2 接收的更新更新。你可以通过确保 Cluster 3 在 Cluster 2 中捕捉到来自 Cluster 1 的更新来处理这个问题。在 MySQL 服务器方面,这意味着需要将来自 server C 的任何未完成更新复制到 server F。
在 server 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
表来改进该查询的性能,从而显著地缩短故障转移时间。有关更多信息,请参阅第 25.7.4 节,“NDB 集群复制架构和表”。
将 @file
和 @pos
的值从服务器 C 复制到服务器 F(或由应用程序执行相等的操作)。然后,在服务器 F 上执行以下CHANGE REPLICATION SOURCE TO
语句:
mysqlF> CHANGE REPLICATION SOURCE TO
-> SOURCE_HOST = 'serverC'
-> SOURCE_LOG_FILE='@file',
-> SOURCE_LOG_POS=@pos;
完成后,您可以在 MySQL 服务器 F 上执行START REPLICA
语句,这将导致来自服务器 B 的任何缺失更新被复制到服务器 F。
CHANGE REPLICATION SOURCE TO 语句也支持一个IGNORE_SERVER_IDS
选项,该选项接受一个逗号分隔的服务器 ID 列表,并且会忽略来自对应服务器的事件。请查看该语句的文档,以及Section 15.7.7.34, “SHOW REPLICA STATUS 语句”
。关于该选项与ndb_log_apply_status
变量的交互,请查看Section 25.7.8, “Implementing Failover with NDB Cluster Replication”
.