前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL8 中文参考(八十一)

MySQL8 中文参考(八十一)

作者头像
ApacheCN_飞龙
发布2024-06-26 13:49:48
1030
发布2024-06-26 13:49:48
举报
文章被收录于专栏:信数据得永生信数据得永生

原文:docs.oracle.com/javase/tutorial/reallybigindex.html

20.1.5 Group Replication 插件架构

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-plugin-architecture.html

MySQL Group Replication 是一个 MySQL 插件,它建立在现有的 MySQL 复制基础设施之上,利用二进制日志、基于行的日志记录和全局事务标识符等功能。它与当前的 MySQL 框架集成,如性能模式或插件和服务基础设施。以下图表展示了 MySQL Group Replication 的整体架构。

图 20.6 Group Replication 插件块图

图后的文本描述了图表的内容。
图后的文本描述了图表的内容。

MySQL Group Replication 插件包括一组用于捕获、应用和生命周期的 API,控制插件与 MySQL 服务器的交互方式。有接口使信息从服务器流向插件,反之亦然。这些接口将 MySQL 服务器核心与 Group Replication 插件隔离开来,主要是放置在事务执行管道中的钩子。在一个方向上,从服务器到插件,有关于事件的通知,如服务器启动、服务器恢复、服务器准备好接受连接以及服务器即将提交事务。在另一个方向上,插件指示服务器执行动作,如提交或中止正在进行的事务,或将事务排队到中继日志中。

Group Replication 插件架构的下一层是一组组件,当通知路由到它们时会做出反应。捕获组件负责跟踪正在执行的事务相关的上下文。应用程序组件负责在数据库上执行远程事务。恢复组件管理分布式恢复,并负责通过选择捐赠者、管理赶上过程和对捐赠者故障做出反应,使加入组的服务器保持最新。

沿着堆栈继续,复制协议模块包含复制协议的具体逻辑。它处理冲突检测,并接收和传播事务到组中。

Group Replication 插件架构的最后两层是 Group Communication System(GCS)API 和基于 Paxos 的群组通信引擎(XCom)的实现。GCS API 是一个高级 API,抽象出构建复制状态机所需的属性(参见第 20.1 节,“Group Replication 背景”)。因此,它将消息传递层的实现与插件的其余上层分离开来。群组通信引擎处理与复制组成员的通信。

20.2 开始

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-getting-started.html

20.2.1 在单主模式下部署群组复制

20.2.2 本地部署群组复制

MySQL Group Replication 是作为 MySQL 服务器的插件提供的;组中的每个服务器都需要配置和安装插件。本节提供了一个详细的教程,介绍了创建至少三个成员的复制组所需的步骤。

提示

要部署多个 MySQL 实例,您可以使用 InnoDB 集群,它使您能够轻松管理一组 MySQL 服务器实例在 MySQL Shell 中。InnoDB 集群将 MySQL Group Replication 封装在一个编程环境中,使您能够轻松部署一组 MySQL 实例以实现高可用性。此外,InnoDB 集群与 MySQL Router 无缝接口,使您的应用程序能够连接到集群而无需编写自己的故障转移过程。然而,对于不需要高可用性的类似用例,您可以使用 InnoDB ReplicaSet。有关 MySQL Shell 的安装说明,请参阅这里。

20.2.1 在单主模式下部署组复制

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-deploying-in-single-primary-mode.html

20.2.1.1 部署用于组复制的实例

20.2.1.2 配置用于组复制的实例

20.2.1.3 分布式恢复的用户凭据

20.2.1.4 启动组复制

20.2.1.5 引导组

20.2.1.6 将实例添加到组中

组中的每个 MySQL 服务器实例可以运行在独立的物理主机上,这是部署组复制的推荐方式。本节解释了如何创建一个由三个 MySQL Server 实例组成的复制组,每个实例运行在不同的主机上。有关在同一主机上部署运行组复制的多个 MySQL 服务器实例的信息,请参见第 20.2.2 节,“在本地部署组复制”,例如用于测试目的。

图 20.7 组架构

三个服务器实例,S1、S2 和 S3,作为一个互联的组部署,并且客户端与每个服务器实例通信。
三个服务器实例,S1、S2 和 S3,作为一个互联的组部署,并且客户端与每个服务器实例通信。

本教程解释了如何获取并部署带有组复制插件的 MySQL Server,如何在创建组之前配置每个服务器实例,以及如何使用性能模式监视来验证一切是否正常运行。

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-deploying-instances.html

20.2.1.1 部署用于组复制的实例

第一步是部署至少三个 MySQL Server 实例,此过程演示了在多个主机上使用实例的方法,命名为 s1、s2 和 s3。假设每个主机上都安装了 MySQL Server(参见 Chapter 2, Installing MySQL)。MySQL Server 8.0 提供了 Group Replication 插件;不需要额外的软件,但插件必须安装在运行中的 MySQL 服务器上。请参见 Section 20.2.1.1, “Deploying Instances for Group Replication”;更多信息,请参见 Section 7.6, “MySQL Server Plugins”。

在这个示例中,使用了三个实例来组成一个组,这是创建组的最小实例数。增加更多实例可以增加组的容错能力。例如,如果组由三个成员组成,在一个实例故障的情况下,组可以继续运行。但在另一个实例故障的情况下,组将无法继续处理写事务。通过增加更多实例,组在继续处理事务的同时可以容忍更多服务器的故障。可以在一个组中使用的最大实例数为九。更多信息请参见 Section 20.1.4.2, “Failure Detection”。

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-configuring-instances.html

20.2.1.2 为 Group Replication 配置实例

本节解释了要为用于 Group Replication 的 MySQL Server 实例配置的配置设置。有关背景信息,请参阅 Section 20.3, “Requirements and Limitations”。

  • 存储引擎
  • 复制框架
  • Group Replication 设置
存储引擎

对于 Group Replication,数据必须存储在 InnoDB 事务性存储引擎中(详情请参阅 Section 20.3.1, “Group Replication Requirements”)。使用其他存储引擎,包括临时的 MEMORY 存储引擎,可能会导致 Group Replication 中的错误。请设置 disabled_storage_engines 系统变量如下以防止其使用:

代码语言:javascript
复制
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"

请注意,当禁用 MyISAM 存储引擎时,当您将 MySQL 实例升级到仍在使用 mysql_upgrade 的版本(在 MySQL 8.0.16 之前),mysql_upgrade 可能会失败并显示错误。为了处理这个问题,您可以在运行 mysql_upgrade 时重新启用该存储引擎,然后在重新启动服务器时再次禁用它。更多信息,请参阅 Section 6.4.5, “mysql_upgrade — Check and Upgrade MySQL Tables”。

复制框架

以下设置根据 MySQL Group Replication 的要求配置复制。

代码语言:javascript
复制
server_id=1
gtid_mode=ON
enforce_gtid_consistency=ON

这些设置配置服务器使用唯一标识号 1,启用 Section 19.1.3, “Replication with Global Transaction Identifiers”,并且只允许执行可以安全记录使用 GTID 的语句。

在 MySQL 8.0.20 及更早版本中,还需要以下设置:

代码语言:javascript
复制
binlog_checksum=NONE

此设置禁用写入二进制日志的事件的校验和,默认情况下为启用状态。从 MySQL 8.0.21 开始,组复制支持二进制日志中的校验和,并可以使用它们来验证某些通道上事件的完整性,因此您可以使用默认设置。有关更多详细信息,请参见第 20.3.2 节,“组复制限制”。

如果您使用的是早于 8.0.3 的 MySQL 版本,在该版本中改进了复制的默认值,您还需要将这些行添加到成员的选项文件中。如果在后续版本的选项文件中有这些系统变量之一,请确保它们设置如下所示。有关更多详细信息,请参见第 20.3.1 节,“组复制要求”。

代码语言:javascript
复制
log_bin=binlog
log_slave_updates=ON
binlog_format=ROW
master_info_repository=TABLE
relay_log_info_repository=TABLE
transaction_write_set_extraction=XXHASH64
组复制设置

此时,选项文件确保服务器已配置并被指示在给定配置下实例化复制基础设施。以下部分为服务器配置组复制设置。

代码语言:javascript
复制
plugin_load_add='group_replication.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "s1:33061"
group_replication_group_seeds= "s1:33061,s2:33061,s3:33061"
group_replication_bootstrap_group=off
  • plugin-load-add将组复制插件添加到服务器在启动时加载的插件列表中。在生产部署中,这比手动安装插件更可取。
  • 配置group_replication_group_name告诉插件,它正在加入或创建的组名为"aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"。 group_replication_group_name的值必须是有效的 UUID。您可以使用SELECT UUID()来生成一个。此 UUID 是 GTID 的一部分,当来自客户端的事务被组成员接收,并且由组成员内部生成的视图更改事件被写入二进制日志时使用。
  • group_replication_start_on_boot变量配置为off会指示插件在服务器启动时不自动启动操作。在设置组复制时很重要,因为这样可以确保您在手动启动插件之前可以配置服务器。一旦成员配置完成,您可以将group_replication_start_on_boot设置为on,这样组复制将在服务器启动时自动启动。
  • 配置group_replication_local_address设置成员用于与组内其他成员进行内部通信的网络地址和端口。组复制使用此地址进行涉及组通信引擎(XCom,一种 Paxos 变体)的远程实例的内部成员之间连接。 重要 组复制本地地址必须与用于 SQL 客户端连接的主机名和端口不同,这些由 MySQL 服务器的hostnameport系统变量定义。它不能用于客户端应用程序。它只能用于运行组复制时组成员之间的内部通信。 group_replication_local_address配置的网络地址必须由所有组成员解析。例如,如果每个服务器实例位于具有固定网络地址的不同机器上,你可以使用机器的 IP 地址,例如 10.0.0.1。如果使用主机名,必须使用完全限定名称,并确保通过 DNS、正确配置的/etc/hosts文件或其他名称解析过程解析。从 MySQL 8.0.14 开始,IPv6 地址(或解析为其的主机名)也可以使用,以及 IPv4 地址。一个组可以包含使用 IPv6 和使用 IPv4 的成员的混合。有关组复制对 IPv6 网络的支持以及混合 IPv4 和 IPv6 组的更多信息,请参阅第 20.5.5 节,“IPv6 和混合 IPv6 和 IPv4 组的支持”。 推荐的group_replication_local_address端口是 33061。group_replication_local_address被组复制用作复制组内组成员的唯一标识符。只要主机名或 IP 地址都不同,你可以为所有复制组成员使用相同的端口,就像在本教程中演示的那样。或者,只要端口都不同,你可以为所有成员使用相同的主机名或 IP 地址,例如在第 20.2.2 节,“本地部署组复制”中所示。 现有成员为组复制的分布式恢复过程提供给加入成员的连接,并非由group_replication_local_address配置的网络地址。在 MySQL 8.0.20 之前,组成员为分布式恢复提供其标准 SQL 客户端连接给加入成员,由 MySQL 服务器的hostnameport系统变量指定。从 MySQL 8.0.21 开始,组成员可以为加入成员提供一组专用客户端连接作为分布式恢复的备用端点。更多详情,请参阅第 20.5.4.1 节,“分布式恢复的连接”。 重要 如果加入成员无法正确使用由 MySQL 服务器的hostname系统变量定义的主机名来识别其他成员,分布式恢复可能会失败。建议运行 MySQL 的操作系统具有经过正确配置的唯一主机名,可以使用 DNS 或本地设置。服务器用于 SQL 客户端连接的主机名可以在性能模式表replication_group_membersMember_host列中验证。如果多个组成员外部化了操作系统设置的默认主机名,加入成员可能无法将其解析为正确的成员地址,无法连接进行分布式恢复。在这种情况下,您可以使用 MySQL 服务器的report_host系统变量为每个服务器配置一个唯一的主机名来外部化。
  • 配置group_replication_group_seeds设置了组成员的主机名和端口,新成员使用这些信息来建立与组的连接。这些成员被称为种子成员。一旦连接建立,组成员信息将列在性能模式表replication_group_members中。通常group_replication_group_seeds列表包含每个组成员的group_replication_local_addresshostname:port,但这并非强制,可以选择一部分组成员作为种子。 重要 在group_replication_group_seeds中列出的hostname:port是种子成员的内部网络地址,由group_replication_local_address配置,而不是用于 SQL 客户端连接的hostname:port,例如在性能模式表replication_group_members中显示。 启动组的服务器不使用此选项,因为它是初始服务器,负责引导组。换句话说,启动组的服务器上存在的任何数据都将用作下一个加入成员的数据。第二个加入的服务器请求组内唯一的成员加入,第二个服务器上缺失的数据将从引导成员的捐赠数据中复制,然后组扩展。第三个加入的服务器可以请求其中任何两个加入,数据将同步到新成员,然后组再次扩展。后续服务器加入时重复此过程。 警告 当同时加入多个服务器时,请确保它们指向已经在组内的种子成员。不要使用正在加入组的成员作为种子,因为当联系时它们可能尚未加入组。 最好的做法是首先启动引导成员,并让它创建组。然后将其设置为其余加入成员的种子成员。这样确保在加入其余成员时已经形成了一个组。 不支持同时创建组并加入多个成员。这样做可能会成功,但有可能操作竞争,然后加入组的操作最终会出现错误或超时。 加入成员必须使用种子成员在group_replication_group_seeds选项中广告的相同协议(IPv4 或 IPv6)与种子成员通信。为了 Group Replication 的 IP 地址权限,种子成员的允许列表必须包含加入成员的 IP 地址,以供种子成员提供的协议使用,或者解析为该协议的地址的主机名。如果加入成员的协议与种子成员广告的协议不匹配,则必须设置并允许此地址或主机名,以及加入成员的group_replication_local_address。如果加入成员没有适当协议的允许地址,则其连接尝试将被拒绝。有关更多信息,请参见 Section 20.6.4, “Group Replication IP Address Permissions”。
  • 配置group_replication_bootstrap_group指示插件是否引导组。在这种情况下,即使s1是组的第一个成员,我们在选项文件中将此变量设置为关闭。相反,我们在实例运行时配置group_replication_bootstrap_group,以确保只有一个成员实际引导组。 重要 group_replication_bootstrap_group变量必须在任何时候仅在属于组的一个服务器实例上启用,通常是您引导组的第一次(或者整个组被关闭并重新启动的情况下)。如果多次引导组,例如当多个服务器实例设置了此选项时,则可能会创建人为的脑裂情况,即存在具有相同名称的两个不同组。始终在第一个服务器实例上线后设置group_replication_bootstrap_group=off

本教程中描述的系统变量是启动新成员所需的配置设置,但还有其他系统变量可用于配置组成员。这些列在 Section 20.9, “Group Replication Variables”中。

重要

一些系统变量,有些是特定于组复制,有些不是,都是组范围的配置设置,必须在所有组成员上具有相同的值。如果组成员为其中一个这些系统变量设置了值,并且加入的成员为其设置了不同的值,则加入的成员无法加入组,并返回错误消息。如果组成员为此系统变量设置了值,而加入的成员不支持该系统变量,则无法加入组。所有这些系统变量都在第 20.9 节,“组复制变量”中标识。

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-user-credentials.html

20.2.1.3 分布式恢复的用户凭据

组复制使用分布式恢复过程在加入组时同步组成员。分布式恢复涉及将捐赠者的二进制日志中的事务传输到加入成员,使用名为group_replication_recovery的复制通道。因此,您必须设置具有正确权限的复制用户,以便组复制可以建立直接成员之间的复制通道。如果组成员已设置为支持远程克隆操作作为分布式恢复的一部分,该操作从 MySQL 8.0.17 开始提供,那么此复制用户也用作捐赠者上的克隆用户,并且对于此角色也需要正确的权限。有关分布式恢复的完整描述,请参见第 20.5.4 节,“分布式恢复”。

每个组成员上的分布式恢复必须使用相同的复制用户。可以在二进制日志中记录为分布式恢复创建复制用户的过程,然后依靠分布式恢复来复制用于创建用户的语句。或者,您可以在创建复制用户之前禁用二进制日志记录,然后在每个成员上手动创建用户,例如,如果您想避免更改传播到其他服务器实例。如果这样做,请确保在配置用户后重新启用二进制日志记录。

重要提示

如果您的组的分布式恢复连接使用 SSL,那么在加入成员连接到捐赠者之前,必须在每台服务器上创建复制用户。有关为分布式恢复连接设置 SSL 并创建需要 SSL 的复制用户的说明,请参见第 20.6.3 节,“保护分布式恢复连接”

重要提示

默认情况下,在 MySQL 8 中创建的用户使用第 8.4.1.2 节,“缓存 SHA-2 可插拔认证”。如果用于分布式恢复的复制用户使用缓存 SHA-2 认证插件,并且在分布式恢复连接中使用 SSL,那么 RSA 密钥对用于密码交换。您可以将复制用户的公钥复制到加入成员,或者在请求时配置捐赠者提供公钥。有关如何执行此操作的说明,请参见第 20.6.3.1 节,“分布式恢复的安全用户凭据”。

要为分布式恢复创建复制用户,请按照以下步骤进行:

启动 MySQL 服务器实例,然后连接客户端。

如果要禁用二进制日志记录,以便在每个实例上单独创建复制用户,请执行以下语句:

代码语言:javascript
复制
mysql> SET SQL_LOG_BIN=0;

创建一个具有以下权限的 MySQL 用户:

  • REPLICATION SLAVE,用于与捐赠者建立分布式恢复连接以检索数据。
  • CONNECTION_ADMIN,确保如果涉及的服务器之一被置于脱机模式,则不会终止 Group Replication 连接。
  • BACKUP_ADMIN,如果复制组中的服务器已设置为支持克隆(参见 Section 20.5.4.2, “Cloning for Distributed Recovery”)。此权限在分布式恢复的克隆操作中,需要成员作为捐赠者时才需要。
  • GROUP_REPLICATION_STREAM,如果 MySQL 通信堆栈用于复制组(参见 Section 20.6.1, “Communication Stack for Connection Security Management”)。此权限要求用户帐户能够使用 MySQL 通信堆栈建立和维护 Group Replication 的连接。

在此示例中显示了用户*rpl_user和密码password*。在配置服务器时,请使用适当的用户名和密码:

代码语言:javascript
复制
mysql> CREATE USER *rpl_user*@'%' IDENTIFIED BY '*password*';
mysql> GRANT REPLICATION SLAVE ON *.* TO *rpl_user*@'%';
mysql> GRANT CONNECTION_ADMIN ON *.* TO *rpl_user*@'%';
mysql> GRANT BACKUP_ADMIN ON *.* TO *rpl_user*@'%';
mysql> GRANT GROUP_REPLICATION_STREAM ON *.* TO *rpl_user*@'%';
mysql> FLUSH PRIVILEGES;

如果您禁用了二进制日志记录,请在创建用户后立即通过以下语句启用它:

代码语言:javascript
复制
mysql> SET SQL_LOG_BIN=1;

创建复制用户后,必须向服务器提供用户凭据,以供分布式恢复使用。您可以通过将用户凭据设置为group_replication_recovery通道的凭据,使用CHANGE REPLICATION SOURCE TO语句(从 MySQL 8.0.23 开始)或CHANGE MASTER TO语句(MySQL 8.0.23 之前)。或者,从 MySQL 8.0.21 开始,您可以在START GROUP_REPLICATION语句中指定分布式恢复的用户凭据。

  • 使用CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO设置的用户凭据以明文形式存储在服务器上的复制元数据存储库中。它们在启动 Group Replication 时应用,包括如果group_replication_start_on_boot系统变量设置为ON时的自动启动。
  • START GROUP_REPLICATION中指定的用户凭据仅保存在内存中,并且通过STOP GROUP_REPLICATION语句或服务器关闭时会被删除。您必须发出START GROUP_REPLICATION语句再次提供凭据,因此不能使用这些凭据自动启动 Group Replication。通过指定用户凭据的这种方法有助于保护 Group Replication 服务器免受未经授权的访问。

有关使用每种提供用户凭据方法的安全影响的更多信息,请参阅 Section 20.6.3.1.3, “提供复制用户凭据的安全性”。如果选择使用CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句提供用户凭据,请立即在服务器实例上发出以下语句,将*rpl_userpassword*替换为创建用户时使用的值:

代码语言:javascript
复制
mysql> CHANGE MASTER TO MASTER_USER='*rpl_user*', MASTER_PASSWORD='*password*' \\
		      FOR CHANNEL 'group_replication_recovery';

Or from MySQL 8.0.23:
mysql> CHANGE REPLICATION SOURCE TO SOURCE_USER='*rpl_user*', SOURCE_PASSWORD='*password*' \\
		      FOR CHANNEL 'group_replication_recovery';

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-launching.html

20.2.1.4 启动 Group Replication

首先需要确保在服务器 s1 上安装了 Group Replication 插件。如果在选项文件中使用了 plugin_load_add='group_replication.so',那么 Group Replication 插件已经安装好了,您可以继续下一步操作。否则,您必须手动安装该插件;要做到这一点,使用 mysql 客户端连接到服务器,并执行这里显示的 SQL 语句:

代码语言:javascript
复制
mysql> INSTALL PLUGIN group_replication SONAME 'group_replication.so';

重要提示

在加载 Group Replication 之前,mysql.session 用户必须存在。mysql.session 是在 MySQL 版本 8.0.2 中添加的。如果您的数据字典是使用早期版本初始化的,则必须执行 MySQL 升级过程(参见 第三章,升级 MySQL)。如果未运行升级,则 Group Replication 在启动时会出现错误消息,指出尝试使用用户 mysql.session@localhost 访问服务器时出错。确保用户存在于服务器中,并且在服务器更新后运行了 mysql_upgrade。

要检查插件是否成功安装,请执行 SHOW PLUGINS; 并检查输出。应该显示类似于以下内容:

代码语言:javascript
复制
mysql> SHOW PLUGINS;
+----------------------------+----------+--------------------+----------------------+-------------+
| Name                       | Status   | Type               | Library              | License     |
+----------------------------+----------+--------------------+----------------------+-------------+
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL                 | PROPRIETARY |

(...)

| group_replication          | ACTIVE   | GROUP REPLICATION  | group_replication.so | PROPRIETARY |
+----------------------------+----------+--------------------+----------------------+-------------+

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-bootstrap.html

20.2.1.5 引导组

