NDB集群中的复制使用了数据库中的许多专用表mysql
数据库在每个MySQL服务器实例上充当被复制集群和副本中的SQL节点。无论副本是单个服务器还是集群,都是如此。
的ndb_binlog_index
而且ndb_apply_status
表是在mysql
数据库。用户不应该显式地复制它们。创建或维护这两个表通常不需要用户干预,因为它们都是由NDB
二进制日志注入器线程。这样就保留了源代码mysqld类执行的更改已更新到NDB
存储引擎。的NDB
宾洛格注入器螺纹对象直接接收事件NDB
存储引擎。的NDB
注入器负责捕获集群内的所有数据事件,并确保所有更改、插入或删除数据的事件都记录在ndb_binlog_index
表格复制I/O线程将事件从源的二进制日志传输到副本的中继日志。
的ndb_replication
表必须手动创建。用户可以更新该表,以按数据库或表进行过滤。看到ndb_replication表,以获取更多资料。ndb_replication
用于NDB复制冲突检测和解决,实现冲突解决控制;看到冲突解决控制.
尽管ndb_binlog_index
而且ndb_apply_status
如果这些表是自动创建和维护的,那么在准备NDB集群进行复制时,建议将检查这些表的存在性和完整性作为初始步骤。方法可以查看二进制日志中记录的事件数据mysql.ndb_binlog_index
表直接上源。也可以使用显示binlog事件
语句在源或副本SQL节点上。(见第13.7.7.2节,“SHOW BINLOG事件语句”.)
的输出也可以获得有用的信息显示引擎NDB状态
.
上执行架构更改时NDB
表、应用程序应等到ALTER TABLE
语句已经在MySQL客户端连接中返回,在尝试使用表的更新定义之前发出该语句。
ndb_apply_status
用于保存从源复制到副本的操作的记录。如果ndb_apply_status
表在副本上不存在,ndb_restore重新创建它。
不像ndb_binlog_index
,该表中的数据不是特定于(副本)集群中的任何一个SQL节点,因此ndb_apply_status
可以使用NDBCLUSTER
存储引擎,如下所示:
CREATE TABLE ' ndb_apply_status ' (' server_id ' INT(10) UNSIGNED NOT NULL, ' epoch ' BIGINT(20) UNSIGNED NOT NULL, ' log_name ' VARCHAR(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, ' start_pos ' BIGINT(20) UNSIGNED NOT NULL, ' end_pos ' BIGINT(20) UNSIGNED NOT NULL,主键(' server_id ') USING HASH) ENGINE=NDBCLUSTER DEFAULT CHARSET=latin1;
的ndb_apply_status
表仅在副本上填充,这意味着在源上,该表从不包含任何行;因此,不需要分配任何DataMemory
来ndb_apply_status
在那里。
因为该表是由源上的数据填充的,所以应该允许它进行复制;任何无意中阻止副本更新的复制过滤或二进制日志过滤规则ndb_apply_status
,或者阻止源写入二进制日志可能会阻止集群之间的复制正常运行。有关此类过滤规则产生的潜在问题的详细信息,请参见复制和二进制日志过滤规则,NDB集群间复制.
NDB集群复制使用ndb_binlog_index
表,用于存储二进制日志的索引数据。由于该表是每个MySQL服务器的本地表,并且不参与集群,因此它使用InnoDB
存储引擎。这意味着它必须在每个服务器上分别创建mysqld参与源集群。(二进制日志本身包含来自集群中所有MySQL服务器的更新。)该表定义如下:
创建表' ndb_binlog_index '('位置' BIGINT(20) UNSIGNED NOT NULL, '文件' VARCHAR(255) NOT NULL, ' epoch ' BIGINT(20) UNSIGNED NOT NULL, '插入' INT(10) UNSIGNED NOT NULL, '更新' INT(10) UNSIGNED NOT NULL, ' schemaops ' INT(10) UNSIGNED NOT NULL, ' orig_server_id ' INT(10) UNSIGNED NOT NULL, ' orig_epoch ' BIGINT(20) UNSIGNED NOT NULL, ' gci ' INT(10) UNSIGNED NOT NULL, ' next_position ' BIGINT(20) UNSIGNED NOT NULL, ' next_file ' VARCHAR(255) NOT NULL, 'PRIMARY KEY (' epoch ', ' orig_server_id ', ' orig_epoch '))
如果您正在从旧版本(NDB 7.5.2之前)升级,请执行MySQL升级过程,并确保系统表已升级。(从MySQL 8.0.16开始,使用——升级=力
选择。在MySQL 8.0.16之前,调用mysql_upgrade与——力
而且——upgrade-system-tables
启动服务器后的选项。)升级系统表会导致修改表…引擎= INNODB
语句将为此表执行。的使用MyISAM
为了向后兼容,继续支持该表的存储引擎。
ndb_binlog_index
转换为?后可能需要额外的磁盘空间InnoDB
.如果这成为一个问题,您可以通过使用InnoDB
该表的表空间,更改其ROW_FORMAT
来压缩
,或者两者都有。有关更多信息,请参见第13.1.21节,创建表空间语句,第13.1.20节“CREATE TABLE语句”,以及第15.6.3节,“表空间”.
的大小ndb_binlog_index
表依赖于每个二进制日志文件的epoch数和二进制日志文件的数量。每个二进制日志文件的epoch数通常取决于每个epoch生成的二进制日志的数量和二进制日志文件的大小,较小的epoch导致每个文件的epoch数更多。对象的空epoch会产生插入ndb_binlog_index
表,即使当——ndb-log-empty-epochs
选择是从
,这意味着每个文件的条目数取决于文件被使用的时间长度;这种关系可以用如下公式表示:
[每个文件的epoch数]=[每个文件花费的时间]/ TimeBetweenEpochs .
繁忙的NDB集群定期写入二进制日志,并且可能比安静的集群更快地旋转二进制日志文件。这意味着”安静的”NDB集群——ndb-log-empty-epochs =
能有更大的数目吗ndb_binlog_index
每个文件的行数比具有大量活动的行数多。
当mysqld是从——ndb-log-orig
选项时,orig_server_id
而且orig_epoch
列分别存储事件发生的服务器ID和事件发生在原始服务器上的时间,这在使用多个源的NDB集群复制设置中非常有用。的选择
语句,用于在多源设置中查找与副本上应用的最高纪元最近的二进制日志位置(请参阅第23.6.10节,“NDB集群复制:双向复制和循环复制”)使用这两个没有索引的列。这在尝试故障转移时可能会导致性能问题,因为查询必须执行表扫描,特别是在源已运行时——ndb-log-empty-epochs =
.您可以通过向这些列添加索引来提高多源故障转移时间,如下所示:
修改mysql表。ndb_binlog_indexADD INDEX orig_lookup USING BTREE (orig_server_id, orig_epoch);
当从单个源复制到单个副本时,添加此索引不会带来任何好处,因为在这种情况下,用于获取二进制日志位置的查询不会使用orig_server_id
或orig_epoch
.
看到第23.6.8节,“使用NDB集群复制实现故障转移”,以获取有关使用next_position
而且next_file
列。
下图显示了NDB集群复制源服务器、其二进制日志注入器线程和线程之间的关系mysql.ndb_binlog_index
表格
的ndb_replication
表用于控制二进制日志记录和冲突解决,并在每个表的基础上进行操作。该表中的每一行都对应于要复制的表,确定如何将更改记录到表中,如果指定了冲突解决函数,则确定如何解决该表的冲突。
不像ndb_apply_status
而且ndb_replication
表,ndb_replication
表必须手动创建。你可以使用如下所示的SQL语句:
创建mysql表。ndb_replication( db VARBINARY(63), table_name VARBINARY(63), server_id INT UNSIGNED, binlog_type INT UNSIGNED, conflict_fn VARBINARY(128), PRIMARY KEY USING HASH (db, table_name, server_id) ) ENGINE=NDB PARTITION BY KEY(db,table_name);
该表的列列如下,说明如下:
db
列包含要复制的表的数据库的名称。您可以使用通配符中的一个或两个
_
而且%
作为数据库名称的一部分。类实现的匹配类似于就像
操作符。table_name
列要复制的表的名称。表名可以包含通配符中的一个或两个
_
而且%
.类实现的匹配类似于就像
操作符。server_id
列表所在的MySQL实例(SQL节点)的唯一服务器ID。
binlog_type
列要使用的二进制日志记录类型。有关值和描述,请参阅文本。
conflict_fn
列将应用的冲突解决功能;之一NDB老美元(column_name),NDB马克斯(column_name)美元,NDB MAX_DELETE_WIN美元(),NDB美元时代(),NDB EPOCH_TRANS美元(),NDB EPOCH2美元(),NDB EPOCH2_TRANS美元();
零
指示此表不使用冲突解决。看到冲突解决功能,以获得有关这些函数及其在NDB Replication冲突解决中的用途的更多信息。
部分冲突解决功能(
旧NDB $ ()
,NDB美元时代()
,NDB EPOCH_TRANS美元()
)要求使用一个或多个用户创建的异常表。看到冲突解决例外表.
为了使用NDB Replication解决冲突,需要在需要解决冲突的一个或多个SQL节点上创建控制信息并填充该表。根据要使用的冲突解决类型和方法,这可能是源服务器、副本服务器或两个服务器。在简单的源副本设置中,数据也可以在副本上本地更改,这通常是副本。在更复杂的复制方案中,例如双向复制,这通常是所有涉及的源。看到第23.6.11节,“NDB集群复制冲突解决”,以获取更多资料。
的ndb_replication
表允许在冲突解决范围之外对二进制日志进行表级控制conflict_fn
指定为零
,而其余列值用于控制匹配通配符表达式的给定表或一组表的二进制日志记录。的适当值binlog_type
列时,可以对给定的表或表使用所需的二进制日志格式进行日志记录,也可以完全禁用二进制日志记录。该列可能的值,包括内部值和描述,如下表所示:
表23.69 binlog_type值,以及内部值和描述
价值 | 内在价值 | 描述 |
---|---|---|
0 | NBT_DEFAULT |
使用服务器默认值 |
1 | NBT_NO_LOGGING |
不要在二进制日志中记录这个表 |
2 | NBT_UPDATED_ONLY |
只记录更新后的属性 |
3. | NBT_FULL |
记录完整行,即使没有更新(MySQL服务器默认行为) |
4 | NBT_USE_UPDATE |
(用于生成NBT_UPDATED_ONLY_USE_UPDATE 而且NBT_FULL_USE_UPDATE 只有值-不打算单独使用) |
5 | [不习惯] | --- |
6 | NBT_UPDATED_ONLY_USE_UPDATE (等于Nbt_updated_only | nbt_use_update ) |
使用更新的属性,即使值没有改变 |
7 | NBT_FULL_USE_UPDATE (等于Nbt_full | nbt_use_update ) |
使用整行,即使值没有改变 |
8 | NBT_UPDATED_ONLY_MINIMAL |
日志更新为UPDATE_ROW ;在图像之前只记录主键列,在图像之后只记录更新的列 |
9 | NBT_UPDATED_FULL_MINIMAL |
日志更新为UPDATE_ROW ;在图像之前只记录主键列,在图像之后只记录主键列以外的所有列 |
控件中插入行,可以为不同的表设置二进制日志记录的不同格式ndb_replication
表使用适当的db
,table_name
,binlog_type
列值。设置二进制日志格式时,应使用上表中所示的内部整数值。下面两个语句将二进制日志记录设置为完整行的日志记录(NBT_FULL
,内部值3)为表试验原理
,以及只记录更新(NBT_UPDATED_ONLY
,内部值2)为表test.b
:
#表测试。a: Log full rows INSERT INTO mysql。ndb_replicationVALUES("test", "a", 0, 3, NULL); # Table test.b: log updates only INSERT INTO mysql.ndb_replication VALUES("test", "b", 0, 2, NULL);
若要禁用一个或多个表的日志记录,请使用1 (NBT_NO_LOGGING
)binlog_type
,如图所示:
#关闭测试表的二进制日志记录。t1 INSERT INTO mysqlndb_replicationVALUES("test", "t1", 0, 1, NULL); # Disable binary logging for any table in 'test' whose name begins with 't' INSERT INTO mysql.ndb_replication VALUES("test", "t%", 0, 1, NULL);