Files
cs-note/hhs/MySQL/07-高可用与分布式/32-Group Replication.md
T
2026-05-24 11:42:38 +08:00

9.3 KiB
Raw Blame History

tags, create time
tags create time
MySQL
Group Replication
Paxos
多主复制
集群
2026-05-16 00:00

Group Replication(组复制)

概述

Group Replication(GR)是 Oracle 官方提供的 MySQL 高可用解决方案,基于 Paxos 共识算法实现多主复制,提供自动故障检测和成员管理。它代表了 MySQL 分布式能力的核心方向。

GR 与主从复制的对比

flowchart LR
    subgraph "传统主从"
        RM["单主模型<br/>Master → Slave(s)"]
        RS["异步/半同步复制"]
        RF["故障切换需外部工具"]
    end
    
    subgraph "Group Replication"
        RG["多主模型<br/>任一节点接受写入"]
        RP["Paxos 共识保证一致性"]
        RA["自动故障检测 + 自动选举"]
    end
    
    RM -.">"| RA
    RF -.">"| RA
    
    style RG fill:#00B6BC,color:#fff
    style RP fill:#C44569,color:#fff
    style RA fill:#00D866,color:#fff

两种工作模式

单主模式(Single-Primary)

flowchart TD
    Primary["Primary\nRW + RO"] --> Paxos["Paxos 共识层"]
    Paxos --> S1["Secondary 1\n只读"]
    Paxos --> S2["Secondary 2\n只读"]
    Paxos --> S3["Secondary N\n只读"]
    
    style Primary fill:#00B6BC,color:#fff
    style Paxos fill:#C44569,color:#fff
    style S1 fill:#74b9ff,color:#000
    style S2 fill:#74b9ff,color:#000
    style S3 fill:#74b9ff,color:#000
  • 特点:类似主从,但故障切换全自动
  • 适用:大多数读写分离场景
  • 冲突解决:单主天然无冲突

多主模式(Multi-Primary)

flowchart LR
    N1["Node 1\nRW + RO"] <-- Paxos --> N2["Node 2\nRW + RO"]
    N2 <-- Paxos --> N3["Node 3\nRW + RO"]
    
    style N1 fill:#00B6BC,color:#fff
    style N2 fill:#C44569,color:#fff
    style N3 fill:#00D866,color:#fff
  • 特点:所有节点都可读写
  • 适用:多数据中心容灾、低延迟写入需求
  • 冲突检测:基于行级别的乐观锁,冲突时拒绝写入节点

[!WARNING] 多主模式的限制

  • 有冲突检测但不自动解决——冲突的那条事务会被拒绝并返回错误码 3092
  • 不适合相同数据在多个节点上同时修改的场景
  • 生产环境推荐使用单主模式

GR 的工作原理

flowchart TD
    Client["客户端连接"] --> Node["任意节点"]
    Node --> TXN["事务执行"]
    TXN --> Cert["Certification: 检查与其他节点的冲突"]
    Cert -->|"无冲突"| Order["Ordering: 获得全局顺序号"]
    Cert -->|"冲突"| REJECT["❌ 事务被拒绝<br/>error 3092"]
    
    Order --> Broadcast["Broadcast: 向所有成员广播 committed order"]
    Broadcast --> Apply["Apply: 按全局顺序提交"]
    
    Apply --> Members{"所有成员 >= N/2+1?"}
    Members -->|是| SUCCESS["✅ 事务提交成功"]
    Members -->|否| PENDING["⏳ pending 状态<br/>等待多数派确认"]
    
    style SUCCESS fill:#00D866,color:#fff
    style REJECT fill:#EE5A24,color:#fff
    style PENDING fill:#FF9F43,color:#000

Certification(认证)

GR 在每个事务提交前进行冲突检测:

// 伪代码:certification 算法
func certTransaction(txn Transaction) error {
    for _, pk := range txn.writeSet.primaryKeys {
        // 检查全局 write set 中是否存在相同主键的并发事务
        if conflict, exists := globalWriteSet.Find(pk); exists {
            if !areCommutative(txn, conflict) {
                return ErrorConflict("row-level conflict detected")
            }
        }
    }
    return nil
}

认证流程的核心思路:

  1. Collect: 当事务在本地执行完毕后,收集所有被修改行的主键集合(write set)
  2. Certify: 将 write set 与组内其他成员已提交的事务进行比较
  3. Resolve: 若发现冲突且不可交换(commutative),则拒绝该事务(返回错误码 3092);若无冲突或可交换,则通过认证

[!TIP] 什么是可交换操作? 两个事务如果修改的是不同的行,即使它们同时发生也不会冲突,这在数学上称为「可交换」(commutative)。例如:UPDATE users SET age=age+1 WHERE id=1 和 UPDATE users SET name='Alice' WHERE id=2 是可交换的,GR 允许两者都提交。

Ordering(全局排序)

通过认证后,事务需要获得一个全局顺序号(view change ID + local order),确保所有节点以完全相同的顺序应用事务——这是保证一致性的关键。