首次启动组的过程称为引导。您使用group_replication_bootstrap_group系统变量来引导一个组。引导应该只由单个服务器执行,即启动组的服务器,并且只执行一次。这就是为什么group_replication_bootstrap_group选项的值未存储在实例的选项文件中。如果它保存在选项文件中,在重新启动时,服务器会自动用相同名称引导第二个组。这将导致具有相同名称的两个不同组。相同的推理适用于设置为ON时停止和重新启动插件。因此,为了安全地引导组,请连接到 s1 并执行以下语句:

代码语言:javascript
复制
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
mysql> START GROUP_REPLICATION;
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;

或者,如果您正在为分布式恢复提供用户凭据START GROUP_REPLICATION语句(从 MySQL 8.0.21 开始),请执行以下语句:

代码语言:javascript
复制
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
mysql> START GROUP_REPLICATION USER='*rpl_user*', PASSWORD='*password*';
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;

一旦START GROUP_REPLICATION语句返回,组已经启动。您可以检查组现在是否已创建,并且其中有一个成员:

代码语言:javascript
复制
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+---------------+-------------+----------------+----------------------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE  | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
+---------------------------+--------------------------------------+-------------+-------------+---------------+-------------+----------------+----------------------------+
| group_replication_applier | ce9be252-2b71-11e6-b8f4-00212844f856 |   s1        |       3306  | ONLINE        |             |                | XCom                       |
+---------------------------+--------------------------------------+-------------+-------------+---------------+-------------+----------------+----------------------------+
1 row in set (0.0108 sec)

这个表中的信息确认了组中有一个具有唯一标识符ce9be252-2b71-11e6-b8f4-00212844f856的成员,它处于ONLINE状态,并在端口3306上的s1上监听客户端连接。

用于演示服务器确实处于组中并且能够处理负载的目的,创建一个表并向其中添加一些内容。

代码语言:javascript
复制
mysql> CREATE DATABASE test;
mysql> USE test;
mysql> CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL);
mysql> INSERT INTO t1 VALUES (1, 'Luis');

检查表t1的内容和二进制日志。

代码语言:javascript
复制
mysql> SELECT * FROM t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+

mysql> SHOW BINLOG EVENTS;
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
| Log_name      | Pos | Event_type     | Server_id | End_log_pos | Info                                                               |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+
| binlog.000001 |   4 | Format_desc    |         1 |         123 | Server ver: 8.0.36-log, Binlog ver: 4                              |
| binlog.000001 | 123 | Previous_gtids |         1 |         150 |                                                                    |
| binlog.000001 | 150 | Gtid           |         1 |         211 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1'  |
| binlog.000001 | 211 | Query          |         1 |         270 | BEGIN                                                              |
| binlog.000001 | 270 | View_change    |         1 |         369 | view_id=14724817264259180:1                                        |
| binlog.000001 | 369 | Query          |         1 |         434 | COMMIT                                                             |
| binlog.000001 | 434 | Gtid           |         1 |         495 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:2'  |
| binlog.000001 | 495 | Query          |         1 |         585 | CREATE DATABASE test                                               |
| binlog.000001 | 585 | Gtid           |         1 |         646 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:3'  |
| binlog.000001 | 646 | Query          |         1 |         770 | use `test`; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL) |
| binlog.000001 | 770 | Gtid           |         1 |         831 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:4'  |
| binlog.000001 | 831 | Query          |         1 |         899 | BEGIN                                                              |
| binlog.000001 | 899 | Table_map      |         1 |         942 | table_id: 108 (test.t1)                                            |
| binlog.000001 | 942 | Write_rows     |         1 |         984 | table_id: 108 flags: STMT_END_F                                    |
| binlog.000001 | 984 | Xid            |         1 |        1011 | COMMIT /* xid=38 */                                                |
+---------------+-----+----------------+-----------+-------------+--------------------------------------------------------------------+

如上所示,数据库和表对象已创建,并且它们对应的 DDL 语句已写入二进制日志。此外,数据已插入到表中并写入二进制日志,因此可以通过从捐赠者的二进制日志进行状态传输来用于分布式恢复。

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-adding-instances.html

20.2.1.6 向组中添加实例

此时,组中有一个成员,服务器 s1,其中包含一些数据。现在是扩展组的时候了,通过添加之前配置的其他两台服务器。

20.2.1.6.1 添加第二个实例

要添加第二个实例,服务器 s2,首先为其创建配置文件。配置与用于服务器 s1 的配置类似,除了诸如server_id之类的内容。以下列出了不同的行。

代码语言:javascript
复制
[mysqld]

#
# Disable other storage engines
#
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"

#
# Replication configuration parameters
#
server_id=2
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE # Not needed from 8.0.21

#
# Group Replication configuration
#
plugin_load_add='group_replication.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "s2:33061"
group_replication_group_seeds= "s1:33061,s2:33061,s3:33061"
group_replication_bootstrap_group= off

与为服务器 s1 执行的过程类似,放置选项文件后启动服务器。然后按以下方式配置分布式恢复凭据。这些命令与在设置服务器 s1 时使用的命令相同,因为用户在组内共享。此成员需要在第 20.2.1.3 节,“分布式恢复的用户凭据”中配置相同的复制用户。如果您依赖分布式恢复来在所有成员上配置用户,则当 s2 连接到种子 s1 时,复制用户将被复制或克隆到 s1。如果在配置用户凭据时未启用二进制日志记录,并且不使用远程克隆操作进行状态传输,则必须在 s2 上创建复制用户。在这种情况下,连接到 s2 并发出:

代码语言:javascript
复制
SET SQL_LOG_BIN=0;
CREATE USER *rpl_user*@'%' IDENTIFIED BY '*password*';
GRANT REPLICATION SLAVE ON *.* TO *rpl_user*@'%';
GRANT CONNECTION_ADMIN ON *.* TO *rpl_user*@'%';
GRANT BACKUP_ADMIN ON *.* TO *rpl_user*@'%';
GRANT GROUP_REPLICATION_STREAM ON *.* TO *rpl_user*@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;

如果您正在使用CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句提供用户凭据,请在此之后发出以下语句:

代码语言:javascript
复制
CHANGE MASTER TO MASTER_USER='*rpl_user*', MASTER_PASSWORD='*password*' \\
	FOR CHANNEL 'group_replication_recovery';

Or from MySQL 8.0.23:
CHANGE REPLICATION SOURCE TO SOURCE_USER='*rpl_user*', SOURCE_PASSWORD='*password*' \\
	FOR CHANNEL 'group_replication_recovery';

提示

如果您正在使用缓存的 SHA-2 身份验证插件,这是 MySQL 8 中的默认设置,请参阅第 20.6.3.1.1 节,“具有缓存 SHA-2 身份验证插件的复制用户”。

如有必要,安装组复制插件,请参阅第 20.2.1.4 节,“启动组复制”。

启动组复制,s2 开始加入组的过程。

代码语言:javascript
复制
mysql> START GROUP_REPLICATION;

或者,如果您正在为START GROUP_REPLICATION语句提供分布式恢复的用户凭据(从 MySQL 8.0.21 开始):

代码语言:javascript
复制
mysql> START GROUP_REPLICATION USER='*rpl_user*', PASSWORD='*password*';

与在 s1 上执行的先前步骤不同,这里的区别在于您需要引导组,因为组已经存在。换句话说,在 s2 上 group_replication_bootstrap_group 设置为OFF,并且在启动 Group Replication 之前不需要发出SET GLOBAL group_replication_bootstrap_group=ON;,因为组已经由服务器 s1 创建和引导。此时,服务器 s2 只需要添加到已经存在的组中。

提示

当 Group Replication 成功启动并且服务器加入组时,它会检查 super_read_only 变量。通过在成员的配置文件中将 super_read_only 设置为 ON,您可以确保由于任何原因在启动 Group Replication 时失败的服务器不接受事务。如果服务器应该作为读写实例加入组,例如作为单主组中的主服务器或作为多主组的成员,当 super_read_only 变量设置为 ON 时,加入组时它会被设置为 OFF。

再次检查 performance_schema.replication_group_members 表,显示组中现在有两个ONLINE服务器。

代码语言:javascript
复制
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
| group_replication_applier | 395409e1-6dfa-11e6-970b-00212844f856 |   s1        |        3306 | ONLINE       | PRIMARY     | 8.0.27         | XCom                       |
| group_replication_applier | ac39f1e6-6dfa-11e6-a69d-00212844f856 |   s2        |        3306 | ONLINE       | SECONDARY   | 8.0.27         | XCom                       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+

当 s2 尝试加入组时,第 20.5.4 节,“分布式恢复” 确保 s2 应用了与 s1 应用的相同事务。一旦此过程完成,s2 可以作为成员加入组,并在此时标记为ONLINE。换句话说,它必须已经自动赶上了服务器 s1。一旦 s2 处于ONLINE状态,它就开始与组处理事务。验证 s2 是否已经与服务器 s1 同步如下。

代码语言:javascript
复制
mysql> SHOW DATABASES LIKE 'test';
+-----------------+
| Database (test) |
+-----------------+
| test            |
+-----------------+

mysql> SELECT * FROM test.t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+

mysql> SHOW BINLOG EVENTS;
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
| Log_name      | Pos  | Event_type     | Server_id | End_log_pos | Info                                                               |
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
| binlog.000001 |    4 | Format_desc    |         2 |         123 | Server ver: 8.0.36-log, Binlog ver: 4                              |
| binlog.000001 |  123 | Previous_gtids |         2 |         150 |                                                                    |
| binlog.000001 |  150 | Gtid           |         1 |         211 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1'  |
| binlog.000001 |  211 | Query          |         1 |         270 | BEGIN                                                              |
| binlog.000001 |  270 | View_change    |         1 |         369 | view_id=14724832985483517:1                                        |
| binlog.000001 |  369 | Query          |         1 |         434 | COMMIT                                                             |
| binlog.000001 |  434 | Gtid           |         1 |         495 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:2'  |
| binlog.000001 |  495 | Query          |         1 |         585 | CREATE DATABASE test                                               |
| binlog.000001 |  585 | Gtid           |         1 |         646 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:3'  |
| binlog.000001 |  646 | Query          |         1 |         770 | use `test`; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL) |
| binlog.000001 |  770 | Gtid           |         1 |         831 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:4'  |
| binlog.000001 |  831 | Query          |         1 |         890 | BEGIN                                                              |
| binlog.000001 |  890 | Table_map      |         1 |         933 | table_id: 108 (test.t1)                                            |
| binlog.000001 |  933 | Write_rows     |         1 |         975 | table_id: 108 flags: STMT_END_F                                    |
| binlog.000001 |  975 | Xid            |         1 |        1002 | COMMIT /* xid=30 */                                                |
| binlog.000001 | 1002 | Gtid           |         1 |        1063 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:5'  |
| binlog.000001 | 1063 | Query          |         1 |        1122 | BEGIN                                                              |
| binlog.000001 | 1122 | View_change    |         1 |        1261 | view_id=14724832985483517:2                                        |
| binlog.000001 | 1261 | Query          |         1 |        1326 | COMMIT                                                             |
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+

如上所示,第二个服务器已添加到组中,并且已自动复制了来自服务器 s1 的更改。换句话说,应用在 s1 上直到 s2 加入组的时间点的事务已经复制到 s2。

20.2.1.6.2 添加额外实例

将额外的实例添加到组中本质上与添加第二个服务器的步骤相同,只是配置必须像对服务器 s2 进行配置一样进行更改。总结所需的命令如下:

创建配置文件。

代码语言:javascript
复制
[mysqld]

#
# Disable other storage engines
#
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"

#
# Replication configuration parameters
#
server_id=3
gtid_mode=ON
enforce_gtid_consistency=ON
binlog_checksum=NONE # Not needed from 8.0.21

#
# Group Replication configuration
#
plugin_load_add='group_replication.so'
group_replication_group_name="aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"
group_replication_start_on_boot=off
group_replication_local_address= "s3:33061"
group_replication_group_seeds= "s1:33061,s2:33061,s3:33061"
group_replication_bootstrap_group= off

启动服务器并连接到它。为分布式恢复创建复制用户。

代码语言:javascript
复制
SET SQL_LOG_BIN=0;
CREATE USER *rpl_user*@'%' IDENTIFIED BY '*password*';
GRANT REPLICATION SLAVE ON *.* TO *rpl_user*@'%';
GRANT CONNECTION_ADMIN ON *.* TO *rpl_user*@'%';
GRANT BACKUP_ADMIN ON *.* TO *rpl_user*@'%';
GRANT GROUP_REPLICATION_STREAM ON *.* TO *rpl_user*@'%';
FLUSH PRIVILEGES;
SET SQL_LOG_BIN=1;

如果您正在使用CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句提供用户凭据,请在此之后发出以下语句:

代码语言:javascript
复制
CHANGE MASTER TO MASTER_USER='*rpl_user*', MASTER_PASSWORD='*password*' \\
	FOR CHANNEL 'group_replication_recovery';

Or from MySQL 8.0.23:
CHANGE REPLICATION SOURCE TO SOURCE_USER='*rpl_user*', SOURCE_PASSWORD='*password*' \\
	FOR CHANNEL 'group_replication_recovery';

如有必要,安装组复制插件。

代码语言:javascript
复制
INSTALL PLUGIN group_replication SONAME 'group_replication.so';

启动组复制。

代码语言:javascript
复制
mysql> START GROUP_REPLICATION;

或者,如果您正在为分布式恢复提供用户凭据,可以在START GROUP_REPLICATION语句中执行此操作(从 MySQL 8.0.21 开始):

代码语言:javascript
复制
mysql> START GROUP_REPLICATION USER='*rpl_user*', PASSWORD='*password*';

此时服务器 s3 已经启动并运行,已加入组并赶上了组内其他服务器的进度。再次查看performance_schema.replication_group_members表可以确认这一点。

代码语言:javascript
复制
mysql> SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
| group_replication_applier | 395409e1-6dfa-11e6-970b-00212844f856 |   s1        |        3306 | ONLINE       | PRIMARY     | 8.0.27         | XCom                       |
| group_replication_applier | 7eb217ff-6df3-11e6-966c-00212844f856 |   s3        |        3306 | ONLINE       | SECONDARY   | 8.0.27         | XCom                       |
| group_replication_applier | ac39f1e6-6dfa-11e6-a69d-00212844f856 |   s2        |        3306 | ONLINE       | SECONDARY   | 8.0.27         | XCom                       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+

在服务器 s2 或服务器 s1 上发出相同的查询会得到相同的结果。此外,您可以验证服务器 s3 已经赶上:

代码语言:javascript
复制
mysql> SHOW DATABASES LIKE 'test';
+-----------------+
| Database (test) |
+-----------------+
| test            |
+-----------------+

mysql> SELECT * FROM test.t1;
+----+------+
| c1 | c2   |
+----+------+
|  1 | Luis |
+----+------+

mysql> SHOW BINLOG EVENTS;
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
| Log_name      | Pos  | Event_type     | Server_id | End_log_pos | Info                                                               |
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+
| binlog.000001 |    4 | Format_desc    |         3 |         123 | Server ver: 8.0.36-log, Binlog ver: 4                              |
| binlog.000001 |  123 | Previous_gtids |         3 |         150 |                                                                    |
| binlog.000001 |  150 | Gtid           |         1 |         211 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1'  |
| binlog.000001 |  211 | Query          |         1 |         270 | BEGIN                                                              |
| binlog.000001 |  270 | View_change    |         1 |         369 | view_id=14724832985483517:1                                        |
| binlog.000001 |  369 | Query          |         1 |         434 | COMMIT                                                             |
| binlog.000001 |  434 | Gtid           |         1 |         495 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:2'  |
| binlog.000001 |  495 | Query          |         1 |         585 | CREATE DATABASE test                                               |
| binlog.000001 |  585 | Gtid           |         1 |         646 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:3'  |
| binlog.000001 |  646 | Query          |         1 |         770 | use `test`; CREATE TABLE t1 (c1 INT PRIMARY KEY, c2 TEXT NOT NULL) |
| binlog.000001 |  770 | Gtid           |         1 |         831 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:4'  |
| binlog.000001 |  831 | Query          |         1 |         890 | BEGIN                                                              |
| binlog.000001 |  890 | Table_map      |         1 |         933 | table_id: 108 (test.t1)                                            |
| binlog.000001 |  933 | Write_rows     |         1 |         975 | table_id: 108 flags: STMT_END_F                                    |
| binlog.000001 |  975 | Xid            |         1 |        1002 | COMMIT /* xid=29 */                                                |
| binlog.000001 | 1002 | Gtid           |         1 |        1063 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:5'  |
| binlog.000001 | 1063 | Query          |         1 |        1122 | BEGIN                                                              |
| binlog.000001 | 1122 | View_change    |         1 |        1261 | view_id=14724832985483517:2                                        |
| binlog.000001 | 1261 | Query          |         1 |        1326 | COMMIT                                                             |
| binlog.000001 | 1326 | Gtid           |         1 |        1387 | SET @@SESSION.GTID_NEXT= 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:6'  |
| binlog.000001 | 1387 | Query          |         1 |        1446 | BEGIN                                                              |
| binlog.000001 | 1446 | View_change    |         1 |        1585 | view_id=14724832985483517:3                                        |
| binlog.000001 | 1585 | Query          |         1 |        1650 | COMMIT                                                             |
+---------------+------+----------------+-----------+-------------+--------------------------------------------------------------------+

20.2.2 本地部署组复制

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-deploying-locally.html

部署组复制最常见的方式是使用多个服务器实例,以提供高可用性。也可以在本地部署组复制,例如用于测试目的。本节解释了如何在本地部署组复制。

重要

组复制通常部署在多个主机上,因为这样可以提供高可用性。本节中的说明不适用于生产部署,因为所有 MySQL 服务器实例都在同一台主机上运行。如果此主机发生故障,整个组都会失败。因此,此信息应仅用于测试目的,不应在生产环境中使用。

本节解释了如何在一台物理机器上创建一个包含三个 MySQL 服务器实例的复制组。这意味着需要三个数据目录,每个服务器实例一个,并且需要独立配置每个实例。此过程假定 MySQL 服务器已下载并解压缩到名为mysql-8.0的目录中。每个 MySQL 服务器实例都需要一个特定的数据目录。创建一个名为data的目录,然后在该目录中为每个服务器实例创建一个子目录,例如s1s2s3,并对每个实例进行初始化。

代码语言:javascript
复制
mysql-8.0/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-8.0 --datadir=$PWD/data/s1
mysql-8.0/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-8.0 --datadir=$PWD/data/s2
mysql-8.0/bin/mysqld --initialize-insecure --basedir=$PWD/mysql-8.0 --datadir=$PWD/data/s3

data/s1data/s2data/s3中是一个已初始化的数据目录,包含 mysql 系统数据库和相关表等等。要了解更多关于初始化过程的信息,请参见第 2.9.1 节,“初始化数据目录”。

警告

在生产环境中不要使用-initialize-insecure,这只是为了简化教程而使用的。有关安全设置的更多信息,请参见第 20.6 节,“组复制安全”。

本地组复制成员的配置

当您按照第 20.2.1.2 节,“为组复制配置实例”时,您需要为前一节添加的数据目录添加配置。例如:

代码语言:javascript
复制
[mysqld]

# server configuration
datadir=<full_path_to_data>/data/s1
basedir=<full_path_to_bin>/mysql-8.0/

port=24801
socket=<full_path_to_sock_dir>/s1.sock

这些设置配置了 MySQL 服务器使用之前创建的数据目录以及服务器应该打开和开始监听传入连接的端口。

注意

本教程中使用非默认端口 24801,因为三个服务器实例使用相同的主机名。在三台不同机器的设置中,这是不需要的。

组复制需要成员之间的网络连接,这意味着每个成员必须能够解析所有其他成员的网络地址。例如,在本教程中,所有三个实例都在一台机器上运行,因此为了确保成员之间可以联系,您可以在选项文件中添加一行,例如report_host=127.0.0.1

然后,每个成员需要能够连接到其他成员的group_replication_local_address。例如,在成员 s1 的选项文件中添加:

代码语言:javascript
复制
group_replication_local_address= "127.0.0.1:24901"
group_replication_group_seeds= "127.0.0.1:24901,127.0.0.1:24902,127.0.0.1:24903"

这将配置 s1 使用端口 24901 进行与种子成员的内部组通信。对于要添加到组中的每个服务器实例,请在成员的选项文件中进行这些更改。对于每个成员,您必须确保指定了唯一地址,因此对于group_replication_local_address,每个实例使用唯一端口。通常,您希望所有成员都能够作为加入组并且尚未通过组处理事务的成员的种子,因此,请像上面显示的那样将所有端口添加到group_replication_group_seeds

第 20.2.1 节,“在单主模式下部署组复制”的其余步骤同样适用于您以这种方式在本地部署的组。

20.3 需求和限制

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-requirements-and-limitations.html

20.3.1 集群复制需求

20.3.2 集群复制限制

本节列出并解释了集群复制的需求和限制。

20.3.1 Group Replication Requirements

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-requirements.html

  • 基础设施
  • 服务器实例配置

您希望用于 Group Replication 的服务器实例必须满足以下要求。

基础设施

InnoDB 存储引擎。 数据必须存储在InnoDB事务性存储引擎中。事务乐观执行,然后在提交时检查冲突。如果存在冲突,为了在组内保持一致性,一些事务将被回滚。这意味着需要一个事务性存储引擎。此外,InnoDB提供了一些额外功能,使其在与 Group Replication 一起操作时能更好地管理和处理冲突。使用其他存储引擎,包括临时MEMORY存储引擎,可能会导致 Group Replication 中的错误。在将实例与 Group Replication 一起使用之前,请将任何其他存储引擎中的表转换为使用InnoDB。您可以通过在组成员上设置disabled_storage_engines系统变量来阻止使用其他存储引擎,例如:

代码语言:javascript
复制
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"

主键。 每个要被组复制的表必须有一个定义好的主键,或者等效的主键,其中等效主键是一个非空唯一键。这些键被要求作为表中每一行的唯一标识符,使系统能够通过确定每个事务修改了哪些行来确定哪些事务发生了冲突。组复制有自己内置的主键或主键等效的检查,不使用sql_require_primary_key系统变量执行的检查。您可以在运行组复制的服务器实例上设置sql_require_primary_key=ON,并且您可以为组复制通道设置CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句的REQUIRE_TABLE_PRIMARY_KEY_CHECK选项为ON。但是,请注意,您可能会发现一些在组复制内置检查下允许的事务,在设置sql_require_primary_key=ONREQUIRE_TABLE_PRIMARY_KEY_CHECK=ON时不被允许。

