在多主模式 (group_replication_single_primary_mode=OFF
) 中,没有成员具有特殊角色。任何与其他组成员兼容的成员在加入组时都会被设置为读写模式,并且可以处理写事务,即使它们是并发发出的。
如果一个成员停止接受写事务,例如,在服务器意外退出时,连接到它的客户端可以被重定向或故障转移到任何其他处于读写模式的成员。组复制本身不处理客户端故障转移,因此您需要使用中间件框架(例如 MySQL Router 8.4、代理、连接器或应用程序本身)来安排此操作。 图 20.5,“客户端故障转移” 显示了如果一个成员离开组,客户端如何重新连接到替代的组成员。
组复制是一个最终一致性系统。这意味着,一旦传入流量减慢或停止,所有组成员都具有相同的数据内容。在流量流动时,事务可以在一些成员上外部化,然后再在其他成员上外部化,特别是如果一些成员的写入吞吐量低于其他成员,从而导致潜在的陈旧读取。在多主模式下,较慢的成员也可能会积压过多的需要认证和应用的事务,从而导致冲突和认证失败的风险更大。为了限制这些问题,您可以激活和调整组复制的流量控制机制,以最大程度地减少快速成员和慢速成员之间的差异。有关流量控制的更多信息,请参见 第 20.7.2 节,“流量控制”.
如果要为组中的每个事务保证事务一致性,可以使用 group_replication_consistency
系统变量来实现。您可以选择适合组的工作负载和数据读写优先级的设置,并考虑到提高一致性所需的同步带来的性能影响。您还可以为单个会话设置系统变量,以保护特别对并发敏感的事务。有关事务一致性的更多信息,请参见 第 20.5.3 节,“事务一致性保证”.
当一个组以多主模式部署时,会检查事务以确保它们与模式兼容。当组复制以多主模式部署时,会执行以下严格的一致性检查
如果一个事务在 SERIALIZABLE 隔离级别下执行,那么它在与组同步时其提交会失败。
如果一个事务针对具有级联约束的外键表执行,那么它在与组同步时其提交会失败。
这些检查由 group_replication_enforce_update_everywhere_checks
系统变量控制。在多主模式下,系统变量通常应设置为 ON
,但可以通过将系统变量设置为 OFF
来选择性地停用检查。在单主模式下部署时,系统变量必须设置为 OFF
。
在多主模式下的组复制拓扑中,在执行数据定义语句(也称为数据定义语言 (DDL))时需要谨慎。
MySQL 8.4 支持原子数据定义语言 (DDL) 语句,其中完整的 DDL 语句要么作为单个原子事务提交,要么回滚。 DDL 语句(原子或其他)会隐式结束当前会话中的任何活动事务,就像您在执行语句之前执行了 COMMIT
一样。这意味着 DDL 语句不能在另一个事务内执行,不能在事务控制语句(例如 START TRANSACTION ... COMMIT
)内执行,也不能与同一个事务内的其他语句组合执行。
组复制基于乐观复制范式,其中语句会乐观地执行,并在必要时稍后回滚。每个服务器在执行之前都不会先获得组协议。因此,在多主模式下复制 DDL 语句时需要更加谨慎。如果对同一个对象的架构进行了更改(使用 DDL)和对该对象包含的数据进行了更改(使用 DML),则需要通过同一个服务器来处理这些更改,同时架构操作尚未完成并复制到所有地方。如果不这样做,如果操作被中断或仅部分完成,可能会导致数据不一致。如果组以单主模式部署,则不会发生此问题,因为所有更改都是通过同一个服务器(主服务器)执行的。
有关原子 DDL 支持的更多信息,请参见 第 15.1.1 节,“原子数据定义语句支持”.
为了获得最佳的兼容性和性能,一个组中的所有成员都应该运行相同的 MySQL Server 版本,因此也应该运行相同的 Group Replication 版本。在多主模式下,这一点更为重要,因为所有成员通常都会以读写模式加入组。如果一个组包含运行多个 MySQL Server 版本的成员,则可能存在一些成员与其他成员不兼容,因为它们支持其他成员不支持的功能,或者缺少其他成员具有的功能。为了防止这种情况,当一个新成员加入时(包括已升级和重新启动的旧成员),该成员会对组中其他成员进行兼容性检查。
这些兼容性检查的结果之一在多主模式下尤为重要。如果加入的成员运行的 MySQL Server 版本高于现有组成员运行的最低版本,它将加入组,但保持只读模式。(在一个以单主模式运行的组中,新添加的成员默认情况下在任何情况下都是只读的。)运行 MySQL 8.0.17 或更高版本的成员在检查其兼容性时会考虑 MySQL 软件的主要版本、次要版本和发行版本(以及 Group Replication 插件的版本)。运行早期版本的成员只考虑主要版本和次要版本。
在一个以多主模式运行的组中,如果成员使用不同的 MySQL Server 版本,Group Replication 会自动管理运行 MySQL 8.0.17 或更高版本的成员的读写状态和只读状态。如果一个成员离开组,则运行现在最低版本的成员会自动设置为读写模式。当您将以单主模式运行的组更改为以多主模式运行时,使用 group_replication_switch_to_multi_primary_mode()
函数,Group Replication 会自动将成员设置为正确的模式。如果成员运行的 MySQL Server 版本高于组中存在的最低版本,则会自动将其设置为只读模式;如果成员运行的版本为最低版本,则会将其设置为读写模式。
有关组中版本兼容性的完整信息,以及这如何影响升级过程中的组行为,请参见 第 20.8.1 节,“组合组中不同的成员版本” 。