**主从复制(Master-Slave Replication)**指的是:把一台主库(Master / Primary)的数据变更,异步或半同步地复制到一个或多个从库(Slave / Replica),让从库尽量保持与主库一致的数据状态。
下面按“是什么 → 为什么 → 怎么做 → 常见问题”来讲。
一、主从复制是什么?
核心特征只有一句话:
主库负责写,从库负责读;主库把数据变更日志发给从库重放。
典型结构:
应用写入
↓
[主库 Master]
↓ ↓ ↓
[从库] [从库] [从库]
↑ ↑
应用读取
关键点:
- 写请求:只走主库(INSERT/UPDATE/DELETE)
- 读请求:可分摊到多个从库(SELECT)
- 复制内容:通常是 binlog / WAL / redo log,而不是整表拷贝
二、为什么要做主从复制?
常见目标有 5 个:
| 目的 | 说明 |
|---|---|
| 读写分离 | 写走主库,读走从库,减轻主库压力 |
| 高可用 & 容灾 | 主库宕机时可提升一个从库为新主库 |
| 数据备份 | 从库本身就是一份“热备”,不影响主库性能 |
| 数据分析 | 报表、BI、离线分析直接连从库,不干扰线上业务 |
| 就近访问 | 异地部署从库,降低跨地域访问延迟 |
三、主从复制的基本流程(以 MySQL 为例)
MySQL 是最典型的主从复制实现,流程如下:
1. 主库做的事情
- 客户端执行写操作
- 主库将数据变更记录到 Binary Log(binlog)
- binlog 按顺序落盘
2. 从库做的事情
- IO 线程:连接主库,拉取 binlog,写入本地 Relay Log
- SQL 线程:读取 Relay Log,重放 SQL,更新从库数据
简化流程:
主库: 写数据 → 写 binlog
↓
从库: IO线程拉binlog → relay log → SQL线程重放 → 更新数据
四、复制模式:异步 / 半同步 / 全同步
1. 异步复制(最常见)
- 主库写完 binlog 就返回给客户端
- 不等待从库确认
- ✅ 性能好
- ❌ 可能丢数据(主库宕机,从库还没收到)
2. 半同步复制
- 主库至少等 一个从库 收到 binlog 才提交
- 平衡性能和安全性
- MySQL / MariaDB 都支持
3. 全同步复制
- 所有从库都确认收到后才提交
- ✅ 强一致性
- ❌ 延迟高,吞吐量低
- 常见于金融级场景(如 MySQL Group Replication、Galera Cluster)
五、主从复制的常见拓扑
| 拓扑 | 说明 |
|---|---|
| 一主一从 | 最简单,适合小业务 |
| 一主多从 | 最常用,适合读写分离 |
| 级联复制 | 主 → 从A → 从B,减少主库压力 |
| 双主复制 | 两个节点互为主从,风险高,需谨慎 |
| 多源复制 | 一个从库同时从多个主库复制(汇总数据) |
六、典型问题与注意事项
1. 主从延迟(Replication Lag)
- 从库落后主库几秒甚至几分钟
- 原因:大事务、慢 SQL、从库性能差、网络抖动
- 后果:读到旧数据
应对:
- 监控
Seconds_Behind_Master - 拆分大事务
- 提升从库硬件
- 对一致性要求高的读,强制走主库
2. 数据不一致
- 从库误写、复制中断、binlog 损坏
- 解决方案:
- 从库设为
read-only - 定期校验数据一致性(如
pt-table-checksum)
- 从库设为
3. 主库单点故障
- 主库挂了,系统不可写
- 解决:
- 配合 MHA / Orchestrator / Keepalived / VIP
- 自动或手动提升从库为主库
4. 主键冲突 / 自增 ID 问题
- 多主写入时容易出问题
- 常见做法:
- 设置不同
auto_increment_offset - 使用雪花算法等分布式 ID
- 设置不同
七、与其他概念的关系
| 概念 | 关系 |
|---|---|
| 读写分离 | 主从复制是实现基础 |
| 高可用(HA) | 主从 + 故障切换 = HA |
| 分库分表 | 常与主从结合,先分片再复制 |
| CAP | 主从复制通常偏向 AP(可用性 + 分区容忍) |
八、一句话总结
主从复制是数据库通过日志同步,实现一份数据多副本、读写分离和高可用的基础机制,但会引入主从延迟和一致性挑战。