网络性能。 MySQL 组复制被设计用于部署在服务器实例非常接近的集群环境中。组的性能和稳定性可能会受到网络延迟和网络带宽的影响。所有组成员之间必须始终保持双向通信。如果某个服务器实例的入站或出站通信被阻止(例如,由防火墙或连接问题),该成员无法在组中运行,并且组成员(包括存在问题的成员)可能无法报告受影响服务器实例的正确成员状态。

从 MySQL 8.0.14 开始,您可以在远程组复制服务器之间使用 IPv4 或 IPv6 网络基础设施,或两者混合,进行 TCP 通信。组复制也可以在虚拟专用网络(VPN)上运行,没有任何限制。

同样从 MySQL 8.0.14 开始,当组复制服务器实例位于同一位置并共享本地组通信引擎(XCom)实例时,会尽可能使用专用输入通道进行通信,而不是 TCP 套接字,以降低开销。对于某些需要远程 XCom 实例之间通信的组复制任务,比如加入一个组,仍然使用 TCP 网络,因此网络性能会影响组的性能。

服务器实例配置

必须按照以下所示配置的选项在组成员的服务器实例上进行配置。

  • 唯一服务器标识符。 使用server_id系统变量为服务器配置一个唯一的服务器 ID,这对于复制拓扑中的所有服务器都是必需的。服务器 ID 必须是介于 1 和(2³²)−1 之间的正整数,并且必须与复制拓扑中任何其他服务器使用的任何其他服务器 ID 不同。
  • 二进制日志激活。 设置--log-bin[=log_file_name]。从 MySQL 8.0 开始,默认情况下启用了二进制日志记录,除非您想更改二进制日志文件的名称,否则不需要指定此选项。组复制会复制二进制日志的内容,因此二进制日志需要处于活动状态才能运行。请参阅第 7.4.4 节,“二进制日志”。
  • 复制更新记录。 设置log_replica_updates=ON(从 MySQL 8.0.26 开始)或log_slave_updates=ON(在 MySQL 8.0.26 之前)。从 MySQL 8.0 开始,此设置是默认的,因此您不需要指定它。组成员需要记录从其提供者在加入时接收并通过复制应用程序应用的事务,并记录他们接收并应用于组中的所有事务。这使得组复制能够通过从现有组成员的二进制日志进行状态传输来进行分布式恢复。
  • 二进制日志行格式。 设置binlog_format=row。这是默认设置,因此您不需要指定它。组复制依赖于基于行的复制格式来在组中的服务器之间一致地传播更改,并提取必要的信息以检测在组中不同服务器上同时执行的事务之间的冲突。从 MySQL 8.0.19 开始,REQUIRE_ROW_FORMAT设置会自动添加到组复制的通道中,以强制在应用事务时使用基于行的复制。请参阅第 19.2.1 节,“复制格式”和第 19.3.3 节,“复制权限检查”。
  • 关闭二进制日志校验和(至 MySQL 8.0.20)。 在 MySQL 8.0.20 及之前的版本中,设置binlog_checksum=NONE。在这些版本中,组复制无法使用校验和,并且不支持其存在于二进制日志中。从 MySQL 8.0.21 开始,组复制支持校验和,因此组成员可以使用默认设置binlog_checksum=CRC32,您不需要指定它。
  • 全局事务标识符开启。gtid_mode=ONenforce_gtid_consistency=ON设置为ON。这些设置不是默认值。基于 GTID 的复制对于 Group Replication 是必需的,它使用全局事务标识符来跟踪已在组中的每个服务器实例上提交的事务。参见第 19.1.3 节,“使用全局事务标识符进行复制”。
  • 复制信息存储库。master_info_repository=TABLErelay_log_info_repository=TABLE设置为TABLE。在 MySQL 8.0 中,这些设置是默认的,FILE设置已被弃用。从 MySQL 8.0.23 开始,这些系统变量的使用已被弃用,因此省略这些系统变量,只允许默认设置。复制应用程序需要将复制元数据写入mysql.slave_master_infomysql.slave_relay_log_info系统表,以确保 Group Replication 插件具有一致的可恢复性和事务管理的复制元数据。参见第 19.2.4.2 节,“复制元数据存储库”。
  • 事务写集提取。transaction_write_set_extraction=XXHASH64设置为XXHASH64,以便在收集要记录到二进制日志的行时,服务器也收集写入集。在 MySQL 8.0 中,这是默认设置,从 MySQL 8.0.26 开始,该系统变量的使用已被弃用。写入集基于每行的主键,并且是一个简化且紧凑的视图,用于唯一标识已更改的行。Group Replication 在所有组成员上使用此信息进行冲突检测和认证。
  • 默认表加密。default_table_encryption设置为所有组成员上的相同值。默认模式和表空间加密可以启用(ON)或禁用(OFF,默认值),只要所有成员的设置相同即可。
  • 表名小写。lower_case_table_names设置为所有组成员上的相同值。对于使用InnoDB存储引擎的情况,设置为 1 是正确的,这是 Group Replication 所需的。请注意,这个设置在所有平台上都不是默认值。
  • 二进制日志依赖跟踪。binlog_transaction_dependency_tracking设置为WRITESET可以根据组的工作负载提高组成员的性能。虽然在应用中继日志中的事务时,组复制在认证后进行自己的并行化,独立于为binlog_transaction_dependency_tracking设置的任何值,但是这个值确实影响了事务在组复制成员的二进制日志中的写入方式。这些日志中的依赖信息用于协助从捐赠者的二进制日志进行分布式恢复的状态传输过程,每当成员加入或重新加入组时都会发生。 注意 当replica_preserve_commit_order设置为ON时,将binlog_transaction_dependency_tracking设置为WRITESET与将其设置为WRITESET_SESSION具有相同的效果。
  • 多线程应用程序。 组复制成员可以配置为多线程副本,使事务可以并行应用。从 MySQL 8.0.27 开始,默认情况下所有副本都配置为多线程。系统变量replica_parallel_workers(从 MySQL 8.0.26 开始)或slave_parallel_workers(MySQL 8.0.26 之前)的非零值启用了成员上的多线程应用程序。从 MySQL 8.0.27 开始,默认值为 4 个并行应用程序线程,最多可以指定 1024 个并行应用程序线程。对于多线程副本,还需要以下设置,这些设置是从 MySQL 8.0.27 开始的默认设置: replica_preserve_commit_order=ON(从 MySQL 8.0.26 开始)或slave_preserve_commit_order=ON(MySQL 8.0.26 之前) 此设置是为了确保并行事务的最终提交与原始事务的顺序相同。组复制依赖于围绕所有参与成员以相同顺序接收和应用已提交事务的一致性机制构建。 replica_parallel_type=LOGICAL_CLOCK(从 MySQL 8.0.26 开始)或slave_parallel_type=LOGICAL_CLOCK(MySQL 8.0.26 之前) 此设置需要与replica_preserve_commit_order=ONslave_preserve_commit_order=ON一起使用。它指定了用于决定在副本上允许哪些事务并行执行的策略。 设置replica_parallel_workers=0slave_parallel_workers=0会禁用并行执行,使得复制品只有一个应用程序线程和没有协调器线程。在这种设置下,replica_parallel_typeslave_parallel_type以及replica_preserve_commit_orderslave_preserve_commit_order选项不起作用,会被忽略。从 MySQL 8.0.27 开始,如果在复制品上使用 GTIDs 时禁用了并行执行,复制品实际上会使用一个并行工作者,以利用在不访问文件位置的情况下重试事务的方法。然而,这种行为对用户不会有任何改变。
  • 分离的 XA 事务。 MySQL 8.0.29 及更高版本支持分离的 XA 事务。分离的事务是指一旦准备好,就不再与当前会话连接的事务。这会自动发生作为执行XA PREPARE的一部分。准备好的 XA 事务可以由另一个连接提交或回滚,然后当前会话可以启动另一个 XA 事务或本地事务,而无需等待刚刚准备的事务完成。 当启用分离的 XA 事务支持(xa_detach_on_prepare = ON)时,任何连接到此服务器的连接都可以列出(使用XA RECOVER)、回滚或提交任何准备好的 XA 事务。此外,在分离的 XA 事务中不能使用临时表。 通过将xa_detach_on_prepare设置为OFF可以禁用对分离的 XA 事务的支持,但这并不推荐。特别是,如果此服务器正在设置为 MySQL 组复制中的一个实例,您应该将此变量保持为其默认值(ON)。 更多信息请参见 Section 15.3.8.2, “XA Transaction States”。

20.3.2 Group Replication 限制

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-limitations.html

  • 组大小限制
  • 事务大小限制

Group Replication 存在以下已知限制。请注意,在故障转移事件期间,多主模式组的限制和问题也可能适用于单主模式集群,而新选举的主节点会清空其来自旧主节点的应用程序队列。

提示

Group Replication 是基于 GTID 的复制构建的,因此您还应该注意 Section 19.1.3.7, “使用 GTID 进行复制的限制”。

  • --upgrade=MINIMAL选项。 Group Replication 无法在使用 MINIMAL 选项(--upgrade=MINIMAL)进行 MySQL Server 升级后启动,因为该选项不会升级复制内部所依赖的系统表。
  • 间隙锁。 Group Replication 的并发事务认证过程不考虑间隙锁,因为间隙锁的信息在InnoDB之外不可用。有关更多信息,请参阅间隙锁。 注意 对于多主模式下的组,除非您的应用程序依赖于REPEATABLE READ语义,我们建议在 Group Replication 中使用READ COMMITTED隔离级别。 InnoDB 在READ COMMITTED中不使用间隙锁,这使得 InnoDB 内部的本地冲突检测与 Group Replication 执行的分布式冲突检测保持一致。对于单主模式下的组,只有主节点接受写操作,因此READ COMMITTED隔离级别对于 Group Replication 并不重要。
  • 表锁和命名锁。 认证过程不考虑表锁(参见 Section 15.3.6, “LOCK TABLES 和 UNLOCK TABLES 语句”)或命名锁(参见GET_LOCK())。
  • 二进制日志校验和。 截至 MySQL 8.0.20,Group Replication 无法使用校验和,也不支持二进制日志中的校验和,因此在配置服务器实例成为组成员时,必须设置binlog_checksum=NONE。从 MySQL 8.0.21 开始,Group Replication 支持校验和,因此组成员可以使用默认设置binlog_checksum=CRC32binlog_checksum 的设置不必对组中的所有成员相同。 当校验和可用时,Group Replication 不会使用它们来验证group_replication_applier通道上的传入事件,因为事件是从多个来源写入到中继日志中的,而在它们实际写入到原始服务器的二进制日志之前,校验和是不会生成的。校验和用于验证group_replication_recovery通道上的事件的完整性,以及组成员上的任何其他复制通道上的事件。
  • 可串行化隔离级别。 SERIALIZABLE 隔离级别在多主组中默认不受支持。将事务隔离级别设置为SERIALIZABLE会配置 Group Replication 拒绝提交事务。
  • 并发 DDL 与 DML 操作。 在使用多主模式时,不支持针对同一对象执行并发数据定义语句和数据操作语句,但在不同的服务器上执行。在对象上执行数据定义语言(DDL)语句期间,在不同服务器实例上执行相同对象的并发数据操作语言(DML)存在冲突的风险,因为在不同实例上执行的冲突 DDL 可能不会被检测到。
  • 具有级联约束的外键。 多主模式组(所有成员都配置为group_replication_single_primary_mode=OFF)不支持具有多级外键依赖关系的表,特别是定义了CASCADING外键约束的表。这是因为由多主模式组执行的导致级联操作的外键约束可能导致未检测到的冲突,并导致组成员之间的数据不一致。因此,我们建议在用于多主模式组的服务器实例上设置group_replication_enforce_update_everywhere_checks=ON以避免未检测到的冲突。 在单主模式下,这不是问题,因为它不允许并发写入到组的多个成员,因此不存在未检测到的冲突风险。
  • 多主模式死锁。 当一个组以多主模式运行时,SELECT .. FOR UPDATE语句可能导致死锁。这是因为锁不在组的成员之间共享,因此对于这样的语句的期望可能无法实现。
  • 复制过滤器。 不能在配置为 Group Replication 的 MySQL 服务器实例上使用全局复制过滤器,因为在某些服务器上过滤事务会导致组无法达成一致状态。可以在与 Group Replication 无直接关系的复制通道上使用特定通道的复制过滤器,例如,当一个组成员同时充当组外源的副本时。不能在group_replication_appliergroup_replication_recovery通道上使用。
  • 加密连接。 MySQL Server 自 MySQL 8.0.16 起支持 TLSv1.3 协议,前提是 MySQL 使用了 OpenSSL 1.1.1 或更高版本进行编译。在 MySQL 8.0.16 和 MySQL 8.0.17 中,如果服务器支持 TLSv1.3,则该协议在组通信引擎中不受支持,无法被 Group Replication 使用。从 MySQL 8.0.18 开始,Group Replication 支持 TLSv1.3,可以用于组通信连接和分布式恢复连接。 在 MySQL 8.0.18 中,TLSv1.3 可以用于 Group Replication 的分布式恢复连接,但group_replication_recovery_tls_versiongroup_replication_recovery_tls_ciphersuites系统变量不可用。因此,捐赠服务器必须允许使用至少一个默认启用的 TLSv1.3 密码套件,如第 8.3.2 节“加密连接 TLS 协议和密码套件”中列出的那样。从 MySQL 8.0.19 开始,您可以使用选项配置客户端支持任意选择的密码套件,包括仅使用非默认密码套件。
  • 克隆操作。 Group Replication 启动并管理用于分布式恢复的克隆操作,但已设置为支持克隆的组成员也可以参与用户手动启动的克隆操作。在 MySQL 8.0.20 之前的版本中,如果操作涉及正在运行 Group Replication 的组成员,则无法手动启动克隆操作。从 MySQL 8.0.20 开始,只要克隆操作不会删除并替换接收方的数据,就可以执行此操作。因此,如果 Group Replication 正在运行,则启动克隆操作的语句必须包含DATA DIRECTORY子句。请参阅 Section 20.5.4.2.4, “Cloning for Other Purposes”。
组大小限制

单个复制组中可以成为成员的 MySQL 服务器的最大数量为 9。如果更多成员尝试加入组,则其请求将被拒绝。这个限制是通过测试和基准测试确定的,作为组在稳定的局域网上可靠运行的安全边界。

事务大小限制

如果单个事务导致消息内容过大,以至于在 5 秒窗口内无法在组成员之间复制消息,那么成员可能会被怀疑失败,然后被驱逐,仅仅因为它们正忙于处理事务。大型事务也可能导致系统由于内存分配问题而变慢。为避免这些问题,请使用以下缓解措施:

  • 如果由于大型消息而发生不必要的驱逐,请使用系统变量group_replication_member_expel_timeout在怀疑失败的成员被驱逐之前提供额外的时间。在初始的 5 秒检测期之后,您可以允许多达一小时的时间,然后才将怀疑的成员从组中驱逐。从 MySQL 8.0.21 开始,默认情况下额外允许 5 秒。
  • 在可能的情况下,在交由 Group Replication 处理之前,尽量限制事务的大小。例如,将与LOAD DATA一起使用的文件拆分为较小的块。
  • 使用系统变量group_replication_transaction_size_limit来指定组接受的最大事务大小。在 MySQL 8.0 中,此系统变量默认为最大事务大小为 150000000 字节(约 143 MB)。超过此大小的事务将被回滚,并且不会发送到 Group Replication 的 Group Communication System (GCS)以分发给组。根据您需要组容忍的最大消息大小调整此变量的值,要牢记处理事务所需的时间与其大小成正比。
  • 使用系统变量group_replication_compression_threshold来指定应用压缩的消息大小阈值。该系统变量默认为 1000000 字节(1 MB),因此大消息会自动进行压缩。当 Group Replication 的 Group Communication System(GCS)接收到一个由group_replication_transaction_size_limit设置允许但超过group_replication_compression_threshold设置的消息时,将执行压缩。更多信息,请参见第 20.7.4 节,“消息压缩”。
  • 使用系统变量group_replication_communication_max_message_size来指定应用分段的消息大小阈值。该系统变量默认为 10485760 字节(10 MiB),因此大消息会自动进行分段。如果压缩后的消息仍超过group_replication_communication_max_message_size限制,GCS 将在压缩后执行分段。为了使复制组使用分段,所有组成员必须使用 MySQL 8.0.16 或更高版本,并且组使用的 Group Replication 通信协议版本必须允许分段。更多信息,请参见第 20.7.5 节,“消息分段”。

最大交易大小、消息压缩和消息分段都可以通过指定相关系统变量的零值来停用。如果您已停用了所有这些保护措施,那么在复制组成员的应用程序线程可以处理的消息的上限大小是成员的replica_max_allowed_packetslave_max_allowed_packet系统变量的值,这些变量的默认和最大值为 1073741824 字节(1 GB)。当接收成员尝试处理超过此限制的消息时,消息将失败。组成员可以发起并尝试传输到组的消息的上限大小为 4294967295 字节(约 4 GB)。这是接受由组复制(XCom,一种 Paxos 变体)的组通信引擎处理后的消息的数据包大小的硬限制,GCS 在处理消息后接收它们。当发起成员尝试广播超过此限制的消息时,消息将失败。

20.4 监视组复制

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-monitoring.html

20.4.1 GTIDs 和组复制

20.4.2 组复制服务器状态

20.4.3 复制组成员表

20.4.4 复制组成员统计表

您可以使用 MySQL 性能模式 监视组复制。这些性能模式表显示特定于组复制的信息:

  • replication_group_member_stats:参见 第 20.4.4 节,“复制组成员统计表”。
  • replication_group_members:参见 第 20.4.3 节,“复制组成员表”。
  • replication_group_communication_information:参见 第 29.12.11.15 节,“复制组通信信息表”。

这些性能模式复制表还显示与组复制相关的信息:

  • replication_connection_status 显示有关组复制的信息,例如从组接收的事务以及在应用程序队列(中继日志)中排队的事务。
  • replication_applier_status 显示与组复制相关的通道和线程的状态。这些也可以用于监视各个工作线程正在做什么。

组复制插件创建的复制通道在此处列出:

  • group_replication_recovery: 用于与分布式恢复相关的复制更改。
  • group_replication_applier: 用于来自组的传入更改,以应用直接来自组的事务。

有关影响组复制的系统变量的信息,请参见第 20.9.1 节,“组复制系统变量”。有关提供有关组复制信息的状态变量的信息,请参见第 20.9.2 节,“组复制状态变量”。

从 MySQL 8.0.21 开始,与组复制生命周期事件相关的消息(除错误外)被分类为系统消息;这些消息始终写入复制组成员的错误日志。您可以使用此信息来查看给定服务器在复制组中的成员资格历史。(以前,这些事件被分类为信息消息;对于 MySQL 服务器的版本早于 8.0.21 的情况,可以通过将log_error_verbosity设置为3将其添加到错误日志中。)

影响整个组的一些生命周期事件会在每个组成员上记录,例如新成员进入ONLINE状态或进行主要选举。其他事件仅在事件发生的成员上记录,例如在成员上启用或禁用超级只读模式,或成员离开组。如果发生频繁,一些可能指示问题的生命周期事件将记录为警告消息,包括成员变得无法访问然后再次可访问,以及成员通过从二进制日志进行状态传输或通过远程克隆操作开始分布式恢复。

注意

如果您正在使用mysqladmin监视一个或多个辅助实例,您应该知道,此实用程序执行的FLUSH STATUS语句会在本地实例上创建一个 GTID 事件,这可能会影响未来的组操作。

20.4.1 GTIDs 和组复制

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-gtids.html

组复制使用 GTIDs(全局事务标识符)来精确跟踪每个服务器实例上已提交的事务。所有组成员都需要设置gtid_mode=ONenforce_gtid_consistency=ON。从客户端接收的事务由接收它们的组成员分配一个 GTID。从组外部源服务器通过异步复制通道接收到的任何复制事务在到达组成员时保留它们的 GTID。

从客户端接收的事务分配的 GTID 使用group_replication_group_name系统变量指定的组名作为标识符的 UUID 部分,而不是接收事务的单个组成员的服务器 UUID。因此,所有直接由组接收的事务都可以被识别并分组在 GTID 集合中,不管最初接收它们的成员是谁。每个组成员都有一块连续的 GTID 保留供其使用,当这些 GTID 被消耗完时,它会保留更多。group_replication_gtid_assignment_block_size系统变量设置了块的大小,默认情况下每个块中有 100 万个 GTID。

当新成员加入时,由组自动生成的视图更改事件(View_change_log_event)在二进制日志中记录时被赋予 GTID。默认情况下,这些事件的 GTID 也使用group_replication_group_name系统变量指定的组名作为标识符的 UUID 部分。从 MySQL 8.0.26 开始,您可以设置 Group Replication 系统变量group_replication_view_change_uuid以在视图更改事件的 GTID 中使用替代 UUID,以便它们易于与从客户端接收的事务区分开来。如果您的设置允许在组之间进行故障切换,并且您需要识别和丢弃特定于备份组的事务,则这可能很有用。替代 UUID 必须与成员的服务器 UUID 不同。它还必须与使用CHANGE REPLICATION SOURCE TO语句的ASSIGN_GTIDS_TO_ANONYMOUS_TRANSACTIONS选项应用于匿名事务的 GTID 中的任何 UUID 不同。

从 MySQL 8.0.27 开始,设置 GTID_ONLY=1REQUIRE_ROW_FORMAT = 1SOURCE_AUTO_POSITION = 1 适用于 Group Replication 通道 group_replication_appliergroup_replication_recovery。这些设置在创建 Group Replication 通道时自动设置,或者当复制组中的成员服务器升级到 8.0.27 或更高版本时自动设置。通常使用 CHANGE REPLICATION SOURCE TO 语句设置这些选项,但请注意,您无法为 Group Replication 通道禁用它们。设置了这些选项后,组成员不会在这些通道的复制元数据存储库中持久保存文件名和文件位置。在必要时,GTID 自动定位和 GTID 自动跳过用于定位正确的接收器和应用程序位置。

额外事务

如果加入成员的 GTID 集中存在在组中现有成员中不存在的事务,则不允许完成分布式恢复过程,并且无法加入该组。如果进行了远程克隆操作,则这些事务将被删除和丢失,因为加入成员的数据目录被擦除。如果从捐赠者的二进制日志进行状态传输,则这些事务可能与组的事务发生冲突。

如果在 Group Replication 停止时在实例上执行管理事务,则可能会存在额外的事务。为了避免以这种方式引入新事务,请在发出管理语句之前始终将 sql_log_bin 系统变量的值设置为 OFF,然后在之后设置回 ON

