NDB群集复制架构和表
NDB群集中的复制利用mysql
每个MySQL Server实例上的数据库中的许多专用表,这些实例在要复制的群集和复制从属服务器中充当SQL节点(无论从属服务器是单个服务器还是群集)。这些表是在MySQL安装过程中创建的,其中包括一个用于存储二进制日志的索引数据的表。由于该ndb_binlog_index
表对于每个MySQL服务器来说都是本地的,并且不参与集群,因此它使用InnoDB
存储引擎。这意味着它必须在每个mysqld上分别创建参与主集群。(但是,二进制日志本身包含要复制的集群中所有MySQL服务器的更新。)此表定义如下:
CREATE TABLE `ndb_binlog_index` ( `Position` BIGINT(20)UNSIGNED NOT NULL, `File ` VARCHAR(255) NOT NULL, `epoch` BIGINT(20)UNSIGNED NOT NULL, `inserts` INT(10)UNSIGNED NOT NULL, `updates` INT(10)UNSIGNED NOT NULL, `deletes` 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`) )ENGINE =InnoDBDEFAULT CHARSET =latin1;
注意如果要从旧版本(到NDB 7.5.2之前的版本)升级,请执行MySQL升级过程,并确保已升级系统表。(从MySQL 8.0.16开始,使用
--upgrade=FORCE
选项启动服务器。在MySQL 8.0.16之前,在启动服务器后使用和选项调用mysql_upgrade。)系统表升级导致对该表执行一条语句。为了向后兼容,继续支持使用该表的存储引擎。--force
--upgrade-system-tables
ALTER TABLE ... ENGINE=INNODB
MyISAM
ndb_binlog_index
转换为时可能需要额外的磁盘空间InnoDB
。如果这成为问题,则可以通过InnoDB
为此表使用表空间或将其更改ROW_FORMAT
为COMPRESSED
或两者来节省空间。有关更多信息,请参见“ CREATE TABLESPACE语句”和“ CREATE TABLE语句”以及“表空间”。
该表的大小取决于每个二进制日志文件的纪元数和二进制日志文件的数。每个二进制日志文件的纪元数通常取决于每个纪元生成的二进制日志数和二进制日志文件的大小,纪元越小,每个文件的纪元就越多。您应该意识到ndb_binlog_index
,即使--ndb-log-empty-epochs
选项为OFF
,空的纪元也会在表中产生插入,这意味着每个文件的条目数取决于文件的使用时间。那是,
[number of epochs per file] = [time spent per file] / TimeBetweenEpochs
繁忙的NDB群集会定期写入二进制日志,并且可能比安静的二进制文件更快地旋转二进制日志文件。这意味着,一个“安静”的 NDB群集--ndb-log-empty-epochs=ON
实际上ndb_binlog_index
每个文件的行数比活动很多的行要高得多。
当mysqld的启动与--ndb-log-orig
选项,orig_server_id
和orig_epoch
列分别存储在服务器的ID在该事件起源和使用多个主机在该事件发生在源服务器上的时代,这在NDB集群复制的设置是非常有用的。该SELECT
语句用于在多主机设置中找到最接近从机上应用最高时期的二进制日志位置(请参见“ NDB群集复制:多主机和循环复制”))使用这两列(未编制索引)。尝试进行故障转移时,这可能会导致性能问题,因为查询必须执行表扫描,尤其是在主数据库运行时--ndb-log-empty-epochs=ON
。您可以通过向这些列添加索引来缩短多主机故障转移时间,如下所示:
ALTER TABLE mysql.ndb_binlog_indexADD INDEX orig_lookupUSING BTREE (orig_server_id, orig_epoch);
从单个主服务器复制到单个从服务器时,添加此索引没有任何好处,因为在这种情况下用于获取二进制日志位置的查询没有使用orig_server_id
或orig_epoch
。
有关使用和列的更多信息,请参见“用NDB群集复制实现故障转移”。next_position
next_file
下图显示了NDB群集复制主服务器,其二进制日志注入器线程和mysql.ndb_binlog_index
表之间的关系。
复制主群集
另一个名为的表ndb_apply_status
用于记录从主服务器复制到从服务器的操作。与的情况不同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 latin1COLLATE latin1_bin NOT NULL, `start_pos` BIGINT(20)UNSIGNED NOT NULL, `end_pos` BIGINT(20)UNSIGNED NOT NULL,PRIMARY KEY (`server_id`)USING HASH )ENGINE =NDBCLUSTER DEFAULT CHARSET =latin1;
该ndb_apply_status
表仅在从属服务器上填充,这意味着在主服务器上,该表从不包含任何行;因此,没有必要允许DataMemory
或IndexMemory
分配在ndb_apply_status
那里。
由于此表是从主数据库上的数据填充的,因此应允许对其进行复制;任何无意中阻止从属服务器更新ndb_apply_status
或主控服务器写入二进制日志的复制过滤或二进制日志过滤规则都可能会阻止群集之间的复制正常运行。有关由此类过滤规则引起的潜在问题的更多信息,请参见复制和二进制日志过滤规则以及NDB群集之间的复制。
将ndb_binlog_index
和ndb_apply_status
表在创建mysql
数据库,因为他们不应该由用户显式复制。通常不需要用户干预来创建或维护这两个表中的任何一个,因为ndb_binlog_index
和ndb_apply_status
都由NDB
二进制日志(binlog)注入器线程维护。这样可以使主mysqld进程保持更新,以适应NDB
存储引擎执行的更改。该二进制日志注入线程直接从接收事件的存储引擎。的NDB
NDB
NDB
注入程序负责捕获集群中的所有数据事件,并确保将所有更改,插入或删除数据的事件记录在ndb_binlog_index
表中。从属I / O线程将事件从主机的二进制日志传输到从属的中继日志。
但是,建议在准备要复制的NDB群集的第一步中检查这些表的存在和完整性。通过mysql.ndb_binlog_index
直接在主数据库上查询表,可以参见二进制日志中记录的事件数据。这也可以使用SHOW BINLOG EVENTS
复制主服务器或从属MySQL服务器上的语句来完成。(请参见“ SHOW BINLOG事件声明”。)
您还可以从的输出获取有用的信息SHOW ENGINE NDB STATUS
。
注意在
NDB
表上执行模式更改时,应用程序应等到ALTER TABLE
发出该语句的MySQL客户端连接中返回该语句,然后再尝试使用表的更新定义。
如果该ndb_apply_status
表在从属服务器上不存在,则ndb_restore重新创建它。
解决NDB群集复制的冲突需要存在一个附加mysql.ndb_replication
表。当前,该表必须手动创建。有关如何执行此操作的信息,请参见“ NDB群集复制冲突解决”。