21.6.3 NDB 群集复制中的已知问题

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

源和副本之间的连接丢失. 源群集 SQL 节点和副本群集 SQL 节点之间或源 SQL 节点和源群集的数据节点之间可能会发生连接丢失。在后一种情况下,这不仅可能是由于物理连接丢失(例如,网络电缆断开)引起的,而且还可能是由于数据节点事件缓冲区的溢出而引起的。如果 SQL 节点的响应速度太慢,则群集可能会将其丢弃(这可以通过调整MaxBufferedEpochsTimeBetweenEpochs配置参数在某种程度上控制)。如果发生这种情况,完全有可能将新数据插入到源群集中,而不会记录在源 SQL 节点的二进制日志中。因此,为了确保高可用性,维护备份复制通道,监视主通道以及在必要时将故障转移到辅助复制通道以保持副本群集与源同步非常重要。 NDB Cluster 并非旨在自行执行此类监视。为此,需要外部应用程序。

源 SQL 节点在连接或重新连接到源群集时会发出“间隙”事件。 (间隔事件是“事件事件”的一种,它 table 示发生的事件会影响数据库的内容,但不能轻易地 table 示为一组更改.事件的示例包括服务器故障,数据库重新同步,某些软件更新,以及某些硬件更改.)当副本在复制日志中遇到间隔时,它将停止并显示一条错误消息。该消息在显示从站状态的输出中可用,并且指示 SQL 线程由于复制流中注册的事件而停止,并且需要手动干预。请参阅第 21.6.8 节“使用 NDB 群集复制实现故障转移”,以获取有关在这种情况下该怎么做的更多信息。

Important

因为 NDB 群集不是单独设计来监视复制状态或提供故障转移,所以如果副本服务器或群集要求高可用性,则必须设置多条复制行,监视主复制行上的源mysqld,并且准备在必要时故障转移到辅助线路。必须手动完成此操作,或者可能通过第三方应用程序完成。有关实现这种类型的设置的信息,请参见第 21.6.7 节“使用两个复制通道进行 NDB 群集复制”第 21.6.8 节“使用 NDB 群集复制实现故障转移”

如果要从独立的 MySQL 服务器复制到 NDB 群集,通常一个通道就足够了。

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

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

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

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

下图显示了这种类型的循环复制设置:

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

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

在这种情况下,群集 1 中的 SQL 节点 A 复制到群集 2 中的 SQL 节点 C。 SQL 节点 C 复制到群集 3 中的 SQL 节点 E; SQL 节点 E 复制到 SQL 节点 A。换句话说,复制线(由图中的弯曲箭头指示)直接连接用作源和副本的所有 SQL 节点。

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

图 21.45 并非所有源都是副本的 NDB 群集循环复制

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

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

Note

NDB存储引擎使用幂等执行模式,该模式可消除重复键和其他错误,否则这些错误会破坏 NDB 群集的循环复制。这等效于将全局slave_exec_mode系统变量设置为IDEMPOTENT,尽管在 NDB Cluster 复制中这不是必需的,因为 NDB Cluster 会自动设置此变量,而忽略任何显式设置的尝试。

NDB 群集复制和主键. 如果发生节点故障,由于在这种情况下可能会插入重复的行,因此仍会发生没有主键的NDBtable 的复制错误。因此,强烈建议所有要复制的NDBtable 都具有显式主键。

NDB 群集复制和唯一键. 在旧版本的 NDB 群集中,更新NDBtable 的唯一键列的值的操作在复制时可能导致重复键错误。通过将唯一键检查推迟到所有 table 行更新执行之后,解决了NDBtable 之间复制的问题。

目前只有NDB支持以这种方式延迟约束。因此,当从NDB复制到另一个存储引擎(例如InnoDBMyISAM)时,仍不支持唯一键的更新。

可以使用NDBtable(例如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);

以下关于tUPDATE语句在源上成功,因为受影响的行是按ORDER BY选项确定的 Sequences 处理的,并在整个 table 上执行:

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

相同的语句将失败,并在副本上出现重复键错误或其他约束冲突,因为行更新的 Sequences 是一次对一个分区执行,而不是对整个 table 执行。

Note

每个NDBtable 在创建时都按键隐式分区。有关更多信息,请参见第 22.2.5 节“密钥分区”

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

不支持多线程副本. NDB Cluster 不支持多线程副本,并且设置相关的系统变量(例如slave_parallel_workersslave_checkpoint_groupslave_checkpoint_group(或等效的mysqld启动选项))无效。

这是因为如果副本是在同一时期内编写的,则副本可能无法将一个数据库中发生的事务与另一数据库中发生的事务分开。此外,由于需要更新mysql.ndb_apply_statustable(请参见第 21.6.4 节“ NDB 群集复制架构和 table”),因此NDB存储引擎处理的每个事务都至少涉及两个数据库-目标数据库和mysql系统数据库。这反过来又 break 了多线程对事务特定于给定数据库的要求。

使用--initial 重新启动. 使用--initial选项重新启动群集会导致 GCI 和纪元编号的序列从0重新开始。 (对于 NDB Cluster,通常是这样,不限于涉及 Cluster 的复制方案.)在这种情况下,应重新启动涉及复制的 MySQL 服务器。此后,您应该使用RESET MASTERRESET SLAVE语句分别清除无效的ndb_binlog_indexndb_apply_statustable。