代码语言:javascript
复制
SET SQL_LOG_BIN=0;
<administrator action>
SET SQL_LOG_BIN=1;

将此系统变量设置为 OFF 意味着从那一点开始发生的事务不会写入二进制日志,并且不会分配 GTID。

如果加入成员存在额外的事务,请检查受影响服务器的二进制日志,查看额外事务的实际内容。将加入成员的数据和 GTID 集与当前组中的成员进行协调的最安全方法是使用 MySQL 的克隆功能,将内容从组中的一个服务器传输到受影响的服务器。有关如何执行此操作的说明,请参见 Section 7.6.7.3, “克隆远程数据”。如果需要该事务,请在成员成功重新加入后重新运行它。

20.4.2 Group Replication Server States

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-server-states.html

Group Replication 群组成员的状态显示其在群组中的当前角色。Performance Schema 表replication_group_members显示了群组中每个成员的状态。如果群组完全正常运行且所有成员正常通信,则所有成员对所有其他成员报告相同的状态。但是,已离开群组或处于网络分区的成员无法准确报告其他服务器的信息。在这种情况下,该成员不会尝试猜测其他服务器的状态,而是将它们报告为不可访问。

一个群组成员可以处于以下状态:

ONLINE

服务器是群组的活跃成员,并处于完全运行状态。其他群组成员可以连接到它,客户端(如果适用)也可以连接到它。只有当成员处于ONLINE状态时,它才会与群组完全同步,并参与其中。

RECOVERING

服务器已加入一个群组,并正在成为活跃成员的过程中。当前正在进行分布式恢复,成员正在接收来自捐赠者的状态传输,使用远程克隆操作或捐赠者的二进制日志。此状态为

更多信息,请参见 Section 20.5.4, “Distributed Recovery”。

OFFLINE

Group Replication 插件已加载,但成员不属于任何群组。在成员加入或重新加入群组时,可能会暂时出现此状态。

ERROR

该成员处于错误状态,并且作为群组成员无法正常运行。成员可能在应用事务期间或恢复阶段进入错误状态。处于此状态的成员不参与群组的事务。有关错误状态可能原因的更多信息,请参见 Section 20.7.7, “Responses to Failure Detection and Network Partitioning”。

根据group_replication_exit_state_action设置的退出操作,成员处于只读模式(super_read_only=ON),也可能处于离线模式(offline_mode=ON)。请注意,遵循OFFLINE_MODE退出操作的离线模式服务器显示为ERROR状态,而不是OFFLINE。采用ABORT_SERVER退出操作的服务器将关闭并从组的视图中移除。更多信息,请参见 Section 20.7.7.4, “退出操作”。

当成员加入或重新加入复制组时,在组完成兼容性检查并接受其为成员之前,其状态可能显示为ERROR

UNREACHABLE

本地故障检测器怀疑无法联系到成员,因为组的消息超时。这可能发生在成员非自愿断开连接的情况下。如果您在其他服务器看到此状态,也可能意味着您查询此表的成员是分区的一部分,组的一部分服务器可以相互联系,但无法联系组中的其他服务器。更多信息,请参见 Section 20.7.8, “处理网络分区和失去法定人数”。

请参见 Section 20.4.3, “复制组成员表”,了解性能模式表内容的示例。

20.4.3 The replication_group_members Table

dev.mysql.com/doc/refman/8.0/en/group-replication-replication-group-members.html

performance_schema.replication_group_members表用于监视组成员的不同服务器实例的状态。表中的信息在视图更改时更新,例如当新成员加入时动态更改组配置时。在那时,服务器交换一些元数据以同步自己并继续共同合作。信息在所有作为复制组成员的服务器实例之间共享,因此可以从任何成员查询所有组成员的信息。该表可用于获取复制组状态的高级视图,例如通过发出:

代码语言:javascript
复制
SELECT * FROM performance_schema.replication_group_members;
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
| group_replication_applier | d391e9ee-2691-11ec-bf61-00059a3c7a00 | example1    |        4410 | ONLINE       | PRIMARY     | 8.0.27         | XCom                       |
| group_replication_applier | e059ce5c-2691-11ec-8632-00059a3c7a00 | example2    |        4420 | ONLINE       | SECONDARY   | 8.0.27         | XCom                       |
| group_replication_applier | ecd9ad06-2691-11ec-91c7-00059a3c7a00 | example3    |        4430 | ONLINE       | SECONDARY   | 8.0.27         | XCom                       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+-------------+----------------+----------------------------+
3 rows in set (0.0007 sec)

根据这个结果,我们可以看到该组由三个成员组成。表中显示了每个成员的server_uuid,以及成员的主机名和端口号,客户端用于连接的信息。MEMBER_STATE列显示了第 20.4.2 节,“组复制服务器状态”中的一个状态,在这种情况下显示该组的所有三个成员都是ONLINEMEMBER_ROLE列显示有两个从属节点和一个主节点。因此,该组必须在单主模式下运行。MEMBER_VERSION列在升级组并合并运行不同 MySQL 版本的成员时可能会有用。MEMBER_COMMUNICATION_STACK列显示了组使用的通信堆栈。

关于MEMBER_HOST值及其对分布式恢复过程的影响的更多信息,请参见第 20.2.1.3 节,“用于分布式恢复的用户凭据”。

20.4.4 The replication_group_member_stats Table

译文:dev.mysql.com/doc/refman/8.0/en/group-replication-replication-group-member-stats.html

每个复制组中的成员都会对组接收的事务进行认证和应用。关于认证者和应用者过程的统计信息对于了解应用程序队列的增长情况、发现了多少冲突、检查了多少事务、哪些事务在所有地方都已提交等方面非常有用。

performance_schema.replication_group_member_stats 表提供了与认证过程相关的组级信息,以及每个复制组成员接收和发起的事务的统计信息。这些信息在所有作为复制组成员的服务器实例之间共享,因此可以从任何成员查询所有组成员的信息。请注意,远程成员的统计信息刷新由group_replication_flow_control_period 选项中指定的消息周期控制,因此这些统计信息可能与在进行查询的成员本地收集的统计信息略有不同。要使用此表监视 Group Replication 成员,请执行以下语句:

代码语言:javascript
复制
mysql> SELECT * FROM performance_schema.replication_group_member_stats\G

从 MySQL 8.0.19 开始,您还可以使用以下语句:

代码语言:javascript
复制
mysql> TABLE performance_schema.replication_group_member_stats\G

这些列对于监视组中连接的成员的性能非常重要。假设组中的一个成员总是报告其队列中的事务数量比其他成员多。这意味着该成员延迟了,并且无法跟上组中其他成员的步伐。根据这些信息,您可以决定是将该成员从组中移除,还是延迟其他组成员的事务处理,以减少排队事务的数量。这些信息还可以帮助您决定如何调整 Group Replication 插件的流量控制,请参阅 Section 20.7.2, “Flow Control”。

20.5 群组复制操作

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-operations.html

20.5.1 配置在线群组

20.5.2 重新启动一个群组

20.5.3 事务一致性保证

20.5.4 分布式恢复

20.5.5 支持 IPv6 和混合 IPv6 和 IPv4 群组

20.5.6 使用 MySQL 企业备份与群组复制

本节解释了管理群组的常见操作。

20.5.1 配置在线组

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-configuring-online-group.html

20.5.1.1 更改主服务器

20.5.1.2 改变组模式

20.5.1.3 使用 Group Replication 组写一致性

20.5.1.4 设置组的通信协议版本

20.5.1.5 配置成员操作

您可以在 Group Replication 运行时使用一组函数配置在线组,这些函数依赖于组操作协调员。这些函数由 Group Replication 插件在 8.0.13 及更高版本中安装。本节描述了如何对运行中的组进行更改以及可用的功能。

重要提示

协调员要能够在运行中的组上配置组范围的操作,所有成员必须运行 MySQL 8.0.13 或更高版本,并安装了这些功能。

要使用这些功能,请连接到运行中的组的成员,并使用SELECT语句调用该函数。 Group Replication 插件处理操作及其参数,协调员将其发送给所有对调用函数的成员可见的成员。如果操作被接受,所有成员执行该操作并在完成后发送终止消息。一旦所有成员声明操作已完成,调用成员将结果返回给客户端。

在配置整个组时,操作的分布性意味着它们与 Group Replication 插件的许多进程进行交互,因此您应该遵守以下规定:

您可以在任何地方发出配置操作。 如果要将成员 A 设置为新的主服务器,则无需在成员 A 上调用操作。所有操作都以协调的方式发送并在所有组成员上执行。此外,操作的分布式执行具有不同的影响:如果发出操作的成员死亡,则任何已经运行的配置过程将继续在其他成员上运行。在发出操作的成员死亡的极少情况下,您仍然可以使用监控功能确保其他成员成功完成操作。

所有成员必须在线。 为了简化迁移或选举过程并确保它们尽可能快速,组不得包含当前处于分布式恢复过程中的任何成员,否则配置操作将被发出语句的成员拒绝。

在配置更改期间,没有成员可以加入组。 任何尝试在协调的配置更改期间加入组的成员都会离开组并取消其加入过程。

一次只能进行一个配置更改。 正在执行配置更改的组不能接受任何其他组的配置更改,因为并发的配置操作可能导致成员分歧。

所有成员必须运行 MySQL 8.0.13 或更高版本。 由于配置操作的分布式特性,所有成员必须识别它们才能执行它们。如果任何运行 MySQL Server 版本低于 8.0.12 的服务器存在于组中,则操作将被拒绝。

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-change-primary.html

20.5.1.1 更改主节点

本节解释了如何更改单一主节点组中的主节点,使用group_replication_set_as_primary()函数,该函数可以在组的任何成员上运行。执行此操作后,当前主节点将成为只读辅助节点,指定的组成员将成为读写主节点;这取代了第 20.1.3.1 节,“单一主节点模式”中描述的通常的主节点选举过程。

如果标准的源到副本复制通道正在现有的主节点上运行,除了组复制通道之外,您必须在更改主节点之前停止该复制通道。您可以使用性能模式表replication_group_members中的MEMBER_ROLE列,或者group_replication_primary_member状态变量来识别当前的主节点。

如果所有成员未运行相同的 MySQL 服务器版本,则只能指定运行组中最低 MySQL 服务器版本的新主节点。此保护措施旨在确保组与新功能保持兼容。这适用于所有 MySQL 版本,并从 MySQL 8.0.17 开始强制执行。

组正在等待的任何未提交事务必须在操作完成之前提交、回滚或终止。在 MySQL 8.0.29 之前,该函数会等待现有主节点上的所有活动事务结束,包括在使用该函数后启动的传入事务。从 MySQL 8.0.29 开始,您可以为在使用该函数时正在运行的事务指定从 0 秒(立即)到 3600 秒(60 分钟)的超时时间。为使超时生效,组的所有成员必须运行 MySQL 8.0.29 或更高版本。超时没有默认设置,因此如果您不设置它,等待时间没有上限,新事务可以在此期间启动。

当超时到期时,对于尚未达到提交阶段的任何事务,客户端会被断开连接,以防事务继续进行。已达到提交阶段的事务将被允许完成。设置超时还会阻止从那时起在主服务器上启动新事务。即使它们不修改任何数据,显式定义的事务(使用START TRANSACTIONBEGIN语句)也会受到超时、断开连接和传入事务阻止的影响。为了允许在函数运行时检查主服务器,允许执行不修改数据的单个语句,如一致性规则下允许的查询中列出的语句。

通过发出以下语句,传递成员的server_uuid,该成员将成为组的新主要成员:

代码语言:javascript
复制
SELECT group_replication_set_as_primary(*member_uuid*);

在 MySQL 8.0.29 及更高版本中,您可以添加一个超时,如下所示:

代码语言:javascript
复制
SELECT group_replication_set_as_primary(‘00371d66-3c45-11ea-804b-080027337932’, 300)

要检查超时的状态,请使用性能模式threads表中的PROCESSLIST_INFO列,如下所示:

代码语言:javascript
复制
mysql> SELECT NAME, PROCESSLIST_INFO FROM performance_schema.threads 
 -> WHERE NAME="thread/group_rpl/THD_transaction_monitor"\G
*************************** 1\. row ***************************
            NAME: thread/group_rpl/THD_transaction_monitor
PROCESSLIST_INFO: Group replication transaction monitor: Stopped client connections

状态显示了事务监控线程何时被创建,新事务何时被停止,带有未提交事务的客户端连接何时被断开,最后,进程何时完成并允许新事务再次进行。

在操作运行时,您可以通过发出以下语句来检查其进度:

代码语言:javascript
复制
mysql> SELECT event_name, work_completed, work_estimated 
 -> FROM performance_schema.events_stages_current 
 -> WHERE event_name LIKE "%stage/group_rpl%"\G
*************************** 1\. row ***************************
    EVENT_NAME: stage/group_rpl/Primary Election: Waiting for members to turn on super_read_only
WORK_COMPLETED: 3
WORK_ESTIMATED: 5

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-changing-group-mode.html

20.5.1.2 更改组模式

本节解释了如何更改组运行的模式,即单主或多主。用于更改组模式的函数可以在任何成员上运行。

切换到单主模式

使用group_replication_switch_to_single_primary_mode()函数通过执行以下命令将运行在多主模式下的组切换到单主模式:

代码语言:javascript
复制
SELECT group_replication_switch_to_single_primary_mode()

当您切换到单主模式时,所有组成员上也会禁用严格的一致性检查,这是单主模式所要求的(group_replication_enforce_update_everywhere_checks=OFF)。

如果没有传入字符串,在结果为单主组的新主要选举中,遵循 20.1.3.1 节,“单主模式”中描述的选举策略。要覆盖选举过程并在过程中配置多主组的特定成员作为新主要成员,请获取成员的server_uuid并将其传递给group_replication_switch_to_single_primary_mode()。例如,执行以下命令:

代码语言:javascript
复制
SELECT group_replication_switch_to_single_primary_mode(*member_uuid*);

如果在运行 MySQL Server 版本为 8.0.17 的成员上调用该函数,并且所有成员都运行 MySQL Server 版本为 8.0.17 或更高版本,则只能指定运行最低 MySQL Server 版本的新主要成员,基于补丁版本。这个保障是为了确保组保持与新功能的兼容性。如果不指定新的主要成员,选举过程将考虑组成员的补丁版本。

如果任何成员运行的 MySQL Server 版本介于 MySQL 8.0.13 和 MySQL 8.0.16 之间,则不会强制执行此保障,并且您可以指定任何新的主要成员,但建议选择运行组中最低 MySQL Server 版本的主要成员。如果不指定新的主要成员,选举过程仅考虑组成员的主要版本。

在操作运行时,您可以通过执行以下命令来检查其进度:

代码语言:javascript
复制
SELECT event_name, work_completed, work_estimated FROM performance_schema.events_stages_current WHERE event_name LIKE "%stage/group_rpl%";
+----------------------------------------------------------------------------+----------------+----------------+
| event_name                                                                 | work_completed | work_estimated |
+----------------------------------------------------------------------------+----------------+----------------+
| stage/group_rpl/Primary Switch: waiting for pending transactions to finish |              4 |             20 |
+----------------------------------------------------------------------------+----------------+----------------+
切换到多主模式

使用group_replication_switch_to_multi_primary_mode()函数通过执行以下命令将运行在单主模式下的组切换到多主模式:

代码语言:javascript
复制
SELECT group_replication_switch_to_multi_primary_mode()

在执行一些协调的组操作以确保数据的安全性和一致性之后,所有属于该组的成员都变为主节点。

当您将在单主模式下运行的组更改为多主模式时,运行 MySQL 8.0.17 或更高版本的成员如果运行的 MySQL 服务器版本高于组中存在的最低版本,则会自动处于只读模式。运行 MySQL 8.0.16 或更低版本的成员不执行此检查,并始终处于读写模式。

当操作运行时,您可以通过发出以下命令来检查其进度:

代码语言:javascript
复制
SELECT event_name, work_completed, work_estimated FROM performance_schema.events_stages_current WHERE event_name LIKE "%stage/group_rpl%";
+----------------------------------------------------------------------+----------------+----------------+
| event_name                                                           | work_completed | work_estimated |
+----------------------------------------------------------------------+----------------+----------------+
| stage/group_rpl/Multi-primary Switch: applying buffered transactions |              0 |              1 |
+----------------------------------------------------------------------+----------------+----------------+

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-group-write-consensus.html

20.5.1.3 使用 Group Replication 群组写共识

本节介绍如何检查和配置群组在任何时候的最大共识实例数。这个最大值被称为群组的事件视界,是群组可以并行执行的最大共识实例数。这使您能够微调您的 Group Replication 部署的性能。例如,默认值为 10 适用于在局域网上运行的群组,但对于在较慢的网络(如广域网)上运行的群组,增加此数字以提高性能。

检查群组的写并发性

使用group_replication_get_write_concurrency()函数,在运行时检查群组的事件视界值,通过发出:

代码语言:javascript
复制
SELECT group_replication_get_write_concurrency();
配置群组的写并发性

使用group_replication_set_write_concurrency()函数,设置系统可以并行执行的最大共识实例数,通过发出:

代码语言:javascript
复制
SELECT group_replication_set_write_concurrency(*instances*);

其中*instances*是新的最大共识实例数。需要GROUP_REPLICATION_ADMIN权限才能使用此功能。

dev.mysql.com/doc/refman/8.0/en/group-replication-communication-protocol.html

20.5.1.4 设置组的通信协议版本

从 MySQL 8.0.16 开始,Group Replication 具有组的通信协议的概念。Group Replication 通信协议版本可以被明确管理,并设置为适应您希望组支持的最旧 MySQL Server 版本。这使得可以从不同 MySQL Server 版本的成员组成组,同时确保向后兼容性。

  • MySQL 5.7.14 版本允许消息的压缩(参见 Section 20.7.4, “Message Compression”)。
  • MySQL 8.0.16 版本还允许消息的分段(参见 Section 20.7.5, “Message Fragmentation”)。
  • MySQL 8.0.27 版本还允许在单主模式下,当group_replication_paxos_single_leader设置为 true 时,组通信引擎可以与单一一致性领导者一起运行(参见 Section 20.7.3, “Single Consensus Leader”)。

所有组成员必须使用相同的通信协议版本,以便组成员可以处于不同的 MySQL Server 版本,但只发送所有组成员都能理解的消息。

MySQL 服务器在版本 X 下,只有当复制组的通信协议版本小于或等于 X 时,才能加入并达到ONLINE状态。当新成员加入复制组时,它会检查现有成员所宣布的通信协议版本。如果加入成员支持该版本,则加入该组并使用组宣布的通信协议,即使该成员支持额外的通信能力。如果加入成员不支持通信协议版本,则会被从组中驱逐。

如果两个成员尝试在同一成员变更事件中加入,只有当两个成员的通信协议版本已经与组的通信协议版本兼容时,它们才能加入。与组不同通信协议版本的成员必须独立加入。例如:

  • 一个 MySQL Server 8.0.16 实例可以成功加入使用通信协议版本 5.7.24 的组。
  • 一个 MySQL Server 5.7.24 实例无法成功加入使用通信协议版本 8.0.16 的组。
  • 两个 MySQL Server 8.0.16 实例不能同时加入使用通信协议版本 5.7.24 的组。
  • 两个 MySQL Server 8.0.16 实例可以同时加入使用通信协议版本 8.0.16 的组。

您可以使用group_replication_get_communication_protocol()函数检查组正在使用的通信协议,该函数返回组支持的最旧 MySQL Server 版本。组的所有现有成员返回相同的通信协议版本。例如:

代码语言:javascript
复制
SELECT group_replication_get_communication_protocol();
+------------------------------------------------+
| group_replication_get_communication_protocol() |
+------------------------------------------------+
| 8.0.16                                         |
+------------------------------------------------+

请注意,group_replication_get_communication_protocol()函数返回组支持的最低 MySQL 版本,这可能与传递给group_replication_set_communication_protocol()函数的版本号不同,并且可能与您在使用该函数的成员上安装的 MySQL Server 版本不同。

如果您需要更改组的通信协议版本,以便早期版本的成员可以加入,请使用group_replication_set_communication_protocol()函数指定您希望允许的最旧成员的 MySQL Server 版本。如果可能的话,这将使组回退到兼容的通信协议版本。使用此函数需要GROUP_REPLICATION_ADMIN权限,并且在发出语句时,所有现有组成员必须在线,没有多数成员丢失。例如:

代码语言:javascript
复制
SELECT group_replication_set_communication_protocol("5.7.25");

如果您将复制组的所有成员升级到新的 MySQL Server 版本,则组的通信协议版本不会自动升级以匹配。如果您不再需要支持早期版本的成员,您可以使用group_replication_set_communication_protocol()函数将通信协议版本设置为您已经升级成员的新 MySQL Server 版本。例如:

代码语言:javascript
复制
SELECT group_replication_set_communication_protocol("8.0.16");

group_replication_set_communication_protocol() 函数被实现为一个组操作,因此在组的所有成员上同时执行。组操作开始缓冲消息,并等待任何正在进行中的传出消息的传递完成,然后更改通信协议版本并发送缓冲消息。如果在更改通信协议版本后的任何时间点,有成员尝试加入组,组成员会宣布新的协议版本。

MySQL InnoDB 集群在使用 AdminAPI 操作更改集群拓扑结构时,自动透明地管理其成员的通信协议版本。InnoDB 集群始终使用当前所有实例支持的最新通信协议版本,这些实例当前是集群的一部分或正在加入其中。有关详细信息,请参阅 InnoDB 集群和组复制协议。

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-member-actions.html

20.5.1.5 配置成员操作

从 MySQL 8.0.26 开始,Group Replication 具有设置组成员在指定情况下采取的操作的能力。可以使用函数单独启用和禁用成员操作。服务器的成员操作配置在离开组后也可以重置为默认值。

管理员(具有GROUP_REPLICATION_ADMIN权限)可以使用group_replication_enable_member_actiongroup_replication_disable_member_action函数在组的主服务器上配置成员操作。然后,成员操作配置(包括所有成员操作以及它们是否启用或禁用)通过 Group Replication 的组消息传播到其他组成员和加入成员。因此,所有组成员都具有相同的成员操作配置。您还可以在不属于任何组的服务器上配置成员操作,只要安装了 Group Replication 插件。在这种情况下,成员操作配置不会传播到任何其他服务器。

