Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  Known Issues in NDB Cluster Replication

25.7.3 NDB 集群复制已知问题

本节讨论使用 NDB 集群复制时的已知问题。

源和副本之间的连接丢失。 连接丢失可能发生在源集群 SQL 节点和副本集群 SQL 节点之间,也可能发生在源 SQL 节点和源集群数据节点之间。在后一种情况下,这可能是由于数据节点事件缓冲区溢出;如果 SQL 节点响应太慢,它可能被集群删除(这可以通过调整 MaxBufferedEpochsTimeBetweenEpochs 配置参数来控制)。如果发生这种情况,新数据可能被插入到源集群中,而不被记录在源 SQL 节点的二进制日志中。因此,为了保证高可用性,非常重要的是维护一个备份复制通道,监控主通道,并在必要时 failover 到次要复制通道,以保持副本集群与源集群同步。NDB 集群本身不设计监控复制状态或提供故障转移;为此,需要外部应用程序。

源 SQL 节点在连接或重新连接到源集群时发出“gap”事件。(gap 事件是一种“incident 事件”,指的是影响数据库内容但无法轻松表示为更改集的事件。示例包括服务器故障、数据库重新同步、一些软件更新和一些硬件更改。)当副本遇到复制日志中的 gap 时,它将停止并显示错误消息。该消息可在 SHOW REPLICA STATUS 的输出中找到,表明 SQL 线程由于复制流中的事件而停止,并且需要手动干预。请参阅 第 25.7.8 节,“使用 NDB 集群复制实现故障转移”,以获取更多关于在这种情况下该做什么的信息。

Important

因为 NDB 集群本身不设计监控复制状态或提供故障转移,因此,如果高可用性是副本服务器或集群的要求,那么您必须设置多个复制线路,监控主复制线路上的源 mysqld,并准备在必要时 failover 到次要线路。必须手动或通过第三方应用程序来实现这种设置。有关实现这种设置的信息,请参阅 第 25.7.7 节,“使用两个复制通道进行 NDB 集群复制”第 25.7.8 节,“使用 NDB 集群复制实现故障转移”

如果您从独立的 MySQL 服务器复制到 NDB 集群,一般来说一个通道就足够。

循环复制。 NDB 集群复制支持循环复制,如下所示的示例所示。复制设置涉及三个 NDB 集群,编号为 1、2 和 3,其中 Cluster 1 作为 Cluster 2 的复制源,Cluster 2 作为 Cluster 3 的源,Cluster 3 作为 Cluster 1 的源,从而形成一个循环。

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

  • 所有源和副本集群的 SQL 节点相同。

  • 所有源和副本集群的 SQL 节点都启用了系统变量 log_replica_updates

这种循环复制设置如以下图所示:

图 25.11 NDB 集群循环复制,所有源作为副本

Some content is described in the surrounding text. The diagram shows three clusters, each with two nodes. Arrows connecting SQL nodes in different clusters illustrate that all sources are also replicas.

在这个场景中,Cluster 1 中的 SQL 节点 A 将数据复制到 Cluster 2 中的 SQL 节点 C;SQL 节点 C 将数据复制到 Cluster 3 中的 SQL 节点 E;SQL 节点 E 将数据复制到 Cluster 1 中的 SQL 节点 A。在其他 words,复制线(图中的弯曲箭头)直接连接所有用作源和副本的 SQL 节点。

也可以设置圆形复制,其中不是所有源 SQL 节点都是副本,如下所示:

图 25.12 NDB 集群圆形复制,其中不是所有源都是副本

Some content is described in the surrounding text. The diagram shows three clusters, each with two nodes. Arrows connecting SQL nodes in different clusters illustrate that not all sources are replicas.

在这种情况下,每个集群中的不同 SQL 节点用作源和副本。但是,您不能在任何 SQL 节点上启用 log_replica_updates 系统变量。这类圆形复制方案对于 NDB 集群,复制线(图中的弯曲箭头)是断开的,应该是可能的,但尚未经过彻底测试,因此仍然是实验性的。

Note

