Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  Using GTIDs for Failover and Scaleout

19.1.3.5 使用 GTIDs 实现故障转移和扩展

使用 MySQL 复制和全局事务标识符(GTIDs)可以使用多种技术来提供新的副本,以便扩展和故障转移。本节描述以下技术:

全局事务标识符被添加到 MySQL 复制,以简化复制数据流和故障转移活动的管理。每个标识符唯一标识一组二进制日志事件,这些事件共同组成一个事务。GTIDs 在应用数据库更改和自动复制定位方面扮演着关键角色:服务器自动跳过任何具有已知标识符的事务,这些标识符服务器之前已经处理过。

标识符和事件集之间的映射关系被捕获在二进制日志中。这在为新的服务器提供数据时提出了挑战:需要从旧服务器复制标识符到新服务器,并保留标识符和事件之间的关系。这对于恢复可以立即作为故障转移或切换的副本是必要的。

简单复制。 在新服务器上复制所有标识符和事务的最简单方法是使新服务器成为具有整个执行历史记录的源服务器的副本,并在两个服务器上启用全局事务标识符。请参阅 第 19.1.3.4 节,“使用 GTIDs 设置复制”,以获取更多信息。

一旦复制开始,新服务器将从源服务器复制整个二进制日志,从而获得所有 GTIDs 的信息。

这种方法简单有效,但需要副本从源服务器读取二进制日志,这可能需要很长时间,因此不适合快速故障转移或从备份恢复。本节将解释如何通过复制二进制日志文件到新服务器来避免从源服务器获取所有执行历史记录。

将数据和事务复制到副本。 执行整个事务历史记录可能需要很长时间,特别是当源服务器已经处理了大量事务时。这可能会在设置新副本时造成主要瓶颈。为了消除这个要求,可以将源服务器的数据快照、二进制日志和全局事务信息导入到新副本。可以从源服务器或其副本之一获取快照,但必须确保服务器在复制数据之前已经处理了所有所需的事务。

这种方法有多种变体,区别在于将数据转储和二进制日志事务传输到副本的方式,如下所述:

Data Set
  1. 使用 mysqldump 在源服务器上创建转储文件。将 mysqldump 选项 --source-data 设置为 1,以包括一个 CHANGE REPLICATION SOURCE TO 语句,带有二进制日志信息。将 --set-gtid-purged 选项设置为 AUTO(默认)或 ON,以包括执行的事务信息在转储文件中。然后使用 mysql 客户端将转储文件导入目标服务器。

  2. 或者,使用原始数据文件创建源服务器的数据快照,然后将这些文件复制到目标服务器,按照第 19.1.2.5 节,“选择数据快照方法”中的说明进行操作。如果您使用InnoDB表,可以使用 MySQL Enterprise Backup 组件中的 mysqlbackup 命令生成一致的快照。该命令记录了快照对应的日志名称和偏移量,以便在副本上使用。MySQL Enterprise Backup 是 MySQL Enterprise 订阅的一部分。请参阅第 32.1 节,“MySQL Enterprise Backup 概述”以获取详细信息。

  3. 或者,停止源服务器和目标服务器,复制源服务器的数据目录到新副本的数据目录,然后重新启动副本。如果您使用这种方法,副本必须配置为基于 GTID 的复制,即使用gtid_mode=ON。有关该方法的说明和重要信息,请参阅第 19.1.2.8 节,“添加副本到复制环境”

Transaction History

如果源服务器具有完整的事务历史记录在其二进制日志中(即 GTID 集 @@GLOBAL.gtid_purged 为空),您可以使用这些方法。

  1. 使用mysqlbinlog从源服务器导入二进制日志到新副本,使用--read-from-remote-server--read-from-remote-source选项。

  2. 或者,复制源服务器的二进制日志文件到副本。您可以使用mysqlbinlog从副本上复制,使用--read-from-remote-server--raw选项。这些可以使用mysqlbinlog > file(不带--raw选项)将二进制日志文件导出到 SQL 文件,然后将这些文件传递给mysql客户端进行处理。确保使用单个mysql进程处理所有二进制日志文件,而不是多个连接。例如:

    $> mysqlbinlog copied-binlog.000001 copied-binlog.000002 | mysql -u root -p

    有关更多信息,请参阅第 6.6.9.3 节,“使用 mysqlbinlog 备份二进制日志文件”

这种方法的优点是新服务器几乎立即可用;只有在快照或转储文件被重放时提交的事务仍需要从现有的源服务器获取。这意味着副本的可用性不是即时的,但只需要相对短暂的时间来 catch up 这些剩余的事务。

提前将二进制日志文件复制到目标服务器通常比从源服务器实时读取整个事务执行历史记录要快。但是,这可能并不总是可行的,因为文件大小或其他考虑因素。下面讨论的两种方法使用其他方式将事务信息传输到新副本。

注入空事务 源服务器的全局gtid_executed变量包含了在源服务器上执行的所有事务。相比复制二进制日志文件来 provision 新服务器,您可以记录源服务器的 gtid_executed 变量的内容。在将新服务器添加到复制链之前,简单地在新服务器上提交一个空事务,对于源服务器的 gtid_executed 变量中的每个事务标识符,如下所示:<|start_header_id|>assistant<|end_header_id|> Please note that I've translated the text into Chinese, but I didn't touch the HTML tags and code snippets, as they are not translatable.

SET GTID_NEXT='aaa-bbb-ccc-ddd:N';

BEGIN;
COMMIT;

SET GTID_NEXT='AUTOMATIC';

一旦所有事务标识符都被重新建立在这个服务器上使用空事务,你必须刷新和清除副本的二进制日志,如下所示,其中 N 是当前二进制日志文件名的非零后缀:

FLUSH LOGS;
PURGE BINARY LOGS TO 'source-bin.00000N';

你应该这样做,以防止这个服务器在以后被提升为源时泛滥 replication 流中虚假的事务。(FLUSH LOGS 语句强制创建一个新的二进制日志文件;PURGE BINARY LOGS 清除空事务,但保留它们的标识符。)

这种方法创建了一个基本上是快照的服务器,但随着时间的推移,它能够成为源,因为其二进制日志历史记录与复制流的历史记录相符(即,它赶上了源或源)。这种结果类似于使用剩余的配置方法所获得的结果,我们将在下面几段中讨论。

排除使用 gtid_purged 的事务。 源的全局 gtid_purged 变量包含了从源的二进制日志中清除的事务集。与之前讨论的方法类似(见 Injecting empty transactions),你可以记录从快照服务器上获取的 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 REPLICA;
mysql> START REPLICA;