如果在使用函数配置成员操作的服务器是组的一部分,则它必须是单主模式下的当前主服务器,并且必须是大多数的一部分。配置更改在 Group Replication 内部被跟踪,但不会被赋予 GTID,并且不会被写入二进制日志,因此不会传播到任何组外的服务器,如下游复制。每次启用或禁用成员操作时,Group Replication 都会增加其成员操作配置的版本号。

成员操作配置传播给成员的方式如下:

  • 在启动组时,引导组的服务器的成员操作配置成为组的配置。
  • 如果组的最低 MySQL Server 版本支持成员操作,则加入成员在加入时进行状态交换过程中接收组的成员操作配置。在这种情况下,加入成员将自己的成员操作配置替换为组的配置。
  • 如果支持成员操作的加入成员加入一个最低 MySQL Server 版本不支持成员操作的组,则加入时不会接收成员操作配置。在这种情况下,加入成员将自己的配置重置为默认值。

不支持成员操作的成员无法加入具有成员操作配置的组,因为其 MySQL Server 版本低于现有组成员运行的最低版本。

Performance Schema 表replication_group_member_actions列出了配置中可用的成员操作、触发它们的事件以及它们当前是否启用。成员操作的优先级从 1 到 100,较低的值首先执行。如果在执行成员操作时发生错误,则可以记录成员操作的失败,但否则忽略。如果认为成员操作的失败是关键的,则可以根据group_replication_exit_state_action系统变量指定的策略进行处理。

可以使用 Performance Schema 表replication_group_configuration_version查看的mysql.replication_group_configuration_version表记录了成员操作配置的当前版本。每当使用函数启用或禁用成员操作时,版本号都会递增。

group_replication_reset_member_actions函数只能在不属于任何组的服务器上使用。它将成员操作配置重置为默认设置,并将其版本号重置为 1。服务器必须可写(使用read_only系统变量设置为OFF),并安装了 Group Replication 插件。您可以使用此函数删除服务器在成为组的一部分时使用的成员操作配置,如果您打算将其用作没有成员操作或具有不同成员操作的独立服务器。

成员操作:mysql_disable_super_read_only_if_primary

成员操作mysql_disable_super_read_only_if_primary可以配置为使单主模式下的组在选举新主时保持在超级只读模式,以便该组仅接受复制事务,不接受来自客户端的直接写入。这种设置意味着当一个组的目的是为另一个组提供灾难容忍的次要备份时,您可以确保次要组与第一个组保持同步。

默认情况下,当选为主服务器时,超级只读模式在主服务器上被禁用,以便主服务器变为读写,并接受来自复制源服务器和客户端的更新。这是当成员操作mysql_disable_super_read_only_if_primary被启用时的情况,这是其默认设置。如果您使用group_replication_disable_member_action函数将操作设置为禁用,主服务器在选举后仍然保持在超级只读模式。在这种状态下,它不接受来自任何客户端的更新,甚至是具有CONNECTION_ADMINSUPER权限的用户。它仍然会接受由复制线程执行的更新。

20.5.2 重新启动组

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-restarting-group.html

Group Replication 旨在确保数据库服务持续可用,即使组成该组的某些服务器由于计划维护或意外问题而无法参与其中。只要剩余成员占据组的大多数,他们就可以选举新的主服务器并继续作为一个组运行。然而,如果复制组的每个成员都离开组,并且每个成员都通过STOP GROUP_REPLICATION语句或系统关闭停止了 Group Replication,那么该组现在只存在于理论上,作为成员上的一个配置。在这种情况下,要重新创建该组,必须像第一次启动一样通过引导启动。

首次引导组与第二次或后续引导组之间的区别在于,后者情况下,关闭的组的成员可能具有不同的事务集,取决于它们停止或失败的顺序。如果成员具有其他组成员上不存在的事务,则无法加入组。对于 Group Replication,这包括已提交和应用的事务,这些事务在gtid_executed GTID 集中,以及已经认证但尚未应用的事务,这些事务在group_replication_applier通道中。事务何时提交取决于为组设置的事务一致性级别(参见第 20.5.3 节,“事务一致性保证”)。然而,Group Replication 组成员永远不会删除已经认证的事务,这是成员承诺提交事务的声明。

因此,必须从最新的成员开始重新启动复制组,即执行最多事务并获得认证的成员。然后,事务较少的成员可以通过分布式恢复加入并赶上他们缺少的事务。不能假设组的最后已知主成员是组中最新的成员,因为比主成员关闭时间更晚的成员可能有更多的事务。因此,必须重新启动每个成员以检查事务,比较所有事务集,并确定最新的成员。然后可以使用该成员来引导组。

在每个成员关闭后,按照以下步骤安全地重新启动复制组。

依次对每个组成员执行以下步骤,顺序不限:

连接客户端到组成员。如果 Group Replication 尚未停止,请执行 STOP GROUP_REPLICATION 语句并等待 Group Replication 停止。

编辑 MySQL 服务器配置文件(通常在 Linux 和 Unix 系统上命名为 my.cnf,在 Windows 系统上命名为 my.ini),并设置系统变量 group_replication_start_on_boot=OFF。此设置防止 MySQL 服务器启动时启动 Group Replication,这是默认设置。

如果无法在系统上更改该设置,则可以允许服务器尝试启动 Group Replication,这将失败,因为组已完全关闭且尚未引导。如果采用这种方法,请勿在此阶段在任何服务器上设置 group_replication_bootstrap_group=ON

启动 MySQL 服务器实例,并验证 Group Replication 尚未启动(或启动失败)。此阶段不要启动 Group Replication。

从组成员收集以下信息:

gtid_executed GTID 集的内容。您可以通过执行以下语句获取:

代码语言:javascript
复制
mysql> SELECT @@GLOBAL.GTID_EXECUTED

group_replication_applier 通道上的已认证事务集。您可以通过执行以下语句获取:

代码语言:javascript
复制
mysql> SELECT received_transaction_set FROM \
        performance_schema.replication_connection_status WHERE \
        channel_name="group_replication_applier";

当您从所有组成员收集了事务集后,比较它们以找出哪个成员具有最大的事务集,包括已执行的事务(gtid_executed)和已认证的事务(在 group_replication_applier 通道上)。您可以通过查看 GTID 手动执行此操作,或者使用存储函数比较 GTID 集,如 Section 19.1.3.8, “Stored Function Examples to Manipulate GTIDs” 中所述。

使用具有最大事务集的成员引导组,通过连接客户端到组成员并执行以下语句:

代码语言:javascript
复制
mysql> SET GLOBAL group_replication_bootstrap_group=ON;
mysql> START GROUP_REPLICATION;
mysql> SET GLOBAL group_replication_bootstrap_group=OFF;

非常重要的是不要将设置 group_replication_bootstrap_group=ON 存储在配置文件中,否则当服务器再次重启时���将设置一个具有相同名称的第二个组。

要验证该组现在存在并包含此创始成员,请在引导它的成员上执行此语句:

代码语言:javascript
复制
mysql> SELECT * FROM performance_schema.replication_group_members;

通过在每个成员上执行 START GROUP_REPLICATION 语句,以任意顺序将其他每个成员重新添加到组中:

代码语言:javascript
复制
mysql> START GROUP_REPLICATION;

要验证每个成员是否已加入组,请在任何成员上执行此语句:

代码语言:javascript
复制
mysql> SELECT * FROM performance_schema.replication_group_members;

当成员重新加入组后,如果您编辑了他们的配置文件以设置group_replication_start_on_boot=OFF,您可以再次编辑它们以设置ON(或者移除该系统变量,因为ON是默认值)。

20.5.3 事务一致性保证

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-consistency-guarantees.html

20.5.3.1 理解事务一致性保证

20.5.3.2 配置事务一致性保证

分布式系统(如 Group Replication)的一个重要影响是作为一个群体提供的一致性保证。换句话说,是分布在群体成员之间的事务全局同步的一致性。本节描述了 Group Replication 如何处理依赖于群体中发生的事件的一致性保证,以及如何最佳配置您的群体的一致性保证。

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-understanding-consistency-guarantees.html

20.5.3.1 理解事务一致性保证

就分布式一致性保证而言,无论是在正常操作还是故障修复操作中,Group Replication 一直是一个最终一致性系统。这意味着一旦传入流量减慢或停止,所有组成员都具有相同的数据内容。与系统一致性相关的事件可以分为控制操作,无论是手动操作还是由故障自动触发;和数据流操作。

对于 Group Replication,可以根据一致性评估的控制操作包括:

  • 成员加入或离开,这在 Group Replication 的 Section 20.5.4, “分布式恢复” 和写保护中有所涵盖。
  • 网络故障,这由围栏模式涵盖。
  • 在单主组中,主故障切换,也可以是由 group_replication_set_as_primary() 触发的操作。
一致性保证和主故障切换

在单主组中,在次级节点被提升为主节点的主故障切换事件中,新的主节点可以立即对应用流量开放,无论复制积压数据有多大,或者可以限制访问直到积压数据被应用。

第一种方法是,在主故障后,组尽可能快地确保稳定的组成员资格,通过选举新的主节点,然后立即允许数据访问,同时仍在应用旧主节点的任何可能的积压数据。确保了写一致性,但在新的主节点应用积压数据时,读取可能暂时检索到陈旧数据。例如,如果客户端 C1 在旧主节点故障前刚写入 A=2 WHERE A=1,当客户端 C1 重新连接到新的主节点时,它可能读取到 A=1,直到新的主节点应用其积压数据并赶上旧主节点离开组的状态。

第二种选择是,在主故障后,系统确保稳定的组成员资格,并像第一种选择一样选举新的主节点,但在这种情况下,组等待新的主节点应用所有积压数据,然后才允许数据访问。这确保了在先前描述的情况下,当客户端 C1 重新连接到新的主节点时,它读取 A=2。然而,这样做的代价是,故障切换所需的时间与积压数据的大小成正比,在正确配置的组上应该很小。

在 MySQL 8.0.14 之前,没有办法配置故障切换策略,默认情况下可用性最大化,如第一种方法所述。在运行 MySQL 8.0.14 及更高版本的成员组中,您可以使用group_replication_consistency变量配置主故障切换期间成员提供的事务一致性保证级别。请参阅一致性对主选举的影响。

数据流操作

数据流与组一致性保证相关,因为读取和写入操作在组中执行,特别是当这些操作分布在所有成员之间时。数据流操作适用于组复制的两种模式:单主和多主,但为了更清晰地解释,本文仅限于单主模式。将传入的读取或写入事务分割到单主组成员的常规方式是将写入路由到主节点,并将读取均匀分布到从节点。由于组应该表现为单个实体,因此可以合理地期望主节点上的写入立即在从节点上可用。虽然组复制是使用实现 Paxos 算法的组通信系统(GCS)协议编写的,但组复制的某些部分是异步的,这意味着数据会异步应用到从节点。这意味着客户端 C2 可以在主节点上写入B=2 WHERE B=1,立即连接到从节点并读取B=1。这是因为从节点仍在应用积压数据,并且尚未应用主节点应用的事务。

事务同步点

您可以根据希望在组中同步事务的时间点配置组的一致性保证。为了帮助您理解概念,本节将简化跨组同步事务的时间点为读取操作时或写入操作时。如果在读取时同步数据,则当前客户端会等待直到给定时间点,即所有先前的更新事务都已应用,然后才能开始执行。使用这种方法,只有此会话受到影响,所有其他并发数据操作不受影响。

如果在写入时同步数据,则写入会话会等待直到所有从节点写入其数据。组复制使用写入的总顺序,因此这意味着等待这个和所有在从节点队列中的先前写入被应用。因此,当使用此同步点时,写入会话等待所有从节点队列被应用。

任何替代方案都确保在描述的客户端 C2 的情况下,即使立即连接到辅助服务器,也始终读取B=2。每种替代方案都有其优点和缺点,这些直接与你的系统工作负载相关。以下示例描述了不同类型的工作负载,并建议哪种同步点是适当的。

想象以下情况:

  • 你希望负载均衡你的读取操作,而不需要在从哪个服务器读取时部署额外的限制,以避免读取过时数据,组写入比组读取要少得多。
  • 如果你有一个主要是只读数据的组,你希望读写事务在提交后到处都被应用,这样后续的读取都是在包含最新写入的最新数据上进行的。这确保你不必为每个只读事务支付同步成本,而只需为读写事务支付。

在这些情况下,你应该选择在写入时进行同步。

想象以下情况:

  • 你希望负载均衡你的读取操作,而不需要在从哪个服务器读取时部署额外的限制,以避免读取过时数据,组写入比组读取要常见得多。
  • 你希望你的工作负载中的特定事务始终从组中读取最新数据,例如每当敏感数据更新时(例如文件的凭据或类似数据),你希望强制读取检索到最新值。

在这些情况下,你应该选择在读取时进行同步。

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-configuring-consistency-guarantees.html

20.5.3.2 配置事务一致性保证

尽管 事务同步点 部分解释了概念上有两个可以选择的同步点:读取或写入时,但这些术语是一种简化,Group Replication 中使用的术语是:事务执行前事务执行后。一致性级别对由组处理的只读(RO)和读写(RW)事务可能产生不同的影响,正如本节所示。

  • 如何选择一致性级别
  • 一致性级别的影响
  • 一致性对主选举的影响
  • 一致性规则下允许的查询

以下列表显示了在 Group Replication 中可以使用 group_replication_consistency 变量配置的可能一致性级别,按照事务一致性保证递增的顺序排列:

  • EVENTUAL 无论是 RO 还是 RW 事务在执行时都不会等待前置事务被应用。这是在添加 group_replication_consistency 变量之前 Group Replication 的行为。一个 RW 事务不会等待其他成员应用事务。这意味着一个事务在其他成员之前可能在一个成员上被外部化。这也意味着在主故障转移的情况下,新的主节点可以在之前的主节点的所有事务都被应用之前接受新的 RO 和 RW 事务。RO 事务可能导致过时的值,RW 事务可能由于冲突而导致回滚。
  • BEFORE_ON_PRIMARY_FAILOVER 具有新选举的主要成员并正在应用旧主要成员的积压的新 RO 或 RW 事务被保留(未应用),直到任何积压被应用。这确保了主要故障转移发生时,无论是故意还是不经意,客户端始终看到主要成员上的最新值。这保证了一致性,但意味着客户端必须能够处理正在应用积压时的延迟。通常,此延迟应该很小,但这取决于积压的大小。
  • BEFORE RW 事务等待所有先前事务完成后再应用。RO 事务等待所有先前事务完成后再执行。这确保了此事务通过仅影响事务的延迟来读取最新值。通过仅在 RO 事务上使用同步,可以减少每个 RW 事务上的同步开销。此一致性级别还包括BEFORE_ON_PRIMARY_FAILOVER提供的一致性保证。
  • AFTER RW 事务等待直到其更改已应用于所有其他成员。此值对 RO 事务没有影响。此模式确保当本地成员上提交事务时,任何后续事务都会读取已写入的值或任何组成员上更近的值。在主要用于 RO 操作的组中使用此模式,以确保一旦提交,已应用的 RW 事务就会被应用到所有地方。您的应用程序可以使用此模式来确保后续读取获取包括最新写入的最新数据。通过仅在 RW 事务上使用同步,可以减少每个 RO 事务上的同步开销。此一致性级别还包括BEFORE_ON_PRIMARY_FAILOVER提供的一致性保证。
  • BEFORE_AND_AFTER RW 事务等待 1) 所有先前事务完成后再应用和 2) 直到其更改已应用于其他成员。RO 事务等待所有先前事务完成后再执行。此一致性级别还包括BEFORE_ON_PRIMARY_FAILOVER提供的一致性保证。

BEFOREBEFORE_AND_AFTER 一致性级别都可以用于 RO 和 RW 事务。AFTER 一致性级别对 RO 事务没有影响,因为它们不生成更改。

如何选择一致性级别

不同的一致性级别为 DBA 和开发人员提供了灵活性,他们可以使用这些级别来设置基础设施;开发人员可以根据其应用程序的要求选择最适合的一致性级别。以下场景展示了如何根据您使用组的方式选择一致性保证级别:

  • 场景 1 您希望负载均衡读取而不必担心过时读取,您的组写入操作明显少于组读取操作。在这种情况下,您应选择AFTER
  • 场景 2 你有一个应用了大量写入的数据集,并且希望偶尔进行读取而不必担心读取过时数据。在这种情况下,你应该选择BEFORE
  • 场景 3 你希望工作负载中的特定事务始终从组中读取最新数据,因此每当敏感数据更新(例如文件的凭据或类似数据)时,你希望强制读取始终读取最新值。在这种情况下,你应该选择BEFORE
  • 场景 4 你有一个主要包含只读(RO)数据的组,你希望你的读写(RW)事务一旦提交就在所有地方应用,以便后续读取是在包括最新写入的最新数据上进行的,而且你不需要在每个 RO 事务上进行同步,而只需在 RW 事务上进行。在这种情况下,你应该选择AFTER
  • 场景 5 你有一个主要包含只读数据的组,你希望你的读写(RW)事务始终从组中读取最新数据,并且一旦提交就在所有地方应用,以便后续读取是在包括最新写入的最新数据上进行的,而且你不需要在每个只读(RO)事务上进行同步,而只需在 RW 事务上进行。在这种情况下,你应该选择BEFORE_AND_AFTER

你有自由选择强制执行一致性级别的范围。这很重要,因为如果在全局范围设置一致性级别,可能会对组性能产生负面影响。因此,你可以通过在不同范围使用group_replication_consistency系统变量来配置组的一致性级别。

要在当前会话上强制执行一致性级别,请使用会话范围:

代码语言:javascript
复制
> SET @@SESSION.group_replication_consistency= 'BEFORE';

要在所有会话上强制执行一致性级别,请使用全局范围:

代码语言:javascript
复制
> SET @@GLOBAL.group_replication_consistency= 'BEFORE';

在特定会话上设置一致性级别的可能性使你能够利用以下场景:

  • 场景 6 给定系统处理几个不需要强一致性级别的指令,但一种指令确实需要强一致性:管理对文档的访问权限。在这种情况下,系统更改访问权限并希望确保所有客户端看到正确的权限。你只需要在这些指令上SET @@SESSION.group_replication_consistency= ‘AFTER’,并将其他指令保留在全局范围设置为EVENTUAL
  • 场景 7 在与场景 6 中描述的相同系统上,每天都需要执行一些分析处理的指令,并且因此需要始终读取最新数据。为了实现这一点,你只需要在该特定指令上SET @@SESSION.group_replication_consistency= ‘BEFORE’

总结一下,你不需要以特定的一致性级别运行所有事务,特别是如果只有一些事务实际上需要它。

请注意,在组复制中,所有读写事务都是完全有序的,因此,即使您将一致性级别设置为AFTER,对于当前会话,此事务也会等待直到其更改在所有成员上应用,这意味着等待此事务和所有可能在次要队列中的前置事务。实际上,一致性级别AFTER会等待一切,直到包括此事务在内。

一致性级别的影响

另一种分类一致性级别的方式是根据对组的影响来进行,即,一致性级别对其他成员的影响。

除了在事务流中排序外,一致性级别BEFORE仅影响本地成员。也就是说,它不需要与其他成员协调,也不会对其事务产生影响。换句话说,BEFORE仅影响使用它的事务。

一致性级别AFTERBEFORE_AND_AFTER对在其他成员上执行的并发事务确实会产生副作用。如果具有EVENTUAL一致性级别的事务在执行具有AFTERBEFORE_AND_AFTER的事务时开始,其他成员的事务将等待,直到AFTER事务在该成员上提交,即使其他成员的事务具有EVENTUAL一致性级别。换句话说,AFTERBEFORE_AND_AFTER影响所有ONLINE组成员。

为了进一步说明这一点,想象一个有 3 个成员 M1、M2 和 M3 的组。在成员 M1 上,一个客户端发出:

代码语言:javascript
复制
> SET @@SESSION.group_replication_consistency= AFTER;
> BEGIN;
> INSERT INTO t1 VALUES (1);
> COMMIT;

然后,在应用上述事务时,成员 M2 上的一个客户端发出:

代码语言:javascript
复制
> SET SESSION group_replication_consistency= EVENTUAL;

在这种情况下,即使第二个事务的一致性级别是EVENTUAL,因为它在第一个事务已经在 M2 上处于提交阶段时开始执行,第二个事务必须等待第一个事务完成提交,然后才能执行。

你只能在ONLINE成员上使用一致性级别BEFOREAFTERBEFORE_AND_AFTER,尝试在其他状态的成员上使用它们会导致会话错误。

一致性级别不是EVENTUAL的事务会等待直到达到由wait_timeout值配置的超时,其默认值为 8 小时。如果超时,将抛出ER_GR_HOLD_WAIT_TIMEOUT错误。

一致性对初选的影响

本节描述了一个群组的一致性级别如何影响已选出新主节点的单主群组。这样的群组会自动检测故障并调整活跃成员的视图,换句话说,成员配置。此外,如果一个群组以单主模式部署,每当群组成员发生变化时,都会执行检查以检测群组中是否仍有主成员。如果没有,则从次要成员列表中选择一个新的主成员。通常,这被称为次要晋升。

鉴于系统能够自动检测故障并自动重新配置自身,用户可能也期望一旦晋升发生,新的主节点在数据方面与旧主节点完全相同。换句话说,用户可能期望在他能够从新主节点读取和写入时,新主节点上没有待应用的复制事务。实际上,用户可能期望一旦他的应用故障切换到新主节点,甚至暂时也不会有机会读取旧数据或写入旧数据记录。

当在群组上激活并正确调整流量控制时,在晋升后立即从新选出的主节点暂时读取陈旧数据的机会很小,因为不应该有积压,或者如果有积压,那么应该很小。此外,您可能会有一个代理或中间件层,在晋升后管理应用程序对主节点的访问并在该级别强制执行一致性标准。如果您的群组成员使用的是 MySQL 8.0.14 或更高版本,您可以使用 group_replication_consistency 变量指定新主节点在晋升后的行为,该变量控制新选出的主节点是否阻止读取和写入,直到积压完全应用或者如果它的行为类似于运行 MySQL 8.0.13 或更早版本的成员。如果在有待应用的积压的新选出的主节点上设置了 group_replication_consistency 选项为 BEFORE_ON_PRIMARY_FAILOVER,并且在新主节点仍在应用积压时发出事务,则传入事务将被阻止,直到积压完全应用。因此,以下异常情况被防止:

对于只读和读写事务,不会出现陈旧的读取。这可以防止陈旧的读取通过新主节点外部化到应用程序中。

由于与仍在等待应用的积压中的复制读写事务发生写-写冲突,因此读写事务不会出现虚假回滚。