NDB 存储引擎使用 幂等执行模式,该模式抑制了重复键和其他错误,这些错误否则会破坏圆形复制的 NDB 集群。这相当于将系统变量 replica_exec_mode 设置为 IDEMPOTENT,尽管这在 NDB 集群复制中不是必要的,因为 NDB 集群自动设置该变量并忽略任何明确设置尝试。

NDB 集群复制和主键。 如果节点失败,在没有主键的 NDB 表中复制时,仍然可能出现错误。这是因为可能会插入重复行。在这种情况下,强烈建议所有要复制的 NDB 表都具有明确的主键。

NDB 集群复制和唯一键。 在 NDB 集群的旧版本中,对唯一键列的更新操作可能会导致复制时的重复键错误。这个问题现在已经解决了,因为 NDB 集群现在可以延迟唯一键检查,直到所有表行更新完成。

这种延迟约束检查目前仅支持 NDB 集群。因此,从 NDB 集群到其他存储引擎(如 InnoDB 或 MyISAM)复制时,更新唯一键仍然不支持。

可以使用 NDB 表(如 t)来说明没有延迟唯一键检查时复制的问题,如下所示:

CREATE TABLE t (
    p INT PRIMARY KEY,
    c INT,
    UNIQUE KEY u (c)
)   ENGINE NDB;

INSERT INTO t
    VALUES (1,1), (2,2), (3,3), (4,4), (5,5);

以下 UPDATE 语句在源上成功,因为受影响的行按照 ORDER BY 选项确定的顺序进行处理:

UPDATE t SET c = c - 1 ORDER BY p;

同样的语句在副本上失败,出现重复键错误或其他约束违规,因为行更新的顺序是按分区进行的,而不是整个表。

Note

每个 NDB 表在创建时隐式地按键分区。请参阅 第 26.2.5 节,“KEY 分区”,以获取更多信息。

GTIDs 不支持。 使用全局事务 ID 的复制与 NDB 存储引擎不兼容,不支持。启用 GTIDs 可能会导致 NDB 集群复制失败。

使用 --initial 重新启动。 使用 --initial 选项重新启动集群将从 0 开始 GCI 和 epoch 号码序列。(这在 NDB 集群中普遍适用,而不仅限于涉及集群的复制场景。) 在这种情况下,参与复制的 MySQL 服务器应该重新启动。然后,您应该使用 RESET BINARY LOGS AND GTIDSRESET REPLICA 语句来清除无效的 ndb_binlog_indexndb_apply_status 表,分别。

从 NDB 到其他存储引擎的复制。 可以将源 NDB 表复制到使用不同存储引擎的表,考虑以下限制:

  • 多源和循环复制不受支持(源和副本上的表必须使用 NDB 存储引擎以使其生效)。

  • 使用不执行二进制日志记录的存储引擎的表在副本上需要特殊处理。

  • 使用非事务性存储引擎的表在副本上也需要特殊处理。

  • mysqld 必须使用 --ndb-log-update-as-write=0--ndb-log-update-as-write=OFF 启动。

接下来几段落提供了每个问题的更多信息。

从 NDB 到其他存储引擎的复制不支持多源。NDB 到不同存储引擎的复制关系必须是一对一的。这意味着双向或循环复制在 NDB 集群和其他存储引擎之间不受支持。

此外,从 NDB 到不同存储引擎的复制不能配置多个复制通道。(NDB 集群数据库 可以 同时复制到多个 NDB 集群数据库。)如果源使用 NDB 表,仍然可以让多个 MySQL 服务器维护二进制日志的所有更改,但为了使副本更改源(故障转移),新的源副本关系必须在副本上明确定义。

将 NDB 表复制到不执行二进制日志记录的存储引擎。 如果您尝试从 NDB 集群复制到使用不执行二进制日志记录的存储引擎的副本,复制过程将中止并显示错误 Binary logging not possible ... Statement cannot be written atomically since more than one engine involved and at least one engine is self-logging(错误 1595)。可以通过以下方式解决此问题:

Important

