Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


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

25.7.3 NDB 集群复制已知问题

本节讨论使用 NDB 集群 replication 时出现的问题或问题。

源和副本之间的连接丢失  可能会出现源集群 SQL 节点和副本集群 SQL 节点之间的连接丢失,或者是源 SQL 节点和源集群数据节点之间的连接丢失。在后一种情况下,这可能不是由于物理连接中断(例如,网络电缆断开),而是由于数据节点事件缓冲区溢出;如果 SQL 节点响应速度太慢,它可能会被集群drop(这可以通过调整 MaxBufferedEpochsTimeBetweenEpochs 配置参数来控制)。如果出现这种情况,可能会在源集群中插入新数据,而这些数据不被记录到源 SQL 节点的二进制日志中。因此,在确保高可用性时,非常重要的是维护备份复制通道,监控主要通道,并在必要时将副本集群切换到次要复制通道,以保持副本集群与源集群同步。 NDB 集群不设计来自己监控这些问题;因此,需要使用外部应用程序进行监控。

源 SQL 节点在连接或重新连接到源集群时,会发出一个gap事件。 (gap 事件是一种类型的incident event,,表示数据库内容受到影响的事件,但不能轻松地表示为一组更改。例如,服务器故障、数据库重新同步、某些软件更新和硬件变化等都是这种事件的示例。)当复制节点遇到 replication 日志中的gap 时,它将停止并出现错误信息。这条消息可以在SHOW REPLICA STATUS的输出中找到,表明 SQL 线程因 replication 流中的事件注册而停止,并且需要人工干预。请参阅第 25.7.8 节“实现 NDB 集群复制故障转移”,了解在这种情况下所需的操作。

Important

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

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

循环复制 NDB 集群复制支持循环复制,如下所示。复制设置涉及三个 NDB 集群,编号为 1、2 和 3,其中集群 1 作为集群 2 的 replication 源,集群 2 作为集群 3 的源,集群 3 作为集群 1 的源,从而完成循环。每个 NDB 集群都有两个 SQL 节点,其中 SQL 节点 A 和 B 属于集群 1,SQL 节点 C 和 D 属于集群 2,SQL 节点 E 和 F 属于集群 3。

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

  • 所有源和副本集中的 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 复制回 SQL 节点 A。在其他字词,这个复制线(图中用曲线箭头表示)直接连接所有用于源和副本的 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

NDBNDB存储引擎使用idempotent执行模式,该模式抑制了否则会中断 NDB 集群循环复制的重复键和其他错误。这等同于将系统变量replica_exec_mode设置为IDEMPOTENT,虽然在 NDB 集群复制中,这不是必要的,因为 NDB 集群自动将该变量设置为 IDEMPOTENT 并忽略任何尝试设置它的操作。

NDB 集群复制和主键  在节点故障时,NDB表格没有主键的复制错误仍然可能发生,因为在这种情况下可能会插入重复行。因此,对于被复制的NDB表格,强烈建议添加明确的主键。

NDB Cluster Replication 和唯一键。 在 NDB Cluster 早期版本中,更新 NDB 表的唯一键列可能会在复制过程中导致重复键错误。这一问题在 NDB Cluster 8.4 及更高版本中被解决了,这是通过将唯一键检查延迟到所有表行更新完成后来实现的。

这种延迟约束方式目前仅支持 NDB。因此,在从 NDB Cluster 复制到其他存储引擎,如 InnoDBMyISAM 时,更新唯一键仍然不受支持。

在没有延迟检查唯一键更新的情况下,可以使用 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 分区”,了解更多信息。

NDB 不支持 GTIDs。 NDB 存储引擎不兼容全球事务 ID(GTID)复制,并且不受支持。如果启用 GTIDs,可能会导致 NDB 集群复制失败。

使用--initial重启-cluster  使用--initial选项重启集群将GCI和epoch号的顺序从0开始。这通常适用于NDB集群,而不仅限于涉及Cluster的复制场景。参与复制的MySQL服务器应该在这个时候被重启。在这种情况下,您应该使用RESET BINARY LOGS AND GTIDSRESET REPLICA语句来清除无效的ndb_binlog_indexndb_apply_status表 respectively。

NDB到其他存储引擎的复制  可以将NDB表在源端复制到使用不同存储引擎的副本中,考虑以下限制:

  • 多源和环形复制不受支持(源端和副本中的表都必须使用NDB存储引擎才能工作)。

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

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

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

以下几段文字提供了每个问题的详细信息。

NDB 到其他存储引擎的多源不支持. 在从NDB到不同的存储引擎进行复制时,两个数据库之间的关系必须是 one-to-one。这意味着 NDB 集群和其他存储引擎之间不支持双向或循环复制。

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

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(Error 1595)而中止。可以通过以下方法解决这个问题:

  • 在副本上关闭二进制日志 这可以通过设置sql_log_bin = 0来实现。

  • 更改 mysql.ndb_apply_status 表的存储引擎 将这个表使用不支持自己二进制日志的存储引擎也可以解决冲突。这可以通过在副本上执行类似于ALTER TABLE mysql.ndb_apply_status ENGINE=MyISAM的语句来实现。使用其他存储引擎(除了 NDB)在副本上是安全的,因为您不需要担心多个副本保持同步。

  • 过滤 MySQL 中的 mysql.ndb_apply_status 表在复制时的更改 。可以通过使用 --replicate-ignore-table=mysql.ndb_apply_status 启动复制来实现。如果您需要忽略其他表,请使用相应的 --replicate-wild-ignore-table 选项。

Important

不应该禁用对 mysql.ndb_apply_status 表的复制或二进制日志记录,或者更改用于该表的存储引擎,在从一个 NDB 集群到另一个 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 集群之间的复制操作是必需的。在具体来说,您需要注意以下几点:

  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节,“Replication and Binary Logging Options and Variables”

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

如果您正在将NDB集群复制到使用存储引擎不同于NDB的副本,那么前面提到的考虑可能不适用,因为在这个部分中讨论了其他地方。

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

Note

在 NDB 8.4 中,您可以禁用 Linux 内核中的 IPv6 支持,如果您不打算使用 IPv6 地址来为任何 NDB 集群节点进行配置。

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

关于 NDB 集群中的属性提升和降低的更多信息,请见基于行的复制:属性提升和降低

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