在读写事务中没有读取偏差,例如:

代码语言:javascript
复制
> BEGIN;
> SELECT x FROM t1; -- x=1 because x=2 is in the backlog;
> INSERT x INTO t2;
> COMMIT;

这个查询不应该引起冲突,但会写入过时的数值。

总结一下,当 group_replication_consistency 设置为 BEFORE_ON_PRIMARY_FAILOVER 时,您选择优先考虑一致性而不是可用性,因为每当选举新的主要成员时,读写操作都会被保留。这是在配置组时必须考虑的权衡。还应记住,如果流量控制正常工作,backlog 应该是最小的。请注意,更高的一致性级别 BEFOREAFTERBEFORE_AND_AFTER 也包括 BEFORE_ON_PRIMARY_FAILOVER 提供的一致性保证。

为了确保组提供相同的一致性级别,无论哪个成员被提升为主要成员,组的所有成员都应该将 BEFORE_ON_PRIMARY_FAILOVER(或更高的一致性级别)持久化到其配置中。例如,在每个成员上执行:

代码语言:javascript
复制
> SET PERSIST group_replication_consistency='BEFORE_ON_PRIMARY_FAILOVER';

这确保了所有成员都以相同的方式行事,并且配置在成员重新启动后仍然保留。

事务不能永远保持挂起状态,如果持续时间超过 wait_timeout,则会返回一个 ER_GR_HOLD_WAIT_TIMEOUT 错误。

在一致性规则下允许的查询

在使用 BEFORE_ON_PRIMARY_FAILOVER 一致性级别时,虽然所有写操作都被保留,但并非所有读操作都被阻塞,以确保您仍然可以在升级后的服务器应用 backlog 时进行检查。这对于调试、监控、可观察性和故障排除非常有用。一些不修改数据的查询是允许的,例如以下内容:

  • SHOW 语句 - 从 MySQL 8.0.27 开始,此处仅限于不依赖于数据,仅依赖于状态和配置的语句,如下所列
  • SET 语句
  • 不使用表或可加载函数的 DO 语句
  • EMPTY 语句
  • USE 语句
  • 使用针对 performance_schemasys 数据库的 SELECT 语句
  • 使用针对 infoschema 数据库中的 PROCESSLIST 表的 SELECT 语句
  • 不使用表或可加载函数的 SELECT 语句
  • STOP GROUP_REPLICATION 语句
  • SHUTDOWN 语句
  • RESET PERSIST 语句

允许在 MySQL 8.0.27 中使用的SHOW语句包括SHOW VARIABLES, SHOW PROCESSLIST, SHOW STATUS, SHOW ENGINE INNODB LOGS, SHOW ENGINE INNODB STATUS, SHOW ENGINE INNODB MUTEX, SHOW MASTER STATUS, SHOW REPLICA STATUS, SHOW CHARACTER SET, SHOW COLLATION, SHOW BINARY LOGS, SHOW OPEN TABLES, SHOW REPLICAS, SHOW BINLOG EVENTS, SHOW WARNINGS, SHOW ERRORS, SHOW ENGINES, SHOW PRIVILEGES, SHOW PROCEDURE STATUS, SHOW FUNCTION STATUS, SHOW PLUGINS, SHOW EVENTS, SHOW PROFILE, SHOW PROFILES,SHOW RELAYLOG EVENTS

20.5.4 分布式恢复

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-distributed-recovery.html

20.5.4.1 用于分布式恢复的连接

20.5.4.2 用于分布式恢复的克隆

20.5.4.3 配置分布式恢复

20.5.4.4 分布式恢复的容错性

20.5.4.5 分布式恢复的工作原理

每当成员加入或重新加入复制组时,它必须赶上在其加入之前或离开期间组成员应用的事务。这个过程称为分布式恢复。

加入成员首先通过检查其group_replication_applier通道的中继日志,查看组中已接收但尚未应用的任何事务。如果加入成员以前曾在组中,它可能会发现在离开之前未应用的事务,这种情况下会将其作为第一步应用。新加入组的成员没有任何需要应用的事务。

在此之后,加入成员连接到在线现有成员以进行状态传输。加入成员传输了在其加入组之前或离开期间发生的所有事务,这些事务由现有成员(称为捐赠者)提供。接下来,加入成员应用了在此状态传输过程中组中发生的事务。当此过程完成时,加入成员已经赶上了组中的其余服务器,并开始正常参与组中的活动。

组复制在分布式恢复期间使用这些方法的组合进行状态传输:

  • 使用克隆插件的功能进行远程克隆操作,该功能从 MySQL 8.0.17 起可用。要启用此状态传输方法,必须在组成员和加入成员上安装克隆插件。组复制自动配置所需的克隆插件设置,并管理远程克隆操作。
  • 从捐赠者的二进制日志复制并在加入成员上应用事务。此方法使用一个名为group_replication_recovery的标准异步复制通道,在捐赠者和加入成员之间建立。

在加入成员上发出START GROUP_REPLICATION后,组复制会自动选择这些方法的最佳组合进行状态转移。为此,组复制会检查哪些现有成员适合作为捐赠者,加入成员需要从捐赠者那里获取多少事务,以及是否在任何组成员的二进制日志文件中不再存在任何必需的事务。如果加入成员与适当的捐赠者之间的事务差距很大,或者某些必需的事务不在任何捐赠者的二进制日志文件中,组复制将开始进行远程克隆操作的分布式恢复。如果事务差距不大,或者未安装克隆插件,则组复制直接进行从捐赠者的二进制日志进行状态转移。

  • 在远程克隆操作期间,加入成员上的现有数据将被删除,并替换为捐赠者的数据副本。当远程克隆操作完成并加入成员重新启动时,将执行从捐赠者的二进制日志进行状态转移,以获取在远程克隆操作进行时组应用的事务。
  • 在从捐赠者的二进制日志进行状态转移期间,加入成员复制并应用所需的事务从捐赠者的二进制日志中,按照接收到的事务逐个应用,直到二进制日志记录加入成员加入组的点(视图更改事件)。在此过程中,加入成员缓冲组应用的新事务。当从二进制日志的状态转移完成时,加入成员应用缓冲事务。

当加入成员与组的所有事务保持最新时,它被声明为在线,并可以作为正常成员参与组,并且分布式恢复完成。

提示

从二进制日志进行状态转移是组复制的分布式恢复的基本机制,如果您的复制组中的捐赠者和加入成员未设置为支持克隆,则这是唯一可用的选项。由于从二进制日志进行状态转移是基于经典的异步复制,如果加入组的服务器根本没有组的数据,或者具有来自非常旧的备份镜像的数据,可能需要很长时间。因此,在将服务器添加到组之前,建议您通过传输一个相当新的服务器快照来设置具有组数据的服务器。这样可以最大程度地减少分布式恢复所需的时间,并减少对捐赠者服务器的影响,因为它们需要保留和传输更少的二进制日志文件。

译文:dev.mysql.com/doc/refman/8.0/en/group-replication-distributed-recovery-connections.html

20.5.4.1 分布式恢复的连接

当一个加入成员在分布式恢复期间连接到在线现有成员进行状态传输时,加入成员在连接上充当客户端,而现有成员充当服务器。当通过这个连接从捐赠者的二进制日志进行状态传输(使用异步复制通道group_replication_recovery)时,加入成员充当副本,而现有成员充当源。当远程克隆操作在这个连接上进行时,加入成员充当接收者,而现有成员充当捐赠者。适用于这些角色的配置设置在 Group Replication 上下文之外也适用于 Group Replication,除非它们被 Group Replication 特定的配置设置或行为所覆盖。

现有成员为分布式恢复向加入成员提供的连接并不是 Group Replication 用于组内在线成员之间通信的连接。

  • Group Replication 的组通信引擎(XCom,一种 Paxos 变体)用于远程 XCom 实例之间的 TCP 通信的连接由group_replication_local_address系统变量指定。这个连接用于在线成员之间的 TCP/IP 消息。与本地实例的通信通过使用共享内存的输入通道进行。
  • 对于分布式恢复,直到 MySQL 8.0.20,组成员向加入成员提供他们的标准 SQL 客户端连接,由 MySQL Server 的hostnameport系统变量指定。如果report_port系统变量指定了替代端口号,则使用该端口号。
  • 从 MySQL 8.0.21 开始,组成员可以向加入成员提供一组专用客户端连接作为分布式恢复端点的替代列表,允许您单独控制分布式恢复流量,而不是由成员的常规客户端用户连接。您可以使用group_replication_advertise_recovery_endpoints系统变量指定此列表,并在加入组时成员将其分布式恢复端点列表传输给组。默认情况下,成员继续像早期版本一样提供标准 SQL 客户端连接。

重要提示

如果加入成员无法使用由 MySQL Server 的hostname系统变量定义的主机名正确识别其他成员,则分布式恢复可能会失败。建议运行 MySQL 的操作系统具有经过正确配置的唯一主机名,可以使用 DNS 或本地设置。服务器用于 SQL 客户端连接的主机名可以在性能模式表replication_group_membersMember_host列中验证。如果多个组成员外部化由操作系统设置的默认主机名,那么加入成员可能无法将其解析为正确的成员地址并无法连接进行分布式恢复。在这种情况下,您可以使用 MySQL Server 的report_host系统变量为每个服务器配置一个唯一的主机名来外部化。

加入成员建立分布式恢复连接的步骤如下:

  1. 当成员加入组时,它使用其group_replication_group_seeds系统变量中包含的种子成员列表中的一个连接,最初使用该列表中指定的group_replication_local_address连接。种子成员可能是组的子集。
  2. 通过此连接,种子成员使用 Group Replication 的成员服务向加入成员提供了一个在线组中所有成员的列表,以视图的形式呈现。成员信息包括每个成员提供的用于分布式恢复的分布式恢复端点或标准 SQL 客户端连接的详细信息。
  3. 加入成员从此列表中选择一个适合的组成员作为其分布式恢复的捐赠者,遵循第 20.5.4.4 节“分布式恢复的容错”中描述的行为。
  4. 然后,加入成员尝试使用捐赠者广告的分布式恢复端点连接到捐赠者,依次尝试列表中指定的顺序。如果捐赠者没有提供端点,则加入成员尝试使用捐赠者的标准 SQL 客户端连接。连接的 SSL 要求如第 20.5.4.1.4 节“分布式恢复的 SSL 和身份验证”中描述的group_replication_recovery_ssl_*选项所指定。
  5. 如果加入成员无法连接到所选的提供者,它将尝试与其他适当的提供者重试,遵循 第 20.5.4.4 节,“分布式恢复的容错性” 中描述的行为。请注意,如果加入成员在不建立连接的情况下耗尽了广告端点列表,则不会回退到提供者的标准 SQL 客户端连接,而是切换到另一个提供者。
  6. 当加入成员与提供者建立分布式恢复连接时,它将使用该连接进行状态传输,如 第 20.5.4 节,“分布式恢复” 中所述。用于连接的主机和端口在加入成员的日志中显示。请注意,如果使用远程克隆操作,当加入成员在操作结束时重新启动时,它将与新的提供者建立连接,以从二进制日志进行状态传输。这可能是与用于远程克隆操作的原始提供者不同的成员的连接,或者可能是与原始提供者的不同连接。无论如何,分布式恢复过程都将像在原始提供者的情况下一样继续。
20.5.4.1.1 选择分布式恢复端点的地址

group_replication_advertise_recovery_endpoints 系统变量提供的 IP 地址作为分布式恢复端点不需要为 MySQL Server 配置(即,它们不需要由 admin_address 系统变量指定或在 bind_address 系统变量的列表中)。它们必须分配给服务器。使用的任何主机名必须解析为本地 IP 地址。可以使用 IPv4 和 IPv6 地址。

为了 MySQL Server 配置分布式恢复端点所提供的端口必须通过 portreport_portadmin_port 系统变量指定。服务器必须在这些端口上监听 TCP/IP 连接。如果指定了 admin_port,则分布式恢复的复制用户需要 SERVICE_CONNECTION_ADMIN 权限才能连接。选择 admin_port 可以将分布式恢复连接与常规 MySQL 客户端连接分开。

加入的成员依次尝试列表中指定的每个端点。如果group_replication_advertise_recovery_endpoints设置为DEFAULT而不是端点列表,则提供标准的 SQL 客户端连接。请注意,标准的 SQL 客户端连接不会自动包含在分布式恢复端点列表中,并且不会作为备用方案提供,如果捐赠者的端点列表在没有连接的情况下耗尽。如果您希望将标准的 SQL 客户端连接作为多个分布式恢复端点之一提供,您必须在由group_replication_advertise_recovery_endpoints指定的列表中显式包含它。您可以将其放在最后一位,以便作为连接的最后手段。

一个组成员的分布式恢复端点(或标准的 SQL 客户端连接,如果没有提供端点)不需要添加到由group_replication_ip_allowlist(从 MySQL 8.0.22 开始)或group_replication_ip_whitelist地址。加入的成员必须通过允许列表允许的初始连接到组,以便检索分布式恢复的地址或地址。

当设置系统变量并发出START GROUP_REPLICATION语句时,您列出的分布式恢复端点将得到验证。如果列表无法正确解析,或者如果主机上的任何端点无法访问,因为服务器没有在其上监听,Group Replication 将记录错误并且不会启动。

20.5.4.1.2 分布式恢复的压缩

从 MySQL 8.0.18 开始,您可以选择通过从捐赠者的二进制日志进行状态传输的方法为分布式恢复配置压缩。压缩可以使分布式恢复受益,特别是在网络带宽有限且捐赠者必须向加入成员传输许多事务时。group_replication_recovery_compression_algorithmsgroup_replication_recovery_zstd_compression_level系统变量配置允许的压缩算法,以及在从捐赠者的二进制日志进行状态传输时使用的zstd压缩级别。有关更多信息,请参见第 6.2.8 节,“连接压缩控制”。

请注意,这些压缩设置不适用于远程克隆操作。当远程克隆操作用于分布式恢复时,克隆插件的clone_enable_compression设置适用。

20.5.4.1.3 分布式恢复的复制用户

分布式恢复需要一个具有正确权限的复制用户,以便 Group Replication 可以建立直接成员间的复制通道。复制用户还必须具有正确权限,以在捐赠者上充当远程克隆操作的克隆用户。在每个组成员上进行分布式恢复时必须使用相同的复制用户。有关设置此复制用户的说明,请参见第 20.2.1.3 节,“分布式恢复的用户凭据”。有关保护复制用户凭据的说明,请参见第 20.6.3.1 节,“分布式恢复的安全用户凭据”。

20.5.4.1.4 分布式恢复的 SSL 和身份验证

分布式恢复的 SSL 配置与正常组通信的 SSL 配置是分开的,由服务器的 SSL 设置和group_replication_ssl_mode系统变量确定。对于分布式恢复连接,专用的 Group Replication 分布式恢复 SSL 系统变量可用于配置专门用于分布式恢复的证书和密码。

默认情况下,分布式恢复连接不使用 SSL。要激活它,请设置group_replication_recovery_use_ssl=ON,并按照 Section 20.6.3, “Securing Distributed Recovery Connections”中描述的方式配置 Group Replication 分布式恢复 SSL 系统变量。您需要设置一个用于 SSL 的复制用户。

当配置分布式恢复使用 SSL 时,Group Replication 会将此设置应用于远程克隆操作,以及从捐赠者的二进制日志进行状态传输。Group Replication 会自动配置克隆 SSL 选项(clone_ssl_caclone_ssl_cert,和clone_ssl_key)的设置,以匹配相应的 Group Replication 分布式恢复选项(group_replication_recovery_ssl_cagroup_replication_recovery_ssl_cert,和group_replication_recovery_ssl_key)的设置。

如果您没有为分布式恢复使用 SSL(因此group_replication_recovery_use_ssl设置为OFF),并且 Group Replication 的复制用户帐户使用caching_sha2_password插件(这是 MySQL 8.0 中的默认设置)或sha256_password插件进行身份验证,则会使用 RSA 密钥对进行密码交换。在这种情况下,要么使用group_replication_recovery_public_key_path系统变量指定 RSA 公钥文件,要么使用group_replication_recovery_get_public_key系统变量从源请求公钥,如 Section 20.6.3.1.1, “Replication User With The Caching SHA-2 Authentication Plugin”中所述。

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-cloning.html

20.5.4.2 分布式恢复的克隆

MySQL Server 的克隆插件从 MySQL 8.0.17 开始提供。如果要在组中使用远程克隆操作进行分布式恢复,必须事先设置现有成员和加入成员以支持此功能。如果不想在组中使用此功能,请不要设置,此时组复制仅使用来自二进制日志的状态传输。

要使用克隆,至少一个现有组成员和加入成员必须事先设置以支持远程克隆操作。最低要求是,在捐赠者和加入成员上安装克隆插件,为分布式恢复的复制用户授予BACKUP_ADMIN权限,并将group_replication_clone_threshold系统变量设置为适当的级别。为确保捐赠者的最大可用性,建议设置所有当前和未来的组成员以支持远程克隆操作。

请注意,远程克隆操作会在从捐赠者传输数据之前,从加入成员中删除用户创建的表空间和数据。如果操作在进行中停止,加入成员可能会留下部分数据或没有数据。这可以通过重新尝试远程克隆操作来修复,组复制会自动执行此操作。

20.5.4.2.1 克隆的先决条件

要设置和配置克隆插件的完整说明,请参阅第 7.6.7 节,“克隆插件”。有关远程克隆操作的详细先决条件,请参阅第 7.6.7.3 节,“克隆远程数据”。对于组复制,请注意以下关键点和差异:

捐赠者(现有组成员)和接收者(加入成员)必须安装并激活克隆插件。有关如何执行此操作的说明,请参阅第 7.6.7.1 节,“安装克隆插件”。

捐赠者和接收者必须运行在相同的操作系统上,并且必须具有相同的 MySQL Server 版本系列。因此,对于运行不同次要 MySQL Server 版本的组,如 MySQL 8.0 和 8.4,克隆不适用。

在 MySQL 8.0.37 之前,克隆要求捐赠者和接收者是相同的点版本,如果捐赠者或接收者是 MySQL 8.0.36 或更早版本,则仍然适用此限制。

捐赠者和接收者必须安装并激活组复制插件,捐赠者上激活的任何其他插件(如密钥环插件)也必须在接收者上激活。

如果分布式恢复配置为使用 SSL(group_replication_recovery_use_ssl=ON),组复制会将此设置应用于远程克隆操作。组复制会自动配置克隆 SSL 选项的设置(clone_ssl_caclone_ssl_certclone_ssl_key),以匹配您对应的组复制分布式恢复选项的设置(group_replication_recovery_ssl_cagroup_replication_recovery_ssl_certgroup_replication_recovery_ssl_key)。

在加入复制组的过程中,您无需在clone_valid_donor_list系统变量中设置有效捐赠者列表。组复制会在从现有组成员中选择捐赠者后自动为您配置此设置。请注意,远程克隆操作使用服务器的 SQL 协议主机名和端口。

克隆插件有许多系统变量来管理远程克隆操作的网络负载和性能影响。组复制不会配置这些设置,因此您可以查看并设置它们,或者允许它们使用默认设置。请注意,当远程克隆操作用于分布式恢复时,克隆插件的clone_enable_compression设置适用于操作,而不是组复制的压缩设置。

为了在接收端调用远程克隆操作,组复制使用内部的mysql.session用户,该用户已经具有CLONE_ADMIN权限,因此您无需设置此权限。

作为远程克隆操作的捐赠者上的克隆用户,Group Replication 使用您为分布式恢复设置的复制用户(在 Section 20.2.1.3, “User Credentials For Distributed Recovery”中介绍)。因此,您必须在支持克隆的所有组成员上为此复制用户授予BACKUP_ADMIN权限。在为 Group Replication 配置加入成员时,还必须为复制用户授予权限,因为它们在加入组后可以充当捐赠者。在每个组成员上为复制用户授予此权限,您可以在禁用二进制日志记录的每个组成员上单独发出此语句,或者在启用二进制日志记录的一个组成员上发出:

代码语言:javascript
复制
GRANT BACKUP_ADMIN ON *.* TO *rpl_user*@'%';

如果您使用START GROUP_REPLICATION在服务器上指定复制用户凭据,而该服务器先前使用CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO提供用户凭据,请确保在进行任何远程克隆操作之前从复制元数据存储库中删除用户凭据。还要确保group_replication_start_on_boot=OFF在加入成员上设置。有关说明,请参见 Section 20.6.3, “Securing Distributed Recovery Connections”。如果不取消用户凭据,则在远程克隆操作期间,这些凭据将传输到加入成员。然后,group_replication_recovery通道可能会意外地使用存储的凭据在原始成员或从原始成员克隆的成员上启动。服务器启动时(包括远程克隆操作后)自动启动 Group Replication 将使用存储的用户凭据,如果操作员未在START GROUP_REPLICATION命令中指定分布式恢复凭据,则也会使用这些凭据。

20.5.4.2.2 克隆门槛

当组成员已经设置支持克隆时,group_replication_clone_threshold 系统变量指定了一个阈值,以事务数量表示,用于在分布式恢复中使用远程克隆操作。如果捐赠者的事务和加入成员的事务之间的差距大于这个数字,当技术上可能时,将使用远程克隆操作进行状态传输到加入成员。Group Replication 根据现有组成员的 gtid_executed 集合计算是否已超过阈值。在存在较大事务差距的情况下使用远程克隆操作,可以让您向组中添加新成员,而无需事先手动将组的数据传输到服务器,并且还可以使非常过时的成员更有效地追赶。

group_replication_clone_threshold Group Replication 系统变量的默认设置非常高(GTID 中事务的最大允许序列号),因此在可能从二进制日志进行状态传输的地方,它有效地停用了克隆。要使 Group Replication 在更合适的情况下选择远程克隆操作进行状态传输,请设置系统变量以指定一个事务数量作为您希望进行克隆的事务差距的上限。

警告

在活动组中不要使用低设置的 group_replication_clone_threshold。如果在远程克隆操作正在进行时组中发生超过阈值的事务数量,那么加入成员在重新启动后会再次触发远程克隆操作,并且可能会无限继续这样做。为避免这种情况,请确保将阈值设置为高于您预期在远程克隆操作所需时间内组中可能发生的事务数量。

集群复制尝试执行远程克隆操作,无论您的阈值如何,当从捐赠者的二进制日志中无法进行状态转移时,例如因为加入成员所需的事务在任何现有组成员的二进制日志中都不可用时。集群复制根据现有组成员的gtid_purged集合来识别这一点。当任何成员的二进制日志文件中没有所需的事务时,您不能使用group_replication_clone_threshold系统变量来停用克隆,因为在这种情况下,克隆是将数据传输到加入成员的唯一选择。