您不应该 禁用 复制或二进制日志记录 mysql.ndb_apply_status 或更改用于此表的存储引擎,当从一个 NDB 集群复制到另一个时。请参阅 复制和二进制日志过滤规则与 NDB 集群之间的复制,以获取详细信息。

从 NDB 复制到非事务性存储引擎。 当从 NDB 复制到非事务性存储引擎,如 MyISAM 时,您可能会遇到不必要的重复键错误,当复制 INSERT ... ON DUPLICATE KEY UPDATE 语句时。您可以使用 --ndb-log-update-as-write=0,强制更新被记录为写入,而不是更新。

复制和二进制日志过滤规则与 NDB 集群之间的复制。 如果您使用任何选项 --replicate-do-*--replicate-ignore-*--binlog-do-db--binlog-ignore-db 来过滤正在复制的数据库或表格,您必须小心不要阻止 mysql.ndb_apply_status 的复制或二进制日志记录,这是 NDB 集群之间的复制所需的。在 particular,您必须牢记以下几点:

  1. 使用 --replicate-do-db=db_name(且不使用其他 --replicate-do-*--replicate-ignore-* 选项)意味着 复制数据库 db_name 中的表格。在这种情况下,您也应该使用 --replicate-do-db=mysql--binlog-do-db=mysql--replicate-do-table=mysql.ndb_apply_status,以确保 mysql.ndb_apply_status 在副本上被填充。

    使用 --binlog-do-db=db_name(且不使用其他 --binlog-do-db 选项)意味着 将数据库 db_name 中的表格更改写入二进制日志。在这种情况下,您也应该使用 --replicate-do-db=mysql--binlog-do-db=mysql--replicate-do-table=mysql.ndb_apply_status,以确保 mysql.ndb_apply_status 在副本上被填充。

  2. 使用 --replicate-ignore-db=mysql 意味着不复制 mysql 数据库中的任何表格。在这种情况下,您也应该使用 --replicate-do-table=mysql.ndb_apply_status,以确保 mysql.ndb_apply_status 被复制。

    使用 --binlog-ignore-db=mysql 意味着不将 mysql 数据库中的任何表格更改写入二进制日志。在这种情况下,您也应该使用 --replicate-do-table=mysql.ndb_apply_status,以确保 mysql.ndb_apply_status 被复制。

您还应该记住,每个复制规则都需要以下几点:

  1. 它自己的 --replicate-do-*--replicate-ignore-* 选项,并且多个规则不能在单个复制过滤选项中表达。有关这些规则的信息,请参阅 第 19.1.6 节,“复制和二进制日志记录选项和变量”

  2. 它自己的 --binlog-do-db--binlog-ignore-db 选项,并且多个规则不能在单个二进制日志过滤选项中表达。有关这些规则的信息,请参阅 第 7.4.4 节,“二进制日志”

如果您正在将 NDB 集群复制到使用其他存储引擎(而不是 NDB)的副本上,那么前面提到的考虑可能不适用,如本节其他地方所讨论的那样。

NDB 集群复制和 IPv6。 在 NDB 8.3 中,所有类型的 NDB 集群节点都支持 IPv6,包括管理节点、数据节点和 API 或 SQL 节点。

Note

在某些以前的版本中,NDB 无法在没有操作系统 IPv6 支持的情况下成功启动,即使没有使用 IPv6 地址。这不是 NDB 8.1 的问题,在这里您可以禁用 Linux 内核中的 IPv6 支持,如果您不打算使用 IPv6 地址来连接任何 NDB 集群节点。

属性升级和降级。 NDB 集群复制包括对属性升级和降级的支持。后者的实现区分了损失和非损失类型转换,并且可以通过设置系统变量 replica_type_conversions 的全局值来控制副本上的使用。

有关 NDB 集群中的属性升级和降级的更多信息,请参阅 基于行的复制:属性升级和降级

NDB,与 InnoDBMyISAM 不同, 不会将虚拟列的更改写入二进制日志;然而,这对 NDB 集群复制或 NDB 和其他存储引擎之间的复制没有不良影响。存储生成列的更改将被记录。