从 NDB 复制到其他存储引擎. 考虑到此处列出的限制,可以使用副本上的其他存储引擎将源上的NDBtable 复制到 table。

  • 不支持多源和循环复制(源和副本上的 table 都必须使用NDB存储引擎才能正常工作)。

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

  • 对于副本上的 table 使用非事务性存储引擎,还需要进行特殊处理。

  • mysqld必须以--ndb-log-update-as-write=0--ndb-log-update-as-write=OFF开头。

接下来的几段提供了有关刚刚描述的每个问题的其他信息。

将 NDB 复制到其他存储引擎时,不支持多个源. 要从NDB复制到另一个存储引擎,两个数据库之间的关系必须是一对一的。这意味着 NDB Cluster 和其他存储引擎之间不支持双向或循环复制。

此外,在NDB和其他存储引擎之间进行复制时,不能配置多个复制通道。 (一个 NDB 群集数据库可以同时复制到多个 NDB 群集数据库.)如果源使用NDBtable,仍然可以有多个 MySQL 服务器维护所有更改的二进制日志,但是副本可以更改源(故障转移),则必须在副本上显式定义新的源副本关系。

将 NDBtable 复制到不执行二进制日志记录的存储引擎. 如果尝试从 NDB 群集复制到使用不处理自身二进制日志记录的存储引擎的副本,复制过程将中止错误无法执行二进制日志记录...不能自动编写语句,因为涉及多个引擎并且至少一个引擎是自日志记录的(错误 1595)。可以通过以下方式之一解决此问题:

  • 关闭副本上的二进制日志记录. 可以通过设置sql_log_bin = 0来完成。

  • 更改用于 mysql.ndb_apply_statustable 的存储引擎. 使该 table 使用不处理自己的二进制日志记录的引擎也可以消除冲突。这可以通过在副本上发出诸如ALTER TABLE mysql.ndb_apply_status ENGINE = MyISAM之类的语句来完成。在副本上使用NDB以外的存储引擎时,这样做是安全的,因为您不必担心保持多个副本同步。

  • 过滤掉副本上 mysql.ndb_apply_statustable 的更改. 可以通过以--replicate-ignore-table=mysql.ndb_apply_status启动副本来完成。如果您需要复制忽略其他 table,则可能希望使用适当的--replicate-wild-ignore-table选项。

Important

从一个 NDB 群集复制到另一个 NDB 群集时,您应**禁用复制或mysql.ndb_apply_status的二进制日志记录或更改用于此 table 的存储引擎。有关详细信息,请参见在 NDB 群集之间进行复制的复制和二进制日志过滤规则

从 NDB 复制到非事务存储引擎. 当从NDB复制到非事务存储引擎(如MyISAM)时,在复制插入...在重复的密钥更新上语句时可能会遇到不必要的重复键错误。您可以使用--ndb-log-update-as-write=0禁止显示这些内容,这会强制将更新记录为写入记录而不是更新记录。

在 NDB 群集之间进行复制的复制和二进制日志过滤规则. 如果使用--replicate-do-*--replicate-ignore-*--binlog-do-db--binlog-ignore-db中的任何一个选项来过滤要复制的数据库或 table,则必须注意不要阻止复制或复制。 mysql.ndb_apply_status的二进制日志记录,这是 NDB 群集之间的复制正常运行所必需的。特别是,您必须牢记以下几点:

使用--binlog-do-db=db_name(并且没有其他--binlog-do-db选项)意味着对数据库中 table 的更改db_name *被写入二进制日志。在这种情况下,还应该使用--replicate-do-db=mysql--binlog-do-db=mysql--replicate-do-table=mysql.ndb_apply_status来确保在副本上填充mysql.ndb_apply_status

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

您还应该记住,每个复制规则都需要满足以下条件:

如果要将 NDB 群集复制到使用NDB以外的存储引擎的副本,则前面提到的注意事项可能不适用,如本节其他地方所述。

NDB 群集复制和 IPv6. 当前,NDB API 和 MGM API 不支持 IPv6.但是,MySQL 服务器(包括那些在 NDB 群集中充当 SQL 节点的服务器)可以使用 IPv6 与其他 MySQL 服务器联系。这意味着您可以使用 IPv6 在 NDB 群集之间进行复制,以连接源 SQL 节点和副本 SQL 节点,如下图中的虚线箭头所示:

图 21.46 使用 IPv6 连接的 SQL 节点之间的复制

大多数内容在周围的文本中描述。table 示 MySQL 到 MySQL 的 IPv6 连接的虚线在两个节点之间,每个节点分别来自源群集和副本群集。群集中的所有连接(例如,数据节点到数据节点或数据节点到 Management 节点)均用实线连接,仅指示 IPv4 连接。

在 NDB 群集内(在该数据库内)发起的所有连接(在上图中用实线箭头 table 示)必须使用 IPv4.换句话说,必须使用 IPv4 相互访问所有 NDB Cluster 数据节点,Management 服务器和 ManagementClient 端。此外,SQL 节点必须使用 IPv4 与群集进行通信。

由于 NDB 和 MGM API 当前不支持 IPv6,因此使用这些 API 编写的任何应用程序还必须使用 IPv4 进行所有连接。

属性升级和降级. NDB 群集复制包括对属性升级和降级的支持。后者的实现区分有损类型转换和非有损类型转换,可以通过设置slave_type_conversions全局服务器系统变量来控制它们在副本上的使用。

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

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