#### 18.1.3.2 多主模式

[](<>)

在多主模式下（[`group_replication_single_primary_mode=OFF`](group-replication-options.html#sysvar_group_replication_single_primary_mode)) 没有成员有特殊的角色。任何与其他组成员兼容的成员在加入组时都设置为读写模式，并且可以处理写事务，即使它们是并发发出的。

如果成员停止接受写入事务，例如，在服务器意外退出的情况下，连接到它的客户端可以重定向或故障转移到处于读写模式的任何其他成员。组复制本身不处理客户端故障转移，因此您需要使用中间件框架来安排它，例如[MySQL 路由器 8.0](https://dev.mysql.com/doc/mysql-router/8.0/en/)、代理、连接器或应用程序本身。[图 18.5，“客户端故障转移”](group-replication-multi-primary-mode.html#group-replication-multi-primary-diagram)显示如果成员离开组，客户端如何重新连接到备用组成员。

[](<>)

**图 18.5 客户端故障转移**

<img alt="Five server instances, S1, S2, S3, S4, and S5, are deployed as an interconnected group. All of the servers are primaries. Write clients are communicating with servers S1 and S2, and a read client is communicating with server S4. Server S1 then fails, breaking communication with its write client. This client reconnects to server S3." src="images/multi-primary.png" height="356" width="899" />

组复制是一个最终一致性系统。这意味着一旦传入流量变慢或停止，所有组成员都具有相同的数据内容。当流量在流动时，事务可以先于其他成员在某些成员上进行外部化，特别是如果某些成员的写入吞吐量低于其他成员，从而产生过时读取的可能性。在多主模式下，速度较慢的成员还可以建立过多的交易积压以进行认证和申请，从而导致更大的冲突和认证失败风险。为了限制这些问题，您可以激活和调整 Group Replication 的流量控制机制，以尽量减少快速和慢速成员之间的差异。有关流量控制的更多信息，请参阅[第 18.7.2 节，“流量控制”](group-replication-flow-control.html).

从 MySQL 8.0.14 开始，如果您想为组中的每个事务提供事务一致性保证，您可以使用[`group_replication_consistency`](group-replication-options.html#sysvar_group_replication_consistency)系统变量。您可以选择适合您的组的工作负载和数据读取和写入优先级的设置，同时考虑提高一致性所需的同步对性能的影响。您还可以为各个会话设置系统变量，以保护对并发敏感的事务。有关事务一致性的更多信息，请参阅[第 18.5.3 节，“交易一致性保证”](group-replication-consistency-guarantees.html).

##### 18.1.3.2.1 交易检查

当一个组以多主模式部署时，会检查事务以确保它们与该模式兼容。以多主模式部署 Group Replication 时，会进行以下严格的一致性检查：

-   如果事务在 SERIALIZABLE 隔离级别下执行，则在与组同步时其提交失败。

-   如果事务针对具有具有级联约束的外键的表执行，则在与组同步时其提交失败。

    支票由[`group_replication_enforce_update_everywhere_checks`](group-replication-options.html#sysvar_group_replication_enforce_update_everywhere_checks)系统变量。在多主模式下，系统变量通常应设置为`在`，但可以选择通过将系统变量设置为来停用检查`离开`.在单主模式下部署时，系统变量必须设置为`离开`.

##### 18.1.3.2.2 数据定义语句

[](<>)

在多主模式下的 Group Replication 拓扑中，执行数据定义语句时需要小心，通常也称为数据定义语言 (DDL)。

MySQL 8.0 引入了对原子数据定义语言 (DDL) 语句的支持，其中完整的 DDL 语句作为单个原子事务提交或回滚。但是，DDL 语句，无论是原子的还是其他的，都会隐式结束当前会话中活动的任何事务，就好像您已经完成了[`犯罪`](commit.html)在执行语句之前。这意味着 DDL 语句不能在另一个事务中执行，例如在事务控制语句中[`开始交易...提交`](commit.html)，或与同一事务中的其他语句组合。

组复制基于乐观复制范式，其中语句被乐观地执行并在必要时稍后回滚。每台服务器在没有首先获得组协议的情况下执行。因此，在多主模式下复制 DDL 语句时需要更加小心。如果您对同一对象进行模式更改（使用 DDL）和对象包含的数据更改（使用 DML），则需要通过同一服务器处理更改，而模式操作尚未完成并在各处复制。当操作中断或仅部分完成时，不这样做可能会导致数据不一致。如果该组以单主模式部署，则不会发生此问题，因为所有更改都是通过同一台服务器（即主服务器）执行的。

有关 MySQL 8.0 中原子 DDL 支持的详细信息，以及复制某些语句所导致的行为变化，请参阅[第 13.1.1 节，“原子数据定义语句支持”](atomic-ddl.html).

##### 18.1.3.2.3 版本兼容性

为了获得最佳兼容性和性能，组的所有成员都应运行相同版本的 MySQL 服务器，因此也应运行相同的组复制。在多主模式下，这更重要，因为所有成员通常都会以读写模式加入组。如果一个组包含运行多个 MySQL 服务器版本的成员，则某些成员可能与其他成员不兼容，因为它们支持其他人不支持的功能，或者缺少其他人拥有的功能。为了防止这种情况发生，当新成员加入时（包括已升级和重新启动的前成员），该成员将对组的其余成员进行兼容性检查。

这些兼容性检查的一个结果在多主模式中尤为重要。如果加入的成员运行的 MySQL 服务器版本高于现有组成员运行的最低版本，它会加入组但保持只读模式。（在以单主模式运行的组中，新添加的成员在任何情况下都默认为只读。）运行 MySQL 8.0.17 或更高版本的成员在检查其兼容性时会考虑发行版的补丁版本。运行 MySQL 8.0.16 或更低版本或 MySQL 5.7 的成员仅考虑主要版本。

在以多主模式运行且成员使用不同 MySQL Server 版本的组中，Group Replication 自动管理运行 MySQL 8.0.17 或更高版本的成员的读写和只读状态。如果成员离开组，运行现在最低版本的成员将自动设置为读写模式。当您将在单主模式下运行的组更改为在多主模式下运行时，使用[`group_replication_switch_to_multi_primary_mode()`](group-replication-functions-for-mode.html#function_group-replication-switch-to-multi-primary-mode)功能，组复制自动将成员设置为正确的模式。如果成员运行的 MySQL 服务器版本高于组中存在的最低版本，则成员将自动置于只读模式，而运行最低版本的成员将置于读写模式。

有关组中版本兼容性以及在升级过程中如何影响组行为的完整信息，请参阅[第 18.8.1 节，“在组中组合不同的成员版本”](group-replication-online-upgrade-combining-versions.html).
