06.1 - 主从复制原理
定位:主从复制是 MySQL 高可用和数据冗余的基础——理解复制流程、线程模型和延迟根源是生产运维的核心技能 面试高频度:⭐⭐⭐⭐⭐ 考查方式:复制流程三线程、异步/半同步/组复制区别、复制延迟原因及解决方案、GTID 复制
一、这是什么?为什么需要它?
是什么
主从复制(Master-Slave Replication)是 MySQL 将主库(Master)的数据变更同步到一个或多个从库(Slave)的机制。
为什么需要主从复制?
| 场景 | 没有复制 | 有复制 |
|---|---|---|
| 主库宕机 | 服务完全中断 | 从库可以切换为主库 |
| 报表查询 | 和生产业务抢资源 | 专门用从库做报表 |
| 数据备份 | 锁表影响在线业务 | 从库备份不影响主库 |
| 读取扩展 | 单库扛不住 | 多从库分散读压力 |
核心 insight:复制解决的是 "单点故障" 和 "读写资源争抢" 两个问题。它不做数据分片(那是分库分表的事),只是把同样的数据复制到多份。
二、原理拆解
2.1 复制三线程模型
主从复制三线程架构
Master Slave
┌──────────────┐ ┌──────────────────┐
│ 事务提交 │ │ │
│ ↓ │ │ ┌────────────┐ │
│ Binlog │ ────────→│ │ IO Thread │ │
│ 文件 │ 拉取 │ └──────┬─────┘ │
│ │ Binlog │ │ │
└──────────────┘ │ ▼ │
│ ┌────────────┐ │
│ │ Relay Log │ │
│ │ (中继日志) │ │
│ └──────┬─────┘ │
│ │ │
│ ▼ │
│ ┌────────────┐ │
│ │ SQL Thread │ │
│ └──────┬─────┘ │
│ │ │
│ ▼ │
│ 数据文件 │
└──────────────────┘
三个线程:
1. Master 的 Binlog Dump Thread
└── 负责读取 Binlog 并发送给 Slave
2. Slave 的 IO Thread
└── 接收 Master 的 Binlog → 写入 Relay Log
3. Slave 的 SQL Thread
└── 读取 Relay Log → 在 Slave 上重放2.2 三种复制模式
异步复制(默认)
Master: 写入 → Binlog → 提交成功 ✅(不管 Slave)
Slave: 异步拉取 Binlog → 重放
优点: 主库性能最高(不等待从库)
缺点: 主库崩溃→从库可能缺少最后几个事务(数据丢失)半同步复制
Master: 写入 → Binlog → 等待至少 1 个 Slave 确认 → 提交成功 ✅
优点: 保证至少有一个从库收到了 Binlog
缺点: 比异步慢(多一次网络往返)
适用: 对数据一致性要求较高的场景
配置:
plugin-load=semisync_master.so;semisync_slave.so
rpl_semi_sync_master_enabled=1
rpl_semi_sync_slave_enabled=1
rpl_semi_sync_master_timeout=10000 -- 超时降级为异步 (ms)组复制 (Group Replication, MGR)
多节点写入 → Paxos 共识协议 → 多数派确认 → 提交
优点: 多主写入,自动故障检测
缺点: 性能开销大,网络要求高
适用: MySQL 8.0 InnoDB Cluster2.3 复制延迟
延迟的定义: Seconds_Behind_Master 显示从库落后主库的时间(秒)。
Master: 10:30:00 写入事务 T1
10:30:01 写入事务 T2
10:30:02 写入事务 T3(提交成功 ✅)
Slave IO Thread: 10:30:01 收到 T1(网络延时)
Slave SQL Thread: 10:30:05 重放完 T1 ← 延迟 4 秒延迟的三大原因:
| 原因 | 说明 | 解决方案 |
|---|---|---|
| SQL 线程单线程 | 主库多线程并发写入,从库 SQL 线程串行重放 | 多线程复制 MTS(slave_parallel_workers) |
| 大事务 | 一个大事务在主库执行 1s,在从库也要执行 1s | 拆分大事务,避免一次性大量操作 |
| 从库查询压力 | 从库同时服务查询,挤占重放资源 | 专用从库做复制,不对外查询 |
2.4 GTID 复制(MySQL 5.6+)
GTID = Global Transaction ID,为每个事务分配一个全局唯一 ID。
GTID = server_uuid:transaction_id
例: 3E11FA47-71CA-11E1-9E33-C80AA9429562:23
优势:
- 不需要指定 Binlog 文件名和位置
- 自动匹配事务,Slave 切换 Master 更简单
- 比对 GTID 集合可以快速发现主从差异
使用:
CHANGE MASTER TO MASTER_AUTO_POSITION=1;三、面试视角
| 追问 | 答案要点 |
|---|---|
| 主从复制三个线程分别是什么? | Master Binlog Dump Thread(发送 Binlog);Slave IO Thread(接收写 Relay Log);Slave SQL Thread(重放) |
| 异步复制和半同步复制的区别? | 异步不等待从库确认(性能好,可能丢数据),半同步等待至少一个从库确认(更安全,略慢) |
| 复制延迟怎么产生的? | 主库多线程写 vs 从库 SQL 线程单线程重放、大事务、从库查询压力 |
| 怎么解决复制延迟? | 多线程复制(MTS)、避免大事务、从库拆分(专用复制/专用查询) |
| GTID 复制的好处? | 全局唯一事务 ID,主从切换更简单,不需要手动指定 Binlog 位置 |
📚 相关链接
- Binlog 基础:**Binlog**
- 读写分离:**读写分离与分库分表**
- ← 返回 **高可用与架构索引**