MySQL 开源主从复制实战指南(SRE 可靠性优先版)
核心原则:
- 异步复制是默认,但不是底线;
- 半同步是生产核心库的最低要求;
- 强一致场景必须上 Group Replication(开源方案)。
一、主从复制三步流程(开源环境标准实现)
步骤 1:主库将变更写入 Binary Log(Binlog)
- 关键进程:
- Binlog Dump 线程(由从库 I/O 线程连接时动态创建)
- 关键文件:
mysql-bin.000001
(Binlog 文件)mysql-bin.index
(Binlog 索引)
- 过程细节:
- 所有修改操作在 事务提交阶段,先写入 binlog(逻辑日志),再提交 InnoDB 事务(通过 两阶段提交 2PC 保证 binlog 与 redo log 一致性)。
- 关键配置(主库):
[mysqld] server-id = 1 log-bin = /var/log/mysql/mysql-bin binlog_format = ROW sync_binlog = 1 # 每次事务刷 binlog 到磁盘 innodb_flush_log_at_trx_commit = 1 # redo log 同步刷盘(“双1”保一致)
原理补充:若主库 crash,InnoDB 通过 redo log 恢复未刷盘数据,binlog 通过
sync_binlog=1
保证不丢,二者通过 2PC 对齐。
步骤 2:从库 I/O 线程复制 binlog → 写入 Relay Log
- 关键进程:
- Slave I/O Thread(从库常驻线程)
- 关键文件:
relay-log.000001
(中继日志)mysql.slave_master_info
(MySQL 5.7+,InnoDB 表存储主库连接信息)
- 过程细节:
- I/O 线程向主库请求从
MASTER_LOG_FILE
+MASTER_LOG_POS
开始的日志; - 主库 Binlog Dump 线程读取 binlog 并发送;
- I/O 线程将内容写入 relay log,并更新
slave_master_info
。
- I/O 线程向主库请求从
步骤 3:从库 SQL 线程执行 Relay Log
- 关键进程:
- Slave SQL Thread(MySQL 5.6+ 支持多线程:
slave_parallel_workers
)
- Slave SQL Thread(MySQL 5.6+ 支持多线程:
- 关键文件:
mysql.slave_relay_log_info
(记录已执行位置)
- 过程细节:
- SQL 线程顺序读取 relay log 并重放;
- 并行复制(MySQL 5.7+ 推荐):
slave_parallel_type = LOGICAL_CLOCK slave_parallel_workers = 8
二、复制架构对比(开源场景适用性)
架构 | 特点 | 适用场景 | 关键风险 |
---|---|---|---|
一主多从 | 从库直连主库 | 读写分离、备份 | 主库网络压力大 |
级联复制 | 主 → 中继 → 叶子 | 跨机房分发 | 延迟叠加,故障链长 |
多主复制(原生 Circular) | A→B, B→A | 双活写入(理论) | ❌ 无冲突检测 ❌ 主键冲突高发 ✅ 社区不推荐 → 改用 Galera Cluster |
半同步复制 | 主库等至少1从 ACK | 核心交易库 | 增加 RTT 延迟,超时降级异步 |
Group Replication(同步) | Paxos 协议多数派提交 | 金融级强一致 | 网络分区时不可用 |
术语澄清:
- “半同步” ≠ “同步”:半同步只要求 relay log 落盘,不要求 APPLY;
- 真同步 = Group Replication(MySQL 5.7.17+ 开源内置)。
三、半同步 vs 异步:优势与不足
维度 | 异步复制 | 半同步复制 |
---|---|---|
数据安全性 | 主库 crash 可能丢事务 | 至少一从有 relay log,可恢复 |
写入延迟 | 最低(主库 COMMIT 即返回) | 增加 1 RTT(等从库 ACK) |
可用性 | 高(主库独立) | 依赖从库存活(超时降级) |
配置 | 默认开启 | 需安装插件 + 配置 timeout |
适用场景 | 日志、分析库 | 订单、库存、支付等核心库 |
重要限制:
半同步 不能保证从库已执行事务,仅保证 relay log 落盘。若需“执行完成才返回”,必须用 Group Replication。