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

276 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
tags: [MySQL, Group Replication, Paxos, 多主复制, 集群]
create time: 2026-05-16 00:00
---
# Group Replication(组复制)
## 概述
Group Replication(GR)是 Oracle 官方提供的 MySQL 高可用解决方案,基于 Paxos 共识算法实现多主复制,提供自动故障检测和成员管理。它代表了 MySQL 分布式能力的核心方向。
## GR 与主从复制的对比
```mermaid
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)
```mermaid
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)
```mermaid
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 的工作原理
```mermaid
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 在每个事务提交前进行冲突检测:
```go
// 伪代码: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 式的确定性状态机复制。
```mermaid
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
```
## 部署配置
```ini
# 每个节点 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
```
### 初始化步骤
```sql
-- 在每个节点上执行
-- 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 方式导出导入
## 故障处理
```mermaid
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 模式,拒绝所有写入
## 监控命令
```sql
-- 组成员状态
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;
```
## 关联笔记
- [[hhs/MySQL/07-高可用与分布式/30-主从复制详解]] — GR 的主干是改进后的主从复制
- [[hhs/MySQL/07-高可用与分布式/31-MHA与Orchestrator]] — 为什么 GR 不需要外部 HA 工具
- [[hhs/MySQL/08-工程实践/38-监控指标]] — GR 特有的监控指标