400-920-5594
173-6014-8050
首页 > 资讯中心 > 技术分享
数据库读写分离与主从延迟治理复盘:刚写入就读不到、读到旧数据、路由错表的生产级方案
2026-09-29 33 技术分享

成都软件开发

  随着业务增长,单库 CPU、连接数被读请求占满,把读压力分流到多个从库的读写分离成了标配。理论上主库写、从库读,既能分担压力又能提升读性能。但上线后用户最常投诉的是:刚下单完跳转到列表页,订单不见了;支付完刷新页面,状态还是待支付;或者某些查询莫名其妙连到了主库,拖慢了写。

  这些问题的根源,不是读写分离"不好用",而是主从复制本身有延迟、路由策略没区分业务场景。主库写入后数据要经过复制才能到从库,这段时间差内读从库就读到旧数据。本文讲清楚主从延迟从哪来、怎么识别和治理、哪些读必须走主库。

一、读写分离高频踩坑场景

1. 主从延迟,刚写完就读到旧数据

  主库提交事务后,binlog 要传到从库、重放后才能查到。正常情况下延迟可能是毫秒到秒级,但大事务、批量更新、网络抖动时延迟可能拉到几秒甚至更久。用户"写后立刻读"的请求被路由到从库,就读到了旧数据,表现为数据"丢失"。

2. 大事务与批量更新放大延迟

  一次性批量更新大量数据、跑长事务,会堵住从库的重放线程,导致后续所有写入都延迟,所有读从库的请求都读到旧数据。这类问题在夜间批处理、数据订正时最容易发生。

3. 路由策略粗暴,读请求乱走

  不区分业务一律把 SELECT 打从库,把写后读、强一致读也分到从库;或者事务内的读请求因为连接没绑定主库而跑到从库,导致同一个事务里前后读到不一致数据。

4. 主库故障切换后连接没切回来

  主库宕机提升从库为新主库后,应用侧的数据源、读写路由没自动更新,或者旧连接还指向旧主,导致写失败、读乱路由。高可用切换没有和应用侧联动,等于高可用没闭环。

二、主从延迟的识别与监控

成都软件开发

1. 持续监控从库延迟

  把主从延迟(Seconds_Behind_Master 或对应指标)作为核心监控项,设置阈值告警。延迟超过业务可接受范围时,要有应对手段,而不是等用户投诉才发现。

SHOW REPLICA STATUS\G
-- 重点关注:
-- Seconds_Behind_Source:从库延迟秒数
-- Replica_IO_Running / Replica_SQL_Running:复制线程是否正常

2. 定位延迟来源

  延迟高时先看是不是大事务、批量更新堵住了重放;再看从库自身性能(IO、CPU、磁盘)是否扛不住;网络带宽不足也会让 binlog 传输变慢。对症下药,而不是盲目加从库。

3. 避免大事务

  把大批量更新拆成小批次、小事务执行,避免单个事务长时间占用从库重放;核心业务的关键写操作避开与批处理同时进行,减少延迟峰值。

三、读请求路由策略

成都软件开发

1. 写后读强制走主库

  对于"刚写完就要读"的场景(下单后看订单、支付后看状态),必须在一段时间内强制走主库,或由业务层判断该请求是否属于写后读,直接路由主库,避免读到旧数据。

@Transactional
public void placeOrder(OrderRequest req) {
    orderMapper.insert(req);
    // 标记后续读请求强制走主库
    DbContext.forceMaster();
}
// 查询时判断:若本线程标记走主库,则路由主库
public Order queryOrder(Long orderId) {
    if (DbContext.isForceMaster()) {
        return masterDao.selectById(orderId);
    }
    return slaveDao.selectById(orderId);
}

2. 事务内读走主库

  一个事务里的多次读必须在同一个数据源、且保证读到自己刚写的数据,因此事务内的读应路由主库,避免跨库、跨主从不一致。

3. 按业务一致性要求分级

  强一致、写后读、事务内读走主库;普通列表、报表、搜索等可容忍短暂延迟的读走从库。不要"一刀切全部走从库",按业务对一致性的真实要求分级路由。

四、从库选型与高可用切换

成都软件开发

1. 从库按读负载分担

  多个从库之间做负载均衡,把读请求均匀分散;报表、后台查询这类重读负载,尽量用独立从库,避免和在线业务读争抢资源。

2. 故障切换与应用联动

  主从高可用切换时,应用侧要能感知新主库地址,通过配置中心、服务发现或数据库代理自动更新数据源,避免切换后应用仍指向旧主。数据库代理层(如统一中间件)能屏蔽主从拓扑变化,减少应用侧改造。

3. 定期演练主从切换

  主从切换流程要定期演练,确认应用数据源能正确切到新主、写不中断、读路由正常,真正故障发生时才不会手忙脚乱。

五、总结

  读写分离带来的"读到旧数据"问题,本质是主从复制延迟和路由策略共同造成的。核心可以归纳为:持续监控主从延迟并设置告警,用小事务、分批更新避免大事务堵重放;写后读、事务内读强制走主库,普通读才走从库;多从库分担读负载,重读用独立从库;主从切换要和应用数据源联动并定期演练。读写分离不是"配好主从就完事",把延迟治理和路由分级做好,才能既分担压力,又不让用户读到旧数据。

推荐文章查看更多》