20.5.4.2.3 克隆操作

当组成员和加入成员设置为进行克隆时,集群复制会为您管理远程克隆操作。远程克隆操作可能需要一些时间才能完成,具体取决于数据的大小。有关监视过程的信息,请参见第 7.6.7.10 节,“监视克隆操作”。

注意

当状态转移完成时,集群复制会重新启动加入成员以完成该过程。如果在加入成员上设置了group_replication_start_on_boot=OFF,例如因为您在START GROUP_REPLICATION语句中指定了复制用户凭据,那么您必须在此重新启动后再次手动发出START GROUP_REPLICATION。如果group_replication_start_on_boot=ON和启动集群复制所需的其他设置是在配置文件中设置或使用SET PERSIST语句设置的,则您无需干预,该过程将自动继续以使加入成员在线。

如果远程克隆过程花费很长时间,在 MySQL 8.0.22 之前的版本中,可能会出现在此期间为组积累的证书信息集合过大而无法传输给加入成员的情况。在这种情况下,加入成员会记录错误消息并且不会加入组。从 MySQL 8.0.22 开始,组复制以不同的方式管理已应用事务的垃圾收集过程,以避免这种情况发生。在早期版本中,如果您看到此错误,请在远程克隆操作完成后等待两分钟,以便进行一轮垃圾收集以减小组的证书信息大小。然后在加入成员上发出以下语句,以使其停止尝试应用先前的证书信息:

代码语言:javascript
复制
RESET SLAVE FOR CHANNEL group_replication_recovery;
Or from MySQL 8.0.22:
RESET REPLICA FOR CHANNEL group_replication_recovery;

远程克隆操作会将存储在表中的设置从捐赠者克隆到接收者,以及数据。组复制管理与组复制通道相关的设置。在配置文件中持久化的组复制成员设置,如组复制本地地址,不会被克隆,也不会在加入成员时更改。组复制还保留与 SSL 使用相关的通道设置,因此这些设置对于每个成员都是独一无二的。

如果捐赠者用于group_replication_recovery复制通道的复制用户凭据已使用CHANGE REPLICATION SOURCE TO | CHANGE MASTER TO语句存储在复制元数据存储库中,则在克隆后将其传输到并由加入成员使用,并且必须在那里有效。使用存储的凭据,通过远程克隆操作接收状态转移的所有组成员因此自动接收用于分布式恢复的复制用户和密码。如果在START GROUP_REPLICATION语句中指定了复制用户凭据,则这些凭据用于启动远程克隆操作,但在克隆后不会被传输到并由加入成员使用。如果不希望将凭据传输给新加入者并记录在那里,请确保在进行远程克隆操作之前取消设置它们,如第 20.6.3 节“保护分布式恢复连接”中所述,并使用START GROUP_REPLICATION来代替提供它们。

如果使用PRIVILEGE_CHECKS_USER帐户来帮助保护复制应用程序(请参阅 Section 19.3.3.2, “Group Replication 通道的权限检查”),从 MySQL 8.0.19 开始,将从捐赠者克隆PRIVILEGE_CHECKS_USER帐户和相关设置到加入的成员。如果设置加入的成员在启动时启动 Group Replication,则自动在适当的复制通道上使用该帐户进行权限检查。(在 MySQL 8.0.18 中,由于一些限制,建议不要在 Group Replication 通道中使用PRIVILEGE_CHECKS_USER帐户。)

20.5.4.2.4 其他目的的克隆

Group Replication 启动并管理分布式恢复的克隆操作。已设置为支持克隆的组成员也可以参与用户手动启动的克隆操作。例如,您可能希望通过从组成员作为捐赠者进行克隆来创建一个新的服务器实例,但您不希望新的服务器实例立即加入组,甚至可能永远不加入。

在支持克隆的所有版本中,您可以手动启动涉及 Group Replication 已停止的组成员的克隆操作。请注意,由于克隆要求捐赠者和接收者上的活动插件必须匹配,因此即使您不打算使服务器实例加入组,Group Replication 插件也必须在另一个服务器实例上安装并激活。您可以通过发出以下语句来安装插件:

代码语言:javascript
复制
INSTALL PLUGIN group_replication SONAME 'group_replication.so';

在 MySQL 8.0.20 之前的版本中,如果克隆操作涉及正在运行 Group Replication 的组成员,则无法手动启动克隆操作。从 MySQL 8.0.20 开始,您可以这样做,前提是克隆操作不会删除并替换接收方的数据。因此,启动克隆操作的语句必须包含DATA DIRECTORY子句,如果 Group Replication 正在运行。

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-tuning-recovery.html

20.5.4.3 配置分布式恢复

Group Replication 的分布式恢复过程的几个方面可以配置以适应您的系统。

连接尝试次数

对于从二进制日志进行状态传输,Group Replication 限制了加入成员在尝试连接到供体池中的供体时所做的尝试次数。如果达到连接重试限制而没有成功连接,则分布式恢复过程将以错误终止。请注意,此限制指定了加入成员尝试连接到供体的总次数。例如,如果有 2 个组成员是适当的供体,并且连接重试限制设置为 4,加入成员在达到限制之前对每个供体进行 2 次连接尝试。

默认连接重试限制为 10。您可以使用group_replication_recovery_retry_count系统变量来配置此设置。以下命令将最大连接尝试次数设置为 5:

代码语言:javascript
复制
mysql> SET GLOBAL group_replication_recovery_retry_count= 5;

对于远程克隆操作,不适用此限制。Group Replication 仅尝试与每个适当的供体进行一次连接,然后开始尝试从二进制日志进行状态传输。

连接尝试的休眠间隔

对于从二进制日志进行状态传输,group_replication_recovery_reconnect_interval系统变量定义了分布式恢复过程在尝试连接到供体之间应该休眠多长时间。请注意,分布式恢复在每次供体连接尝试后不会休眠。由于加入成员正在连接到不同的服务器而不是重复连接到同一个服务器,它可以假设影响服务器 A 的问题不会影响服务器 B。因此,分布式恢复仅在经过所有可能的供体后暂停。一旦加入组的服务器对组中的每个适当的供体都尝试连接了一次,分布式恢复过程将休眠,时间由group_replication_recovery_reconnect_interval系统变量配置。例如,如果有 2 个组成员是适当的供体,并且连接重试限制设置为 4,加入成员对每个供体进行一次连接尝试,然后休眠连接重试间隔,然后对每个供体进行一次进一步的连接尝试,直到达到限制。

默认连接重试间隔为 60 秒,您可以动态更改此值。以下命令将分布式恢复捐赠者连接重试间隔设置为 120 秒:

代码语言:javascript
复制
mysql> SET GLOBAL group_replication_recovery_reconnect_interval= 120;

对于远程克隆操作,此间隔不适用。在开始尝试从二进制日志进行状态转移之前,Group Replication 仅对每个适当的捐赠者进行一次连接尝试。

在线标记加入成员

当分布式恢复成功完成从捐赠者到加入成员的状态转移后,加入成员可以在组中标记为在线并准备参与。默认情况下,在加入成员接收并应用了其缺失的所有事务后才会执行此操作。可选地,您可以允许在加入成员接收并认证(即完成冲突检测)其缺失的所有事务后,但在应用它们之前将其标记为在线。如果您想这样做,请使用group_replication_recovery_complete_at系统变量来指定替代设置TRANSACTIONS_CERTIFIED

dev.mysql.com/doc/refman/8.0/en/group-replication-distributed-recovery-fault.html

20.5.4.4 分布式恢复的容错性

Group Replication 的分布式恢复过程具有多项内置措施,以确保在过程中出现任何问题时的容错性。

从当前视图中的适当在线组成员列表中随机选择分布式恢复的捐赠者。选择随机捐赠者意味着当多个成员进入组时,同一服务器不会被多次选择的机会很大。从 MySQL 8.0.17 开始,对于从二进制日志进行状态转移,加入者只选择运行低于或等于自身的 MySQL Server 补丁版本的捐赠者。对于早期版本,所有在线成员都可以成为捐赠者。对于远程克隆操作,加入者只选择与自身运行相同补丁版本的捐赠者。请注意,当加入成员在操作结束时重新启动时,它会与新的捐赠者建立连接,以从二进制日志进行状态转移,这可能是与用于远程克隆操作的原始捐赠者不同的成员。

在以下情况下,Group Replication 检测到分布式恢复中的错误,自动切换到新的捐赠者,并重试状态转移:

  • 连接错误 - 存在身份验证问题或与候选捐赠者建立连接的其他问题。
  • 复制错误 - 用于从二进制日志进行状态转移的复制线程之一(接收器或应用程序线程)失败。由于此状态转移方法使用现有的 MySQL 复制框架,因此可能会出现一些瞬态错误导致接收器或应用程序线程出错。
  • 远程克隆操作错误 - 远程克隆操作失败或在完成之前停止。
  • 捐赠者离开组 - 捐赠者离开组,或者在状态转移正在进行时,在捐赠者上停止 Group Replication。

Performance Schema 表replication_applier_status_by_worker显示导致最后一次重试失败的错误。在这些情况下,错误后的新连接将尝试与新的候选捐赠者建立连接。在错误事件中选择不同的捐赠者意味着新的候选捐赠者可能不会有相同的错误。如果安装了克隆插件,Group Replication 首先尝试与每个适当的在线支持克隆的捐赠者进行远程克隆操作。如果所有这些尝试失败,Group Replication 将尝试依次从所有适当的捐赠者进行二进制日志状态转移,如果可能的话。

警告

对于远程克隆操作,接收方(加入成员)上的用户创建的表空间和数据在远程克隆操作开始传输数据之前被删除。如果远程克隆操作开始但未完成,加入成员可能会留下部分原始数据文件集,或者没有用户数据。如果在数据完全克隆之前停止克隆操作,捐赠者传输的数据将从接收方中删除。Group Replication 会自动重试克隆操作,以修复这种情况。

在以下情况下,分布式恢复过程无法完成,加入成员将离开组:

  • 清除的事务 - 加入成员需要的事务不在任何在线组成员的二进制日志文件中,并且数据无法通过远程克隆操作获取(因为未安装克隆插件,或者尝试了所有可能的捐赠者但失败)。因此,加入成员无法赶上组的进度。
  • 额外的事务 - 加入成员已经包含一些组中不存在的事务。如果进行了远程克隆操作,这些事务将被删除和丢失,因为加入成员上的数据目录被擦除。如果进行了从捐赠者的二进制日志进行状态传输,这些事务可能会与组的事务发生冲突。有关处理此情况的建议,请参阅额外事务。
  • 连接重试限制已达到 - 加入成员已经尝试了连接重试限制允许的所有连接尝试。您可以使用group_replication_recovery_retry_count系统变量进行配置(参见第 20.5.4.3 节,“配置分布式恢复”)。
  • 没有更多的捐赠者 - 加入成员已经尝试了每个在线支持克隆的捐赠者进行远程克隆操作(如果安装了克隆插件),然后尝试了每个适当的在线捐赠者进行二进制日志的状态传输,如果可能的话。
  • 加入成员离开组 - 加入成员离开组或在状态传输进行中时,加入成员上的 Group Replication 停止。

如果加入成员意外离开组,因此在上述任何情况下(除最后一种情况外),它将执行group_replication_exit_state_action系统变量指定的操作。

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-view-changes.html

20.5.4.5 分布式恢复的工作原理

当 Group Replication 的分布式恢复过程从二进制日志中执行状态传输时,为了使加入的成员与捐赠者在特定时间点上同步,加入的成员和捐赠者使用 GTIDs(参见 Section 19.1.3, “Replication with Global Transaction Identifiers”)。然而,GTIDs 只提供了加入成员缺失的事务信息。它们并不能帮助标记加入群组的服务器必须追赶到的特定时间点,也不能传递认证信息。这是二进制日志视图标记的工作,它们标记了二进制日志流中的视图更改,并且包含额外的元数据信息,为加入成员提供缺失的与认证相关的数据。

本主题解释了视图更改的作用以及视图更改标识符,以及执行从二进制日志中进行状态传输的步骤。

视图和视图更改

一个视图对应于在当前配置中积极参与的一组成员,换句话说就是在特定时间点。他们在群组中正常运行并在线。

视图更改发生在群组配置发生修改时,比如成员加入或离开。任何群组成员变更都会导致独立的视图更改,同时在同一逻辑时间点向所有成员通信。

视图标识符唯一标识一个视图。每当视图更改发生时,它就会生成。

在群组通信层,视图更改及其相关的视图标识符标记了成员加入之前和之后交换的数据之间的边界。这个概念通过二进制日志事件实现:“视图更改日志事件”(VCLE)。视图标识符被记录下来,以划分在群组成员身份发生更改之前和之后传输的事务。

视图标识符本身由两部分构成:一个随机生成的部分和一个单调递增的整数。随机生成的部分在创建组时生成,并在组中至少有一个成员时保持不变。整数在每次视图更改发生时递增。使用这两个不同的部分使视图标识符能够识别由成员加入或离开引起的增量组更改,并且能够识别所有成员离开组导致的完全组关闭的情况,因此不会留下任何关于组处于何种视图的信息。在组从一开始创建时随机生成标识符的部分确保二进制日志中的数据标记保持唯一,并且在完全组关闭后不会重复使用相同的标识符,因为这将导致未来的分布式恢复出现问题。

开始:稳定组

所有服务器都在线并处理来自组的传入交易。一些服务器可能在复制交易方面稍有落后,但最终它们会收敛。该组充当一个分布式和复制的数据库。

图 20.8 稳定组

服务器 S1、S2 和 S3 是组的成员。它们的二进制日志中最近的项目是交易 T20。
服务器 S1、S2 和 S3 是组的成员。它们的二进制日志中最近的项目是交易 T20。
视图更改:成员加入

每当新成员加入组,因此执行视图更改时,每个在线服务器都会将视图更改日志事件排队等待执行。这是因为在视图更改之前,服务器上可以排队应用的多个交易,因此这些属于旧视图。在它们之后排队视图更改事件可以保证正确标记此事件发生的时间。

与此同时,加入的成员从在线服务器列表中选择一个适当的捐赠者,如成员服务通过视图抽象所述。一个成员在视图 4 上加入,而在线成员将视图更改事件写入二进制日志。

图 20.9 成员加入

服务器 S4 加入组并寻找捐赠者。服务器 S1、S2 和 S3 分别为它们的二进制日志排队视图更改条目 VC4。与此同时,服务器 S1 正在接收新交易 T21。
服务器 S4 加入组并寻找捐赠者。服务器 S1、S2 和 S3 分别为它们的二进制日志排队视图更改条目 VC4。与此同时,服务器 S1 正在接收新交易 T21。
状态转移:追赶

如果组成员和加入成员都使用克隆插件进行设置(参见第 20.5.4.2 节,“用于分布式恢复的克隆”),并且加入成员与组之间的事务差异超过了远程克隆操作的阈值(group_replication_clone_threshold),则 Group Replication 将开始使用远程克隆操作进行分布式恢复。如果所需事务不再存在于任何组成员的二进制日志文件中,则还会执行远程克隆操作。在远程克隆操作期间,加入成员上的现有数据将被删除,并替换为捐赠者的数据副本。当远程克隆操作完成并加入成员重新启动后,将从捐赠者的二进制日志进行状态转移,以获取在远程克隆操作进行时组应用的事务。如果没有大的事务间隙,或者未安装克隆插件,则 Group Replication 直接进行从捐赠者的二进制日志进行状态转移。

对于从捐赠者的二进制日志进行状态转移,加入成员与捐赠者之间建立连接并开始状态转移。这种与捐赠者的交互会一直持续,直到加入组的服务器的应用程序线程处理与加入组时触发的视图更改日志事件相对应的视图更改日志事件。换句话说,加入组的服务器会从捐赠者进行复制,直到到达与其当前所在的视图标记相匹配的视图标记为止。

图 20.10 状态转移:追赶上

服务器 S4 已选择服务器 S2 作为捐赠者。状态转移从服务器 S2 执行到服务器 S4,直至达到视图更改条目 VC4(view_id = VC4)。服务器 S4 使用临时应用程序缓冲区进行状态转移,其二进制日志目前为空。
服务器 S4 已选择服务器 S2 作为捐赠者。状态转移从服务器 S2 执行到服务器 S4,直至达到视图更改条目 VC4(view_id = VC4)。服务器 S4 使用临时应用程序缓冲区进行状态转移,其二进制日志目前为空。

由于视图标识符在同一逻辑时间传输到组中的所有成员,因此加入组的服务器知道应在哪个视图标识符处停止复制。这避免了复杂的 GTID 集计算,因为视图标识符清楚地标记了哪些数据属于每个组视图。

当加入组的服务器从捐赠者进行复制时,同时也会缓存来自组的传入事务。最终,它停止从捐赠者进行复制,并切换到应用那些已经缓存的事务。

图 20.11 排队事务

状态转移已完成。服务器 S4 已应用事务直至 T20 并将其写入二进制日志。服务器 S4 在恢复时,已将在视图更改后到达的事务 T21 缓存在临时应用程序缓冲区中。
状态转移已完成。服务器 S4 已应用事务直至 T20 并将其写入二进制日志。服务器 S4 在恢复时,已将在视图更改后到达的事务 T21 缓存在临时应用程序缓冲区中。
完成:追赶上

当加入组的服务器识别到具有预期视图标识符的视图更改日志事件时,与提供者的连接将被终止,并开始应用缓存的事务。虽然它在二进制日志中充当标记,分隔视图更改,但视图更改日志事件还扮演另一个角色。它传达了所有服务器在加入组时感知到的认证信息,换句话说是最后一次视图更改。没有它,加入组的服务器将没有必要的信息来认证(检测冲突)后续事务。

追赶的持续时间不确定,因为它取决于工作负载和事务进入组的速率。这个过程完全在线进行,加入组的服务器在追赶时不会阻塞任何其他服务器。因此,当服务器进入这个阶段时落后的事务数量可能会因工作负载而变化,从而增加或减少。

当加入组的服务器达到零排队事务并且其存储的数据与其他成员相同时,其公共状态变为在线。

图 20.12 实例在线

服务器 S4 现在是组的在线成员。它已经应用了缓存事务 T21,因此其二进制日志显示与其他组成员的二进制日志相同,并且不再需要临时应用程序缓冲区。新的传入事务 T22 现在被所有组成员接收并应用。
服务器 S4 现在是组的在线成员。它已经应用了缓存事务 T21,因此其二进制日志显示与其他组成员的二进制日志相同,并且不再需要临时应用程序缓冲区。新的传入事务 T22 现在被所有组成员接收并应用。

20.5.5 支持 IPv6 和混合 IPv6 和 IPv4 组

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-ipv6.html

从 MySQL 8.0.14 开始,Group Replication 组成员可以使用 IPv6 地址作为组内通信的替代方案,而不是 IPv4 地址。要使用 IPv6 地址,服务器主机上的操作系统和 MySQL Server 实例都必须配置为支持 IPv6。有关为服务器实例设置 IPv6 支持的说明,请参见 Section 7.1.13, “IPv6 Support”。

IPv6 地址,或解析为其的主机名,可以被指定为成员在 group_replication_local_address 选项中提供给其他成员连接的网络地址。当与端口号一起指定时,IPv6 地址必须用方括号指定,例如:

代码语言:javascript
复制
group_replication_local_address= "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:33061"

group_replication_local_address 中指定的网络地址或主机名被 Group Replication 用作复制组内组成员的唯一标识符。如果为服务器实例指定的 Group Replication 本地地址的主机名解析为 IPv4 和 IPv6 地址,那么始终使用 IPv4 地址进行 Group Replication 连接。指定为 Group Replication 本地地址的地址或主机名与 MySQL 服务器 SQL 协议主机和端口不同,并且不在服务器实例的 bind_address 系统变量中指定。为了 Group Replication 的 IP 地址权限目的(参见 Section 20.6.4, “Group Replication IP Address Permissions”),您在 group_replication_local_address 中为每个组成员指定的地址必须添加到复制组中其他服务器的 group_replication_ip_allowlist(从 MySQL 8.0.22 开始)或 group_replication_ip_whitelist 系统变量的列表中。

复制组可以包含将 IPv6 地址作为其 Group Replication 本地地址的成员组合,以及呈现 IPv4 地址的成员。当服务器加入这样的混合组时,必须使用种子成员在 group_replication_group_seeds 选项中广告的协议进行初始联系,无论是 IPv4 还是 IPv6。如果组的任何种子成员在 group_replication_group_seeds 选项中列出了具有 IPv6 地址的情况,而加入成员具有 IPv4 Group Replication 本地地址,或者反之,则还必须为加入成员为所需协议设置和允许替代地址(或解析为该协议地址的主机名)。如果加入成员没有适当协议的允许地址,则其连接尝试将被拒绝。替代地址或主机名只需要添加到复制组中其他服务器的 group_replication_ip_allowlist(从 MySQL 8.0.22 开始)或 group_replication_ip_whitelist 系统变量中,而不需要添加到加入成员的 group_replication_local_address 值(该值只能包含单个地址)。

例如,服务器 A 是一个组的种子成员,并具有以下 Group Replication 的配置设置,以便在 group_replication_group_seeds 选项中广告 IPv6 地址:

代码语言:javascript
复制
group_replication_bootstrap_group=on
group_replication_local_address= "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:33061"
group_replication_group_seeds= "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:33061"

服务器 B 是组的加入成员,并具有以下 Group Replication 的配置设置,以便具有 IPv4 Group Replication 本地地址:

代码语言:javascript
复制
group_replication_bootstrap_group=off
group_replication_local_address= "203.0.113.21:33061"
group_replication_group_seeds= "[2001:db8:85a3:8d3:1319:8a2e:370:7348]:33061"

服务器 B 还具有替代 IPv6 地址 2001:db8:8b0:40:3d9c:cc43:e006:19e8。为了成功加入组,服务器 B 的 IPv4 Group Replication 本地地址和其替代 IPv6 地址都必须列在服务器 A 的允许列表中,如下例所示:

代码语言:javascript
复制
group_replication_ip_allowlist=
"203.0.113.0/24,2001:db8:85a3:8d3:1319:8a2e:370:7348,
2001:db8:8b0:40:3d9c:cc43:e006:19e8"

作为 Group Replication IP 地址权限的最佳实践,服务器 B(以及所有其他组成员)应具有与服务器 A 相同的允许列表,除非安全要求另有规定。

