MySQL 主从复制
主从复制是商业系统里非常常见的数据库架构能力。它的目标不是让单个 SQL 更快,而是提升读能力、可用性和数据安全。
一句话理解:
主库负责写入并记录 binlog,从库拉取并重放 binlog,最终让从库数据追上主库。
为什么需要主从复制
| 场景 | 主从复制的作用 |
|---|---|
| 读多写少 | 从库分担读查询 |
| 备份 | 从库可用于备份,降低主库压力 |
| 高可用 | 主库故障时可以切换从库 |
| 数据分析 | 报表查询放从库,避免影响主库 |
但主从复制不等于强一致。默认情况下,从库可能落后主库。
复制流程
mermaid
sequenceDiagram
participant M as 主库
participant B as binlog
participant R as 从库 IO 线程
participant L as relay log
participant S as 从库 SQL 线程
M->>B: 写入 binlog
R->>M: 拉取 binlog
R->>L: 写入 relay log
S->>L: 读取 relay log
S->>S: 重放 SQL 或行事件核心组件:
| 组件 | 作用 |
|---|---|
binlog | 主库记录数据变更 |
| IO 线程 | 从主库拉取 binlog |
| relay log | 从库本地中继日志 |
| SQL 线程 | 重放 relay log 中的事件 |
binlog 格式
| 格式 | 含义 | 特点 |
|---|---|---|
| Statement | 记录 SQL | 日志小,但某些函数和不确定 SQL 风险高 |
| Row | 记录行变更 | 更准确,日志可能更大 |
| Mixed | 混合模式 | MySQL 根据场景选择 |
商业项目通常更推荐 Row,因为复制结果更确定,也方便基于 binlog 做数据同步。
主从延迟
主从延迟是指从库还没重放到主库最新位置。
mermaid
flowchart TD
A["主库提交事务"] --> B["binlog 写入"]
B --> C["从库拉取"]
C --> D["从库重放"]
D --> E{"是否追上主库"}
E -- "否" --> F["产生主从延迟"]
E -- "是" --> G["数据基本一致"]常见原因:
| 原因 | 说明 |
|---|---|
| 主库写入太快 | 从库重放速度跟不上 |
| 大事务 | 一个事务很大,从库重放耗时长 |
| 从库机器弱 | CPU、IO、内存不足 |
| 从库有慢 SQL | 报表查询占用资源 |
| 网络问题 | binlog 拉取变慢 |
读写分离的坑
用户刚下单,马上查订单:
mermaid
sequenceDiagram
participant App as 应用
participant M as 主库
participant S as 从库
App->>M: 写入订单
M-->>App: 提交成功
App->>S: 查询订单
S-->>App: 查不到原因:从库还没追上主库。
解决方案:
- 写后短时间读主库。
- 对强一致接口读主库。
- 根据主从延迟动态切换。
- 使用缓存或业务状态避免立即读从库。
GTID
GTID 是全局事务 ID,用于标识每个事务。它让复制定位和故障切换更方便。
传统复制要关注 binlog 文件名和位置:
text
mysql-bin.000010:123456GTID 复制关注事务 ID 集合,更适合自动化运维。
商业场景
订单系统常见策略:
| 请求 | 推荐库 |
|---|---|
| 创建订单 | 主库 |
| 支付回调更新状态 | 主库 |
| 用户刚支付后查看结果 | 主库或缓存 |
| 历史订单列表 | 可读从库 |
| 后台报表 | 独立从库或数仓 |
不要把所有读都打到从库。强一致读、写后读、支付结果查询等场景应谨慎。
排查主从延迟
常用方向:
sql
show slave status\G
-- 新版本可能使用
show replica status\G关注:
| 字段 | 含义 |
|---|---|
Seconds_Behind_Master | 从库落后主库的估算秒数 |
Slave_IO_Running | IO 线程是否正常 |
Slave_SQL_Running | SQL 线程是否正常 |
Last_Error | 最近复制错误 |
面试标准回答
text
MySQL 主从复制的核心是主库写 binlog,从库 IO 线程拉取 binlog 写入 relay log,从库 SQL 线程再重放 relay log。它可以用于读写分离、备份、高可用和报表隔离。binlog 常见格式有 Statement、Row、Mixed,商业项目通常更偏向 Row,因为复制结果更确定。主从复制默认是异步或半同步思路,所以可能存在主从延迟。写后立刻读从库可能查不到刚写入的数据,强一致读应该走主库或做读写路由控制。主从延迟常见原因包括大事务、主库写入高峰、从库资源不足、慢查询和网络问题。关联学习:redo log 与 binlog、事务、优化相关。
