在使用带有全局事务标识符 (GTID) 的 MySQL 复制来提供新副本时,有许多技术可以用于横向扩展,并根据故障转移的需要提升为源。本节介绍以下技术:
全局事务标识符被添加到 MySQL 复制中,目的是简化复制数据流的一般管理,特别是故障转移活动。每个标识符唯一标识一组二进制日志事件,这些事件一起构成一个事务。GTID 在将更改应用到数据库中起着关键作用:服务器会自动跳过任何具有服务器识别为它之前处理过的标识符的事务。此行为对于自动复制定位和正确的故障转移至关重要。
标识符和包含给定事务的事件集之间的映射被捕获在二进制日志中。当使用来自另一台现有服务器的数据配置新服务器时,这会带来一些挑战。要在新服务器上重现标识符集,需要将旧服务器上的标识符复制到新服务器上,并保留标识符与实际事件的关系。这对于恢复可立即用作候选者以在故障转移或切换时成为新源的副本是必要的。
简单复制。 在新服务器上重现所有标识符和事务的最简单方法是使新服务器成为具有完整执行历史的源的副本,并在两台服务器上启用全局事务标识符。有关更多信息,请参阅 第 17.1.3.4 节,“使用 GTID 设置复制”。
复制开始后,新服务器从源复制整个二进制日志,从而获得有关所有 GTID 的所有信息。
这种方法简单有效,但需要从源读取二进制日志;新副本有时需要相对较长的时间才能赶上源,因此这种方法不适合快速故障转移或从备份恢复。本节介绍如何通过将二进制日志文件复制到新服务器来避免从源获取所有执行历史记录。
将数据和事务复制到副本。 当源服务器之前处理过大量事务时,执行整个事务历史可能会很耗时,这可能是设置新副本时的主要瓶颈。为了消除这一要求,可以将源服务器包含的数据集快照、二进制日志和全局事务信息导入到新副本中。拍摄快照的服务器可以是源服务器或其副本之一,但您必须确保服务器在复制数据之前已处理所有必需的事务。
这种方法有多种变体,不同之处在于二进制日志中的数据转储和事务传输到副本的方式,如下所述:
- 数据集
-
在源服务器上使用mysqldump 创建转储文件。设置mysqldump 选项
--master-data
(默认值为 1)以包含CHANGE REPLICATION SOURCE TO
|CHANGE MASTER TO
带有二进制日志信息的语句。将--set-gtid-purged
选项设置为AUTO
(默认值)或ON
,以在转储中包含有关已执行事务的信息。然后使用 mysql客户端导入目标服务器上的转储文件。或者,使用原始数据文件创建源服务器的数据快照,然后按照 第 17.1.2.5 节“选择数据快照方法”中的说明将这些文件复制到目标服务器。如果您使用
InnoDB
表,您可以使用 MySQL Enterprise Backup 组件中的mysqlbackup命令来生成一致的快照。此命令记录与要在副本上使用的快照对应的日志名称和偏移量。MySQL Enterprise Backup 是一种商业产品,作为 MySQL Enterprise 订阅的一部分包含在内。看 第 30.2 节,“MySQL 企业备份概述”了解详细信息。或者,停止源服务器和目标服务器,将源数据目录的内容复制到新副本的数据目录,然后重新启动副本。如果您使用此方法,则副本必须配置为基于 GTID 的复制,换句话说,使用
gtid_mode=ON
. 有关此方法的说明和重要信息,请参阅 第 17.1.2.8 节,“将副本添加到复制环境”。
- 交易纪录
如果源服务器在其二进制日志中有完整的事务历史记录(即 GTID 集
@@GLOBAL.gtid_purged
为空),则可以使用这些方法。使用mysqlbinlog以及
--read-from-remote-server
、--read-from-remote-source
和--read-from-remote-master
选项 将二进制日志从源服务器导入到新副本。或者,将源服务器的二进制日志文件复制到副本。您可以使用带有 和选项的mysqlbinlog从副本创建副本。这些可以通过使用 mysqlbinlog (没有 选项)将二进制日志文件导出到 SQL 文件,然后将这些文件传递给mysql 客户端进行处理,从而将这些读入副本。确保使用单个 mysql处理所有二进制日志文件
--read-from-remote-server
--raw
>
file
--raw
进程,而不是多个连接。例如:$> mysqlbinlog copied-binlog.000001 copied-binlog.000002 | mysql -u root -p
有关详细信息,请参阅 第 4.6.9.3 节,“使用 mysqlbinlog 备份二进制日志文件”。
这种方法的优点是几乎可以立即使用新服务器;只有那些在重放快照或转储文件时提交的事务仍然需要从现有源中获取。这意味着副本的可用性不是瞬时的,但副本只需要相对较短的时间就可以赶上这少数剩余事务。
提前将二进制日志复制到目标服务器通常比实时从源读取整个事务执行历史要快。但是,由于大小或其他考虑因素,在需要时将这些文件移动到目标并不总是可行的。本节讨论的剩余两种供应新副本的方法使用其他方法将有关事务的信息传输到新副本。
注入空交易。
源的全局
gtid_executed
变量包含在源上执行的所有事务的集合。在拍摄快照以提供新服务器时,您不必复制二进制日志,而是可以记下
gtid_executed
拍摄快照的服务器上的内容。在将新服务器添加到复制链之前,只需在新服务器上为源中包含的每个事务标识符提交一个空事务gtid_executed
,如下所示:
SET GTID_NEXT='aaa-bbb-ccc-ddd:N';
BEGIN;
COMMIT;
SET GTID_NEXT='AUTOMATIC';
使用空事务以这种方式恢复所有事务标识符后,您必须刷新并清除副本的二进制日志,如下所示,
N
当前二进制日志文件名的非零后缀在哪里:
FLUSH LOGS;
PURGE BINARY LOGS TO 'source-bin.00000N';
您应该这样做是为了防止此服务器在稍后提升到源时用错误事务淹没复制流。(该FLUSH
LOGS
语句强制创建一个新的二进制日志文件;PURGE BINARY LOGS
清除空事务,但保留它们的标识符。)
此方法创建的服务器本质上是一个快照,但随着它的二进制日志历史与复制流的历史收敛(即,当它赶上一个或多个源)时,它能够及时成为一个源。这个结果在效果上与使用剩余供应方法获得的结果类似,我们将在接下来的几段中讨论。
排除与 gtid_purged 的交易。
源的全局
gtid_purged
变量包含已从源的二进制日志中清除的所有事务的集合。与前面讨论的方法一样(请参阅
注入空事务),您可以
gtid_executed
在拍摄快照的服务器上记录值(代替将二进制日志复制到新服务器)。与以前的方法不同,不需要提交空交易(或发出
PURGE BINARY LOGS
);相反,您可以根据从中获取备份或快照的服务器
gtid_purged
上的值直接在副本上
设置。gtid_executed
与使用空事务的方法一样,此方法创建的服务器在功能上是一个快照,但随着它的二进制日志历史与源和其他副本的二进制日志历史收敛,及时能够成为一个源。
恢复 GTID 模式副本。 在基于 GTID 的复制设置中还原遇到错误的副本时,注入空事务可能无法解决问题,因为事件没有 GTID。
使用mysqlbinlog查找下一个事务,这可能是事件发生后下一个日志文件中的第一个事务。复制COMMIT
该交易的所有内容,确保包括SET
@@SESSION.gtid_next
. 即使您没有使用基于行的复制,您仍然可以在命令行客户端中运行二进制日志行事件。
停止副本并运行您复制的事务。mysqlbinlog输出将分隔符设置为
,
/*!*/;
因此将其设置回去:
mysql> DELIMITER ;
自动从正确的位置重新启动复制:
mysql> SET GTID_NEXT=automatic;
mysql> RESET SLAVE;
mysql> START SLAVE;
Or from MySQL 8.0.22:
mysql> SET GTID_NEXT=automatic;
mysql> RESET REPLICA;
mysql> START REPLICA;