如果复制组的任何成员或所有成员使用不支持在组复制中使用 IPv6 地址的较旧 MySQL Server 版本,则成员无法使用 IPv6 地址(或解析为 IPv6 地址的主机名)作为其组复制本地地址参与组。这适用于至少一个现有成员使用 IPv6 地址且不支持此功能的新成员尝试加入的情况,以及新成员尝试使用 IPv6 地址加入但组中至少有一个成员不支持此功能的情况。在每种情况下,新成员都无法加入。要使加入成员提供 IPv4 地址进行组通信,您可以将 group_replication_local_address 的值更改为 IPv4 地址,或配置您的 DNS 将加入成员的现有主机名解析为 IPv4 地址。在将每个组成员升级到支持 IPv6 用于组复制的 MySQL Server 版本后,您可以将每个成员的 group_replication_local_address 值更改为 IPv6 地址,或配置您的 DNS 提供 IPv6 地址。更改 group_replication_local_address 的值仅在停止并重新启动组复制时生效。

IPv6 地址还可以用作分布式恢复端点,从 MySQL 8.0.21 开始,可以使用 group_replication_advertise_recovery_endpoints 系统变量指定。在此列表中使用的地址适用相同的规则。请参阅 Section 20.5.4.1, “Connections for Distributed Recovery”。

20.5.6 使用 MySQL Enterprise Backup 与组复制

原文:dev.mysql.com/doc/refman/8.0/en/group-replication-enterprise-backup.html

MySQL Enterprise Backup 是 MySQL Server 的商业许可备份实用程序,可与MySQL Enterprise Edition一起使用。本节解释了如何使用 MySQL Enterprise Backup 备份并随后恢复组复制成员。相同的技术可以用于快速向组中添加新成员。

使用 MySQL Enterprise Backup 备份组复制成员

备份组复制成员类似于备份独立的 MySQL 实例。以下说明假定您已经熟悉如何使用 MySQL Enterprise Backup 执行备份;如果不是这种情况,请查看 MySQL Enterprise Backup 8.0 用户指南,特别是备份数据库服务器。还请注意授予 MySQL 特权给备份管理员和使用 MySQL Enterprise Backup 与组复制中描述的要求。

考虑以下具有三个成员s1s2s3的组,运行在具有相同名称的主机上:

代码语言:javascript
复制
mysql> SELECT member_host, member_port, member_state FROM performance_schema.replication_group_members;
+-------------+-------------+--------------+
| member_host | member_port | member_state |
+-------------+-------------+--------------+
| s1          |        3306 | ONLINE       |
| s2          |        3306 | ONLINE       |
| s3          |        3306 | ONLINE       |
+-------------+-------------+--------------+

使用 MySQL Enterprise Backup,在其主机上发出以下命令,例如,创建s2的备份:

代码语言:javascript
复制
s2> mysqlbackup --defaults-file=/etc/my.cnf --backup-image=/backups/my.mbi_`date +%d%m_%H%M` \
		      --backup-dir=/backups/backup_`date +%d%m_%H%M` --user=root -p \
--host=127.0.0.1 backup-to-image

注意

*对于 MySQL Enterprise Backup 8.0.18 及更早版本,*如果系统变量sql_require_primary_key设置为ON,MySQL Enterprise Backup 无法在服务器上记录备份进度。这是因为服务器上的backup_progress表是一个 CSV 表,不支持主键。在这种情况下,mysqlbackup在备份操作期间会发出以下警告:

代码语言:javascript
复制
181011 11:17:06 MAIN WARNING: MySQL query 'CREATE TABLE IF NOT EXISTS
mysql.backup_progress( `backup_id` BIGINT NOT NULL, `tool_name` VARCHAR(4096)
NOT NULL, `error_code` INT NOT NULL, `error_message` VARCHAR(4096) NOT NULL,
`current_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP               ON
UPDATE CURRENT_TIMESTAMP,`current_state` VARCHAR(200) NOT NULL ) ENGINE=CSV
DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin': 3750, Unable to create a table
without PK, when system variable 'sql_require_primary_key' is set. Add a PK
to the table or unset this variable to avoid this message. Note that tables
without PK can cause performance problems in row-based replication, so please
consult your DBA before changing this setting.
181011 11:17:06 MAIN WARNING: This backup operation's progress info cannot be
logged.

这并不会阻止mysqlbackup完成备份。

对于 MySQL Enterprise Backup 8.0.20 及更早版本,当备份次要成员时,由于 MySQL Enterprise Backup 无法将备份状态和元数据写入只读服务器实例,可能会在备份操作期间发出类似以下警告:

代码语言:javascript
复制
181113 21:31:08 MAIN WARNING: This backup operation cannot write to backup
progress. The MySQL server is running with the --super-read-only option.

您可以通过在备份命令中使用--no-history-logging选项来避免警告。对于 MySQL Enterprise Backup 8.0.21 及更高版本,这不是问题—请参阅使用 MySQL Enterprise Backup 与组复制获取详细信息。

恢复失败的成员

假设其中一个成员(以下示例���的s3)无法协调。可以使用组成员s2的最新备份来恢复s3。以下是执行恢复的步骤:

*将 s2 的备份复制到 s3 的主机上。*复制备份的确切方式取决于您可用的操作系统和工具。在本例中,我们假设主机都是 Linux 服务器,并使用 SCP 在它们之间复制文件:

代码语言:javascript
复制
s2/backups> scp my.mbi_2206_1429 s3:/backups

*恢复备份。*连接到目标主机(在本例中为s3的主机),并使用 MySQL Enterprise Backup 恢复备份。以下是步骤:

停止受损服务器,如果它仍在运行。例如,在使用 systemd 的 Linux 发行版上:

代码语言:javascript
复制
s3> systemctl stop mysqld

将受损服务器的数据目录中的两个配置文件auto.cnfmysqld-auto.cnf(如果存在)复制到数据目录之外的安全位置以保存服务器的 UUID 和 Section 7.1.9.3,“持久化系统变量”(如果使用),这些在下面的步骤中是必需的。

删除s3的数据目录中的所有内容。例如:

代码语言:javascript
复制
s3> rm -rf /var/lib/mysql/*

如果系统变量innodb_data_home_dirinnodb_log_group_home_dir,和innodb_undo_directory指向除数据目录之外的任何目录,则它们也应该被清空;否则,恢复操作将失败。

s2的备份恢复到s3的主机上:

代码语言:javascript
复制
s3> mysqlbackup --defaults-file=/etc/my.cnf \
  --datadir=/var/lib/mysql \
  --backup-image=/backups/my.mbi_2206_1429  \
--backup-dir=/tmp/restore_`date +%d%m_%H%M` copy-back-and-apply-log

注意

上述命令假定s2s3上的二进制日志和中继日志具有相同的基本名称,并且位于两个服务器上的相同位置。如果不满足这些条件,您应该使用--log-bin--relay-log选项将二进制日志和中继日志恢复到s3上的原始文件路径。例如,如果您知道在s3上二进制日志的基本名称是s3-bin,中继日志的基本名称是s3-relay-bin,则您的恢复命令应如下所示:

代码语言:javascript
复制
mysqlbackup --defaults-file=/etc/my.cnf \
  --datadir=/var/lib/mysql \
  --backup-image=/backups/my.mbi_2206_1429  \
  --log-bin=s3-bin --relay-log=s3-relay-bin \
  --backup-dir=/tmp/restore_`date +%d%m_%H%M` copy-back-and-apply-log

能够将二进制日志和中继日志恢复到正确的文件路径会使恢复过程更容易;如果由于某种原因这是不可能的,请参阅重建失败的成员以作为新成员重新加入。

恢复 s3 的auto.cnf文件。为了重新加入复制组,恢复的成员必须具有加入组之前使用的相同的server_uuid。通过将在步骤 2 中保留的auto.cnf文件复制到恢复成员的数据目录中来提供旧的服务器 UUID。

注意

如果您无法通过恢复其旧的auto.cnf文件向恢复的成员提供失败成员的原始server_uuid,则必须让恢复的成员作为新成员加入组;请参见下面的重建失败的成员以重新加入作为新成员中的说明。

s3恢复mysqld-auto.cnf文件(仅在s3使用持久系统变量时需要)。 必须提供用于配置失败成员的 Section 7.1.9.3,“持久系统变量”的设置,这些设置可以在失败服务器的mysqld-auto.cnf文件中找到,您应该在上述第 2 步中保留该文件。将文件恢复到恢复服务器的数据目录中。请参阅恢复持久系统变量以了解如果没有文件副本该怎么办。

启动恢复服务器。 例如,在使用 systemd 的 Linux 发行版上:

代码语言:javascript
复制
systemctl start mysqld

注意

如果您正在恢复的服务器是主要成员,请在启动恢复服务器之前执行恢复主要成员中描述的步骤。

重新启动 Group Replication。 连接到重新启动的s3,例如,使用mysql客户端,并执行以下命令:

代码语言:javascript
复制
mysql> START GROUP_REPLICATION;

在恢复的实例可以成为组的在线成员之前,需要应用在备份之后发生的任何事务;这是通过使用 Group Replication 的分布式恢复机制实现的,该过程在发出 START GROUP_REPLICATION 语句后开始。要检查恢复实例的成员状态,请执行:

代码语言:javascript
复制
mysql> SELECT member_host, member_port, member_state FROM performance_schema.replication_group_members;
+-------------+-------------+--------------+
| member_host | member_port | member_state |
+-------------+-------------+--------------+
| s1          |        3306 | ONLINE       |
| s2          |        3306 | ONLINE       |
| s3          |        3306 | RECOVERING   |
+-------------+-------------+--------------+

这表明s3正在应用事务以赶上组的进度。一旦它赶上了组的其他成员,它的member_state就会变为ONLINE

代码语言:javascript
复制
mysql> SELECT member_host, member_port, member_state FROM performance_schema.replication_group_members;
+-------------+-------------+--------------+
| member_host | member_port | member_state |
+-------------+-------------+--------------+
| s1          |        3306 | ONLINE       |
| s2          |        3306 | ONLINE       |
| s3          |        3306 | ONLINE       |
+-------------+-------------+--------------+

注意

如果您正在恢复的服务器是主要成员,一旦它与组同步并变为ONLINE,请执行恢复主要成员末尾描述的步骤,以恢复您在启动服务器之前所做的配置更改。

该成员现在已经完全从备份中恢复,并作为组的常规成员运行。

重建失败的成员以重新加入作为新成员

有时,恢复失败成员中概述的步骤无法执行,因为例如二进制日志或中继日志已损坏,或者在备份中丢失。在这种情况下,使用备份重建成员,然后将其作为新成员添加到组中。在以下步骤中,我们假设重建的成员命名为s3,与失败的成员相同,并且在与s3相同的主机上运行:

s2的备份复制到s3的主机上。复制备份的确切方式取决于您所使用的操作系统和可用工具。在本示例中,我们假设主机都是 Linux 服务器,并使用 SCP 在它们之间复制文件:

代码语言:javascript
复制
s2/backups> scp my.mbi_2206_1429 s3:/backups

恢复备份。连接到目标主机(在本例中为s3的主机),并使用 MySQL Enterprise Backup 恢复备份。以下是步骤:

停止受损的服务器,如果它仍在运行。例如,在使用 systemd 的 Linux 发行版上:

代码语言:javascript
复制
s3> systemctl stop mysqld

保留配置文件mysqld-auto.cnf,如果在受损服务器的数据目录中找到,则将其复制到数据目录之外的安全位置。这是为了保留服务器的第 7.1.9.3 节,“持久化系统变量”,稍后会用到。

删除s3的数据目录中的所有内容。例如:

代码语言:javascript
复制
s3> rm -rf /var/lib/mysql/*

如果系统变量innodb_data_home_dirinnodb_log_group_home_dirinnodb_undo_directory指向除数据目录以外的任何目录,则这些目录也应该清空;否则,恢复操作将失败。

s2的备份恢复到s3的主机上。通过这种方法,我们正在将s3重新构建为一个新成员,因此我们不需要或不想使用备份中的旧二进制日志和中继日志;因此,如果这些日志已包含在您的备份中,请使用--skip-binlog--skip-relaylog选项排除它们:

代码语言:javascript
复制
s3> mysqlbackup --defaults-file=/etc/my.cnf \
  --datadir=/var/lib/mysql \
  --backup-image=/backups/my.mbi_2206_1429  \
  --backup-dir=/tmp/restore_`date +%d%m_%H%M` \
  --skip-binlog --skip-relaylog \
copy-back-and-apply-log

注意

如果您在备份中有健康的二进制日志和中继日志,可以毫无问题地将其传输到目标主机上,建议您按照上述恢复失败成员中描述的更简单的过程进行操作。

s3恢复mysqld-auto.cnf文件(仅在s3使用持久系统变量时需要)。 必须提供用于配置失败成员的 Section 7.1.9.3, “Persisted System Variables”的设置,这些设置可以在失败服务器的mysqld-auto.cnf文件中找到,您应该在上述第 2 步中保留该文件。将文件恢复到恢复服务器的数据目录中。如果您没有文件副本,则请参阅恢复持久系统变量。

注意

不要将损坏服务器的auto.cnf文件恢复到新成员的数据目录中——当重建的s3作为新成员加入组时,它将被分配一个新的服务器 UUID。

启动恢复的服务器。 例如,在使用 systemd 的 Linux 发行版上:

代码语言:javascript
复制
systemctl start mysqld

注意

如果您正在恢复的服务器是主要成员,请在启动恢复的服务器之前执行恢复主要成员中描述的步骤。

重新配置恢复的成员以加入组复制。 使用mysql客户端连接到恢复的服务器,并使用以下命令重置源和副本信息:

代码语言:javascript
复制
mysql> RESET MASTER;
代码语言:javascript
复制
mysql> RESET SLAVE ALL;
Or from MySQL 8.0.22:
mysql> RESET REPLICA ALL;

为了使恢复的服务器能够使用组复制的内置机制进行分布式恢复,配置服务器的gtid_executed变量。为此,请使用备份的s2中包含的backup_gtid_executed.sql文件,该文件通常在恢复成员的数据目录下恢复。禁用二进制日志记录,使用backup_gtid_executed.sql文件配置gtid_executed,然后通过您的mysql客户端发出以下语句重新启用二进制日志记录:

代码语言:javascript
复制
mysql> SET SQL_LOG_BIN=OFF;
mysql> SOURCE *datadir*/backup_gtid_executed.sql
mysql> SET SQL_LOG_BIN=ON;

然后,在成员上配置组复制用户凭据:

代码语言:javascript
复制
mysql> CHANGE MASTER TO MASTER_USER='*rpl_user*', MASTER_PASSWORD='*password*' /
		FOR CHANNEL 'group_replication_recovery';

Or from MySQL 8.0.23:
mysql> CHANGE REPLICATION SOURCE TO SOURCE_USER='*rpl_user*', SOURCE_PASSWORD='*password*' /
		FOR CHANNEL 'group_replication_recovery';

重新启动组复制。 使用您的mysql客户端向恢复的服务器发出以下命令:

代码语言:javascript
复制
mysql> START GROUP_REPLICATION;

在恢复的实例可以成为组的在线成员之前,需要将备份后组中发生的任何事务应用到实例上;这是通过使用 Group Replication 的分布式恢复机制实现的,该过程在发出 START GROUP_REPLICATION 语句后开始。要检查恢复实例的成员状态,请执行:

代码语言:javascript
复制
mysql> SELECT member_host, member_port, member_state FROM performance_schema.replication_group_members;
+-------------+-------------+--------------+
| member_host | member_port | member_state |
+-------------+-------------+--------------+
| s3          |        3306 | RECOVERING   |
| s2          |        3306 | ONLINE       |
| s1          |        3306 | ONLINE       |
+-------------+-------------+--------------+

这表明s3正在应用事务以赶上组的进度。一旦它赶上了组的其他成员,其member_state将变为ONLINE

代码语言:javascript
复制
mysql> SELECT member_host, member_port, member_state FROM performance_schema.replication_group_members;
+-------------+-------------+--------------+
| member_host | member_port | member_state |
+-------------+-------------+--------------+
| s3          |        3306 | ONLINE       |
| s2          |        3306 | ONLINE       |
| s1          |        3306 | ONLINE       |
+-------------+-------------+--------------+

注意

如果您正在恢复的服务器是主要成员,在它与组同步并变为ONLINE后,执行恢复主要成员末尾描述的步骤,以恢复在启动之前对服务器所做的配置更改。

该成员现在已经作为新成员恢复到组中。

恢复持久化系统变量。 mysqlbackup不支持备份或保留 Section 7.1.9.3, “Persisted System Variables” ——文件mysqld-auto.cnf不包含在备份中。要使用其持久化变量设置启动恢复的成员,您需要执行以下操作之一:

  • 保留从损坏服务器复制的mysqld-auto.cnf文件,并将其复制到恢复服务器的数据目录。
  • 从组的另一个成员复制mysqld-auto.cnf文件到恢复服务器的数据目录,如果该成员具有与损坏成员相同的持久化系统变量设置。
  • 在启动恢复服务器并重新启动 Group Replication 之前,通过mysql客户端手动将所有系统变量设置为其持久化值。

恢复主要成员。 如果恢复的成员是组中的主要成员,则在 Group Replication 分布式恢复过程中必须注意防止对恢复数据库的写入。根据客户端访问组的方式,存在在恢复成员在网络上可访问之前执行 DML 语句的可能性,而在成员完成赶上其离线期间错过的活动之前。为了避免这种情况,在启动恢复服务器之前,在服务器选项文件中配置以下系统变量:

代码语言:javascript
复制
group_replication_start_on_boot=OFF
super_read_only=ON
event_scheduler=OFF

这些设置确保成员在启动时变为只读,并且在成员在分布式恢复过程中与组进行同步期间关闭事件调度程序。客户端还必须配置足够的错误处理,因为在恢复的成员上在此期间暂时阻止执行 DML 操作。一旦恢复过程完全完成,并且恢复的成员与组的其余部分同步,撤销这些更改;重新启动事件调度程序:

代码语言:javascript
复制
mysql> SET global event_scheduler=ON;

编辑成员选项文件中的以下系统变量,以便为下一次启动正确配置事物:

代码语言:javascript
复制
group_replication_start_on_boot=ON
super_read_only=OFF
event_scheduler=ON

务器发出以下命令:

代码语言:javascript
复制
```sql
mysql> START GROUP_REPLICATION;
```

在恢复的实例可以成为组的在线成员之前,需要将备份后组中发生的任何事务应用到实例上;这是通过使用 Group Replication 的分布式恢复机制实现的,该过程在发出 START GROUP_REPLICATION 语句后开始。要检查恢复实例的成员状态,请执行:

```sql
mysql> SELECT member_host, member_port, member_state FROM performance_schema.replication_group_members;
+-------------+-------------+--------------+
| member_host | member_port | member_state |
+-------------+-------------+--------------+
| s3          |        3306 | RECOVERING   |
| s2          |        3306 | ONLINE       |
| s1          |        3306 | ONLINE       |
+-------------+-------------+--------------+
```

这表明`s3`正在应用事务以赶上组的进度。一旦它赶上了组的其他成员,其`member_state`将变为`ONLINE`:

```sql
mysql> SELECT member_host, member_port, member_state FROM performance_schema.replication_group_members;
+-------------+-------------+--------------+
| member_host | member_port | member_state |
+-------------+-------------+--------------+
| s3          |        3306 | ONLINE       |
| s2          |        3306 | ONLINE       |
| s1          |        3306 | ONLINE       |
+-------------+-------------+--------------+
```

注意

如果您正在恢复的服务器是主要成员,在它与组同步并变为`ONLINE`后,执行恢复主要成员末尾描述的步骤,以恢复在启动之前对服务器所做的配置更改。

该成员现在已经作为新成员恢复到组中。

恢复持久化系统变量。 mysqlbackup不支持备份或保留 Section 7.1.9.3, “Persisted System Variables” ——文件mysqld-auto.cnf不包含在备份中。要使用其持久化变量设置启动恢复的成员,您需要执行以下操作之一:

  • 保留从损坏服务器复制的mysqld-auto.cnf文件,并将其复制到恢复服务器的数据目录。
  • 从组的另一个成员复制mysqld-auto.cnf文件到恢复服务器的数据目录,如果该成员具有与损坏成员相同的持久化系统变量设置。
  • 在启动恢复服务器并重新启动 Group Replication 之前,通过mysql客户端手动将所有系统变量设置为其持久化值。

恢复主要成员。 如果恢复的成员是组中的主要成员,则在 Group Replication 分布式恢复过程中必须注意防止对恢复数据库的写入。根据客户端访问组的方式,存在在恢复成员在网络上可访问之前执行 DML 语句的可能性,而在成员完成赶上其离线期间错过的活动之前。为了避免这种情况,在启动恢复服务器之前,在服务器选项文件中配置以下系统变量:

代码语言:javascript
复制
group_replication_start_on_boot=OFF
super_read_only=ON
event_scheduler=OFF

这些设置确保成员在启动时变为只读,并且在成员在分布式恢复过程中与组进行同步期间关闭事件调度程序。客户端还必须配置足够的错误处理,因为在恢复的成员上在此期间暂时阻止执行 DML 操作。一旦恢复过程完全完成,并且恢复的成员与组的其余部分同步,撤销这些更改;重新启动事件调度程序:

代码语言:javascript
复制
mysql> SET global event_scheduler=ON;

编辑成员选项文件中的以下系统变量,以便为下一次启动正确配置事物:

代码语言:javascript
复制
group_replication_start_on_boot=ON
super_read_only=OFF
event_scheduler=ON
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-06-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 20.1.5 Group Replication 插件架构
  • 20.2 开始
  • 20.2.1 在单主模式下部署组复制
  • 20.2.2 本地部署组复制
  • 20.3 需求和限制
  • 20.3.1 Group Replication Requirements
  • 20.3.2 Group Replication 限制
  • 20.4 监视组复制
  • 20.4.1 GTIDs 和组复制
  • 20.4.2 Group Replication Server States
  • 20.4.3 The replication_group_members Table
  • 20.4.4 The replication_group_member_stats Table
  • 20.5 群组复制操作
  • 20.5.1 配置在线组
  • 20.5.2 重新启动组
  • 20.5.3 事务一致性保证
  • 20.5.4 分布式恢复
  • 20.5.5 支持 IPv6 和混合 IPv6 和 IPv4 组
  • 20.5.6 使用 MySQL Enterprise Backup 与组复制
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档