在传统主从复制中,架构的可用性高度依赖外部工具来实现故障检测和主库切换。一旦主库宕机,如果不借助 MHA、Orchestrator 等组件,很难自动完成切换并保证数据不丢失。MySQL 组复制(MySQL Group Replication,简称 MGR)则提供了一种原生的高可用解决方案,它将多个 MySQL 实例组成一个复制组,组内任何成员都可以处理读写请求(单主模式)或所有成员均可写入(多主模式),并基于 Paxos 协议自动进行故障检测和选主。
20.3.1 组复制的核心思想:基于 Paxos 的强一致性复制
MGR 的实现基础是 Paxos 协议,具体采用的是其变种——Mencius 算法,允许多个节点同时提案,降低单一 Leader 的瓶颈。这套机制使得组复制能够做到:
- 数据强一致性:事务提交前,必须经过组内多数节点的认可(多数派确认),从而保证在发生故障时已提交的事务绝对不会丢失。
- 自动故障检测与恢复:组内节点通过心跳互相监控,一旦发现某个成员失联或性能严重滞后,组可自动将其驱逐;当主节点故障时,剩余节点会在极短时间内选出新的主节点,无需人工干预。
- 成员管理自动化:新节点加入时,组复制会自动从现有节点获取增量数据,追上状态后成为正式成员,整个过程对应用层几乎透明。
从使用者角度看,MGR 就像是一个自带高可用和故障切换的 MySQL 集群,没有中心协调节点,所有成员对等,避免了单点故障。
20.3.2 组复制的架构与运行模式
一个 MGR 组通常由三个或更多的 MySQL 实例组成(出于容错需要,生产环境建议至少三个节点)。所有节点运行相同的 MySQL 版本,并启用组复制插件。
架构核心组件:
- 组通信引擎(GCS):基于 Paxos 的实现,负责组内消息传递、成员列表维护、事务全局排序。它使用 XCom 通信层传递事务消息,比原始的 Binlog 复制更底层和高效。
- 组复制插件(group_replication):嵌入 MySQL 服务层,拦截事务提交流程,将 Binlog 事件发送给 GCS,并根据多数派确认结果决定是提交还是回滚。
- Binlog 作为事务载体:事务在发起节点从存储引擎层面提交后,其对应的 Binlog 事件作为 Paxos 提案在组内复制。各节点接收到事务后,将其 Relay Log 事件写入并应用,从而保持数据一致。
两种运行模式:
- 单主模式(Single-Primary):组内只有一个节点可以写入(主节点),其余均为只读节点。如果主节点故障,组复制会自动从其余节点中选举一个新主,并将写权限转移给它。这是生产环境中最常用的模式,因为它避免了多写冲突,应用层也无需考虑冲突处理。
- 多主模式(Multi-Primary):组内所有节点都可以接受写入。MySQL 通过在事务提交时进行冲突检测(基于主键和版本信息)来确保数据一致性,如果检测到冲突,后提交的事务会被回滚。这一模式对应用设计和网络延迟要求较高,一般用于跨地域分布式写入的场景。
无论哪种模式,所有事务都必须经过多数派确认,因此组复制对网络延迟较为敏感,跨地域部署时需要通过配置 group_replication_consistency 参数在一致性和响应延迟之间权衡。
20.3.3 事务执行的详细流程
以单主模式为例,一条写操作在 MGR 中的完整流程如下:
- 客户端发起事务,在主节点上正常执行 SQL。
- 事务准备提交时,InnoDB 先将写入记录到 Redo Log 和 Undo Log,生成相应的 Binlog 事件。
- 组复制插件拦截提交,将本事务的 Binlog 事件打包成 Paxos 提案,通过 GCS 发送给组内所有成员。
- 各成员收到提案后,向提案发起者发送确认(Ack)。当发起节点收集到包括自己在内的多数派确认后,表决通过。
- 发起者收到多数派确认后,向所有成员广播“提交”消息,然后各节点各自提交该事务(先后写入 Relay Log、应用 Binlog、提交存储引擎)。
- 客户端收到提交成功返回,整个事务完成。
如果在这个过程中主节点崩溃,组内剩余节点会重新选举一个主节点,并从已达成多数派确认的事务开始继续服务,崩溃节点重新加入时会自动追赶并同步。
20.3.4 生产环境部署的关键参数与注意事项
MGR 并非“即装即用”,上线前需要理解并调整以下关键参数:
group_replication_group_name:组的唯一标识,必须为 UUID,每个节点相同。group_replication_local_address:本节点用于组通信的 IP 和端口(例如192.168.1.10:33061),每个节点都要配置。group_replication_group_seeds:种子成员地址列表,用于节点加入时发现组中其他成员。group_replication_bootstrap_group:仅在第一个启动的节点上设为ON,用于创建新组,后续节点加入时必须设为OFF。group_replication_single_primary_mode:控制单主/多主模式,默认为ON(单主)。group_replication_consistency:控制事务一致性与性能的平衡,可设为EVENTUAL、BEFORE_ON_PRIMARY_FAILOVER、BEFORE、AFTER等,强烈建议生产环境设置为BEFORE_ON_PRIMARY_FAILOVER或更高。transaction_write_set_extraction:必须设为XXHASH64,用于多主模式下的冲突检测。
除了参数,部署时还需注意:
- 所有表必须有主键:MGR 的冲突检测依赖主键来识别行,没有主键的表无法进行冲突校验,操作会被拒绝。
- 网络必须低延迟且稳定:组内节点间的网络抖动会导致提案确认超时,进而引发成员驱逐和重新加入,频繁的成员变更会严重降低集群可用性。
- 节点数最好为奇数:这符合多数派协议的故障容忍原则。3 个节点可容忍 1 个节点故障,5 个节点可容忍 2 个节点故障。偶数节点并不会提高容错能力,反而增加通信开销。
- 不要在 MGR 上执行 DDL 和 DML 混合:虽然组复制允许并发 DDL,但大量 DDL 操作可能引发冲突或延迟,建议通过专门的变更流程执行。
- 定期监控成员状态和复制延迟:可通过
performance_schema.replication_group_members和replication_group_member_stats表查看各节点角色和健康状况,发现异常成员及时处理。
20.3.5 MGR 的适用场景与局限性
MGR 最适合以下场景:
- 要求数据库层自动故障切换,不希望依赖外部 HA 工具。
- 对数据一致性要求极高,不能接受主从异步复制可能造成的数据丢失。
- 需要弹性扩缩容,可以动态增加或减少节点(单一主模式增加只读从节点很简便)。
- 有跨机房强一致需求的业务(多主模式可以部署在同城双活环境中)。
不过 MGR 也存在一些局限:
- 性能开销:每个事务都需要多数派确认,写请求的响应时间会略高于普通主从复制,特别是在网络延迟较高的环境下。
- 不支持一些传统功能:例如 GTID 模式是强制开启的,不能关闭;部分 DDL 操作受限;大事务可能导致组内大量积压。
- 运维复杂度:虽然内置了高可用,但对网络、主机名依赖较强,故障排查比传统主从更复杂,需要对 Paxos 原理有一定理解。
- 多主模式冲突风险:如果两个节点同时修改同一行数据,后提交的事务会被回滚,应用需要能够处理这种重试逻辑。
综合来看,MGR 是 MySQL 官方在原生高可用方向上的一次重要升级,让用户可以在不引入第三方中间件的情况下,获得一个自管理、强一致、可自动故障恢复的数据库集群。对于新上线的项目或希望减少外部依赖的团队,MGR 是一个非常值得考虑的选择。