本节讨论在使用NDB集群复制时已知的问题。
源和副本之间失去连接。源集群SQL节点和复制集群SQL节点之间,或者源SQL节点和源集群的数据节点之间,都可能发生连接丢失。在后一种情况下,这不仅可能是物理连接丢失(例如,网线断了)的结果,而且可能是数据节点事件缓冲区溢出的结果;如果SQL节点响应太慢,它可能会被集群丢弃(这在一定程度上可以通过调整MaxBufferedEpochs
而且TimeBetweenEpochs
配置参数)。如果发生这种情况,将新数据插入到源集群中而不被记录在源SQL节点的二进制日志中是完全可能的.因此,为了保证高可用性,维护备份复制区域通道、监控主复制区域通道以及在必要时故障切换到从复制区域通道,以保持复制集群与源端同步是非常重要的。NDB集群本身并不是为执行此类监控而设计的;为此,需要一个外部应用程序。
源SQL节点发出一个”差距”事件,当连接或重新连接到源集群时。(间隙事件是一种”事故事件,”这表示发生了影响数据库内容但不容易表示为一组更改的事件。事件的例子包括服务器故障、数据库重新同步、一些软件更新和一些硬件更改。)当复制在复制日志中遇到空白时,它将停止并显示错误消息。的输出中提供了此消息显示奴隶状态
,并指示由于复制流中注册的事件,SQL线程已停止,需要手动干预。看到第18.6.8节“使用NDB集群复制实现故障转移”,以了解在这种情况下该如何做的更多信息。
由于NDB集群本身并不是为监视复制状态或提供故障转移而设计的,如果复制服务器或集群需要高可用性,则必须设置多条复制线,监视源mysqld在主复制线上,并在必要时准备故障转移到辅助复制线上。这必须手动完成,也可能通过第三方应用程序完成。有关实现这种类型设置的信息,请参见18.6.7节“使用双复制通道实现NDB集群复制”,第18.6.8节“使用NDB集群复制实现故障转移”.
如果你要从一个独立的MySQL服务器复制到一个NDB集群,一个通道通常就足够了。
圆形的复制。NDB集群复制支持循环复制,如下例所示。复制设置包括编号为1、2、3的三个NDB集群,集群1作为集群2的复制源,集群2作为集群3的复制源,集群3作为集群1的复制源,循环完成。每个NDB集群有两个SQL节点,SQL节点A和B属于Cluster 1, SQL节点C和D属于Cluster 2, SQL节点E和F属于Cluster 3。
只要满足以下条件,就支持使用这些集群进行循环复制:
所有源集群和复制集群上的SQL节点都是相同的。
作为源和副本的所有SQL节点都以
log_slave_updates
系统变量启用。
这种循环复制设置如下图所示:
在此场景中,集群1中的SQL节点A复制到集群2中的SQL节点C;集群3中SQL节点C复制到SQL节点E;SQL节点E复制到SQL节点a。换句话说,复制线(由图中曲线箭头表示)直接连接用作源和副本的所有SQL节点。
也可以设置循环复制,其中并非所有源SQL节点都是副本,如下所示:
在本例中,每个集群中的不同SQL节点用作源和副本。但是,你必须不启动任何SQL节点log_slave_updates
系统变量启用。对于NDB集群来说,这种循环复制方案(复制线(如图中曲线箭头所示)是不连续的)应该是可行的,但需要注意的是,它还没有经过彻底的测试,因此还必须被认为是实验性的。
的NDB
存储引擎使用幂等执行模式,可以抑制重复键等错误,否则会破坏NDB集群的循环复制。这相当于设置全局变量slave_exec_mode
系统变量幂等
虽然这在NDB集群复制中是不必要的,因为NDB集群会自动设置此变量并忽略任何显式设置。
NDB集群复制和主键。节点故障时,复制中的错误NDB
由于在这种情况下插入重复行的可能性,仍然可能出现没有主键的表。因此,强烈建议大家NDB
被复制的表具有显式的主键。
NDB集群复制和唯一密钥。在旧版本的NDB Cluster中,更新惟一键列值的操作NDB
表在复制时可能会导致重复键错误。之间的复制解决了这个问题NDB
通过将惟一键检查推迟到执行所有表行更新之后才执行。
以这种方式延迟约束目前仅由NDB
.因此,从复制时更新惟一键NDB
到不同的存储引擎,例如InnoDB
或MyISAM
仍然不受支持。
在不延迟检查唯一键更新的情况下进行复制时遇到的问题可以使用NDB
表等t
,在源上创建并填充(并传输到不支持延迟惟一键更新的副本),如下所示:
创建表t (p INT主键,c INT,唯一键,u (c))插入t值(1,1),(2,2),(3),(4,4),(5);
以下更新
声明t
方法确定的顺序处理受影响的行,因此在源上成功命令
选项,在整个表上执行:
UPDATE SET c = c - 1 ORDER BY p;
相同的语句在副本上出现重复的键错误或其他违反约束的情况下失败,因为行更新的顺序每次只对一个分区执行,而不是对整个表执行。
每一个NDB
表在创建时按键隐式分区。看到第19.2.5节,“键分区”,以查询更多资料。
GTIDs不受支持的。使用全局事务id的复制与NDB
存储引擎,不支持。启用gtid可能导致NDB集群复制失败。
不支持多线程副本。NDB集群不支持多线程副本,设置相关系统变量如slave_parallel_workers
,slave_checkpoint_group
,slave_checkpoint_group
(或等效mysqld启动选项)没有影响。
这是因为如果事务是在同一时期写入的,那么副本可能无法将发生在一个数据库中的事务与发生在另一个数据库中的事务分开。此外,每笔交易都由NDB
存储引擎至少涉及两个数据库—目标数据库和mysql
系统数据库-由于更新的要求mysql.ndb_apply_status
表(参见第18.6.4节“NDB集群复制模式和表”).这反过来又打破了多线程的要求,即事务特定于给定的数据库。
重新启动,初始。方法重新启动集群——初始
选项导致GCI和epoch号的顺序重新开始0
.(NDB集群通常如此,不限于涉及集群的复制场景。)在这种情况下,应该重新启动参与复制的MySQL服务器。之后,您应该使用重置的主人
而且重置的奴隶
语句清除无效ndb_binlog_index
而且ndb_apply_status
表,分别。
从NDB复制到其他存储引擎。可以复制一个NDB
将源上的表转移到副本上使用不同存储引擎的表上,并考虑这里列出的限制:
不支持多源复制和循环复制(源和复制上的表都必须使用
NDB
存储引擎的工作)。使用不为副本上的表执行二进制日志记录的存储引擎需要特殊处理。
对副本上的表使用非事务性存储引擎还需要特殊处理。
源mysqld必须从以下开始
——ndb-log-update-as-write = 0
或——ndb-log-update-as-write =了
.
接下来的几段提供了关于刚才描述的每个问题的附加信息。
NDB复制到其他存储引擎时,不支持多源复制。复制的NDB
对于不同的存储引擎,两个数据库之间的关系必须是一对一的。这意味着NDB集群与其他存储引擎之间不支持双向或循环复制。
同时,在两者之间进行复制时,不允许配置多个复制区域通道NDB
还有一个不同的存储引擎。(NDB集群数据库可以同时复制到多个NDB集群数据库。)如果源使用NDB
表中,仍然有可能有多个MySQL Server维护所有更改的二进制日志,但是为了让副本更改源(故障转移),必须在副本上显式定义新的源-副本关系。
将NDB表复制到不执行二进制日志记录的存储引擎。如果试图从NDB集群复制到使用不处理自身二进制日志记录的存储引擎的副本,复制过程将中止并出现错误二进制日志记录不可能…语句不能原子地写入,因为涉及多个引擎,而且至少有一个引擎是自记录的(错误1595).我们可以通过以下方式解决这个问题:
在副本上关闭二进制日志记录。这可以通过设置来完成
sql_log_bin = 0
.修改mysql数据库使用的存储引擎。ndb_apply_status表。让这个表使用一个不处理它自己的二进制日志记录的引擎也可以消除冲突。这可以通过发布一个声明来完成,例如
ALTER TABLE mysql。ndb_apply_statusENGINE=MyISAM
在副本。在使用其他存储引擎时这样做是安全的NDB
在副本上,因为您不需要担心保持多个副本同步。过滤掉mysql的更改。ndb_apply_statustable on the replica.这可以通过使用
——replicate-ignore-table = mysql.ndb_apply_status
.如果需要复制忽略其他表,则可能希望使用适当的——replicate-wild-ignore-table
选项。
你应该不的复制或二进制日志mysql.ndb_apply_status
或者在从一个NDB集群复制到另一个NDB集群时更改该表使用的存储引擎。看到复制和二进制日志过滤规则,NDB集群之间有复制的细节。
从NDB复制到非事务性存储引擎。当复制NDB
到非事务性存储引擎,例如MyISAM
,复制时可能会遇到不必要的重复键错误插入……关于重复密钥更新
语句。你可以通过使用——ndb-log-update-as-write = 0
,它强制将更新记录为写,而不是更新。
复制和二进制日志过滤规则,NDB集群之间有复制。如果您正在使用任何选项——replicate-do - *
,——replicate-ignore - *
,——binlog-do-db
,或——binlog-ignore-db
类的复制或二进制日志记录要筛选正在复制的数据库或表,必须注意不要阻塞mysql.ndb_apply_status
为保证NDB集群间复制的正常运行,需要配置该配置。你必须特别记住以下几点:
使用
——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
Options)意味着改变只有到数据库中的表db_name
写入二进制日志。在这种情况下,您还应该使用——replicate-do-db = mysql
,——binlog-do-db = mysql
,或——replicate-do-table = mysql.ndb_apply_status
以确保mysql.ndb_apply_status
在副本上填充。使用
——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
是复制的。
您还应该记住,每个复制规则都需要以下条件:
自己的
——replicate-do - *
或——replicate-ignore - *
选项,并且多个规则不能在单个复制筛选选项中表示。有关这些规则的信息,请参见第17.1.4节“复制和二进制日志选项和变量”.自己的
——binlog-do-db
或——binlog-ignore-db
选项,多个规则不能在一个二进制日志过滤选项中表示。有关这些规则的信息,请参见第5.4.4节“二进制日志”.
如果要将NDB集群复制到使用非NDB
,前面给出的考虑可能不适用,如本节其他部分所讨论的。
NDB集群复制和IPv6。虽然NDB API和MGM API(以及数据节点和管理节点)在NDB 7.3和7.4中不支持IPv6,但MySQL服务器——包括那些在NDB集群中充当SQL节点的服务器——可以使用IPv6联系其他MySQL服务器。这意味着您可以在NDB集群之间使用IPv6进行复制,以连接源SQL节点和复制SQL节点,如下图中虚线箭头所示:
所有连接的在NDB集群(在上图中用实箭头表示)必须使用IPv4。也就是说,所有NDB集群数据节点、管理服务器和管理客户端必须通过IPv4相互访问。此外,SQL节点必须使用IPv4与集群通信。
由于NDB和MGM api目前不支持IPv6,任何使用这些api编写的应用程序也必须使用IPv4进行所有连接。
属性提升和降级。NDB集群复制包括属性提升和降级支持。的实现区分了有损和非有损类型转换,并且可以通过设置来控制它们在副本上的使用slave_type_conversions
全局服务器系统变量。
有关NDB集群中属性提升和降级的更多信息,请参见基于行的复制:属性提升和降级.