Skip to content
MySQL 事务、锁与高可用 · 第 4 篇 / 共 6 篇
领域数据与中间件
专题MySQL 专题
当前序列MySQL 事务、锁与高可用
阅读位置第 4 篇 / 共 6 篇当前专题第 2 个序列 / 共 7 个序列

MySQL 主从复制与读写分离:延迟、数据一致性和故障切换怎么理解

很多系统数据库一上量,第一反应就是:

  • 能不能把读流量拆出去

这时通常就会引入:

  • 主从复制
  • 读写分离

但如果只记住“主写从读”,后面很快就会遇到麻烦:

  • 刚写完为什么从库查不到
  • 延迟高时业务为什么出错
  • 切换故障后为什么数据边界不一致

先说结论

主从复制和读写分离主要解决的是:

  • 读压力扩展
  • 备份与高可用基础

它不能自动解决:

  • 强一致读
  • 所有故障切换问题

真正最需要提前想清楚的是:

  • 复制延迟能不能接受
  • 哪些读必须回主库

以及更重要的一句:

  • 读写分离解决的是“扩读”,不是“自动强一致”

一、为什么要做主从复制

常见目的包括:

  • 分摊查询压力
  • 提供只读副本
  • 为高可用和备份打基础

尤其是读多写少系统,读写分离带来的收益会比较明显。

二、主从复制怎么粗略理解

可以先非常粗略地理解成:

  • 主库负责写入
  • 主库的变更通过 binlog 传播
  • 从库重放变更,追上主库状态

这意味着一个非常关键的事实:

  • 主从之间天然可能存在时间差

这就是复制延迟问题的根源。

在 MySQL 里,这条链通常可以理解为:

  • 主库写入事务
  • binlog 落地
  • 从库拉取 binlog
  • 从库重放 relay log

只要中间任一环节慢了,延迟就会出现。

三、为什么读写分离最怕延迟

典型场景:

  1. 用户刚写入一条订单
  2. 立即查询详情
  3. 查询被路由到了从库
  4. 从库还没追上

结果就是:

  • 明明写成功了,但立刻查不到

这不是程序“随机故障”,而是读写分离天然的最终一致性边界。

这类问题通常叫:

  • 写后读不一致

它不是 bug,而是架构天然约束。

四、哪些场景更适合读写分离

比较适合:

  • 读远大于写
  • 对短暂延迟容忍度较高
  • 报表、列表、检索类查询多

不太适合直接全量分离:

  • 下单后立即查结果
  • 强实时账户余额类查询
  • 强一致状态确认

再补一句更现实的话:

  • 列表页、报表页、搜索页更适合走从库
  • 提交结果页、支付状态页、库存确认页更适合回主库

五、哪些读应该强制回主库

非常值得单独标记的通常有:

  • 写后立刻读
  • 事务内读
  • 关键状态确认读

也就是说,读写分离一般不是“所有读都扔从库”,而是:

  • 有选择地分离

一个实用判断是:

  • 只要这次查询结果会直接影响用户下一步决策,通常就别轻易走从库

六、复制延迟为什么会突然变大

线上复制延迟经常不是一直高,而是某个时间点突然被放大。
常见原因包括:

  • 主库大事务或批量更新
  • 从库本身查询负载太高
  • 从库磁盘 IO 跟不上
  • DDL、索引变更、归档任务占用资源

所以延迟问题不能只从“网络慢”去想。

七、主从复制还会带来哪些问题

1. 延迟放大

高峰期写入量大、从库负载高时,延迟会明显放大。

2. 切换复杂度

主库故障切换时,不只是地址变更问题,还涉及:

  • 数据追平
  • 新主库确认
  • 应用路由切换

3. 查询路由复杂度增加

业务层要考虑:

  • 这次读该去哪
  • 是否允许读旧数据

4. 从库不只是“读库”,也是故障切换候选

从库平时状态是否健康,会直接影响后续切主质量。
复制长期落后、磁盘空间不足、只读负载过高,都会让切换风险变大。

八、一个更实际的使用原则

1. 先把主从复制当成扩展读能力和高可用基础

不要一开始就假设它能承载所有一致性需求。

2. 对关键读场景做主库兜底

特别是写后立刻读。

3. 持续监控复制延迟

否则你只是“用了主从”,但并不知道它是不是已经影响业务。

4. 把读写路由策略产品化

不要在业务代码里到处手写“这个查询走主、那个查询走从”。
最好通过统一的数据源层、注解或路由规则来治理。

一句话总结

MySQL 主从复制和读写分离的核心价值,在于扩展读能力,而不在于替你自动实现强一致。

只要系统还存在复制延迟,你就必须明确区分:

  • 哪些读可以接受旧数据
  • 哪些读必须回主库
延伸阅读相关文章优先当前专题,再补跨专题关联。
同一序列 · 顺着当前主线继续读主从延迟出现时业务应该怎么兜底适合把事务锁、死锁、主从复制、写后读一致性和切换治理串起来看。MySQL 专题 · MySQL 事务、锁与高可用同一序列 · 顺着当前主线继续读MySQL 主从切换检查清单适合把事务锁、死锁、主从复制、写后读一致性和切换治理串起来看。MySQL 专题 · MySQL 事务、锁与高可用同专题其他序列 · MySQL 变更与运维治理大表在线 DDL 怎么做更稳适合把计数、日志、在线变更和归档清理放在一起看。MySQL 专题 · MySQL 变更与运维治理同专题其他序列 · MySQL 变更治理与数据生命周期大事务为什么会拖垮数据库适合把大事务、DDL、回填、慢 SQL 治理和归档分层放进一条持续治理主线上看。MySQL 专题 · MySQL 变更治理与数据生命周期跨专题关联 · 同场景:基础学习@Conditional 系列注解怎么配合使用适合把自动装配、条件装配、Profile 和循环依赖放回 Spring Boot 启动过程里理解。Spring 专题 · Spring Boot 启动、装配与配置跨专题关联 · 同场景:基础学习保留策略和日志压缩适合哪些场景适合把副本机制、acks、批量压缩和日志组织放在一条 Kafka 投递主线上理解。Kafka 专题 · Kafka 投递链路与日志存储机制
继续阅读MySQL 事务、锁与高可用当前序列第 4 篇 / 共 6 篇当前专题第 2 个序列 / 共 7 个序列
往前看
上一篇MySQL 常见连接与包大小错误排查回到当前序列上一章上一序列MySQL 建模与查询优化从第 1 篇开始:MySQL 字段类型怎么选
往后看
下一篇主从延迟出现时业务应该怎么兜底继续当前序列下一章下一序列MySQL 存储引擎与执行细节从第 1 篇开始:MVCC 和 Read View 怎么理解

把零散经验整理成可查、可复用、可持续更新的企业级知识门户