Broadcast & Apply(广播与应用)

获得全局序号的事务会通过 group communication layer 广播给所有组成员。每个成员收到后按全局顺序依次 apply,最终达成状态机的一致性。这就是 Paxos/Raft 式的确定性状态机复制。

flowchart TD
    TA["事务 A: UPDATE users SET x=1 WHERE id=1"]
    TB["事务 B: UPDATE users SET y=2 WHERE id=1"]
    
    TA --> CA{Certification}
    TB --> CB{Certification}
    
    CA -->|passed| O1["已获得全局顺序 #100"]
    CB -->|conflict! both write id=1| CE["Conflict Error 3092"]
    
    style CE fill:#EE5A24,color:#fff

部署配置

# 每个节点 my.cnf 中需要配置

# 基本复制配置
server_id = 1
gtid_mode = ON
enforce_gtid_consistency = ON
master_info_repository = TABLE
relay_log_info_repository = TABLE
binlog_checksum = NONE

# GR 专用配置
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 = "10.0.1.10:33061"
group_replication_group_seeds = "10.0.1.10:33061,10.0.1.11:33061,10.0.1.12:33061"

# 单主模式
group_replication_single_primary_mode = ON
group_replication_enforce_update_everywhere_checks = OFF

# 多主模式(取消注释以上两行,注释掉以下两行)
# group_replication_single_primary_mode = OFF
# group_replication_enforce_update_everywhere_checks = ON

初始化步骤

-- 在每个节点上执行

-- 1. 创建复制用户
CREATE USER rpl_user@'%' IDENTIFIED BY 'password';
GRANT REPLICATION SLAVE ON *.* TO rpl_user@'%';
FLUSH PRIVILEGES;

-- 2. 配置集群地址
SET GLOBAL group_replication_bootstrap_group = OFF;

-- 3. 在第一个节点启动组(引导组)
SET GLOBAL group_replication_bootstrap_group = ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group = OFF;

-- 4. 在其他节点加入组
START GROUP_REPLICATION;

-- 5. 检查组成员状态
SELECT * FROM performance_schema.replication_group_members;

性能与注意事项

性能特点

GR 的性能瓶颈主要来自 Paxos 共识层,以下为生产环境的经验总结:

维度 说明
写入延迟 单主模式下,提交需要等待多数派确认(majority commit),TPS 通常比异步主从低 20%~40%
并发能力 行级认证 + 乐观锁策略让不同行的写操作可以并行通过,高并发小事务场景表现较好
网络要求 节点间通过端口 33061 通信,要求低延迟、高带宽局域网;跨 DC 部署延迟应控制在 5ms 以内
SSD 必要 binlog 和 relay log 频繁刷盘,强烈建议使用 SSD/NVMe

生产注意事项

[!IMPORTANT] 上线前必须检查的清单

  1. 表必须有主键:没有主键的表无法被 GR 复制,启动时会报错并拒绝加入该表的数据
  2. 外键约束:建议关闭 foreign_key_checks,GR 不保证跨节点外键一致性
  3. 存储引擎:只支持 InnoDB
  4. 事务隔离级别:推荐使用 READ COMMITTED(GR 默认),RR 在部分场景下可能增加冲突概率
  5. 自增主键冲突:多主模式下多个节点同时产生自增值会冲突,需配置 auto_increment_increment 和 auto_increment_offset 错开编号区间
  6. DDL 操作:大表的 DDL(如 ADD INDEX)会在整个组阻塞,务必在维护窗口执行
  7. GTID 不可变:开启 GTID 后无法关闭,数据初始化时必须用 GTID 方式导出导入

故障处理

stateDiagram-v2
    [*] --> ONLINE: 节点正常加入组
    
    ONLINE --> REMOVED: 节点宕机 / 网络断开
    ONLINE --> OFFLINE: 手动 STOP GROUP_REPLICATION
    
    REMOVED --> SELF_JOIN: 节点恢复并重新加入
    REMOVED --> [*]: 永久退出
    
    SELF_JOIN --> ONLINE: 数据同步完成
    
    state REMOVED {
        state_config ["Config Change Pending"]
        state_error ["Error Recovering"]
    }

[!NOTE] 组的最小生存条件

  • 单主模式:至少 2 个节点在线(1 primary + 1 secondary)
  • 多主模式:至少 N/2+1 个节点在线
  • 少于这个阈值,整个组进入 readonly 模式,拒绝所有写入

监控命令

-- 组成员状态
SELECT * FROM performance_schema.replication_group_members;
-- MEMBER_ID, MEMBER_HOST, MEMBER_PORT, MEMBER_STATE (ONLINE/RECOVERING/ERROR/RO)

-- 组内事务统计
SELECT * FROM performance_schema.replication_group_member_stats;

-- 正在进行的冲突事务
SELECT * FROM performance_schema.replication_group_history;

-- 连接数
SELECT * FROM performance_schema.replication_group_connections;

关联笔记