MySQL 主从复制是怎么工作的?主从延迟时怎样保证读到刚写的数据?
🧑💻 面试官:MySQL 主从复制完成后,从库和主库是不是一样?
🙋♂️ 我:主库写 binlog,从库重放,所以是一样的。
🧑💻 面试官:用户刚修改昵称,马上读从库却看到旧昵称,复制哪里还没完成?
🙋♂️ 我:应该是从库还没收到日志。
🧑💻 面试官:也可能收到了却没应用。半同步复制能保证这次读取就是新值吗?
主从复制要拆成三个进度:主库已提交、从库已收到、从库已应用。用户能不能读到新值,取决于最后一个。
面试速答(60 秒版)
MySQL 常见主从复制,是主库把变更记录到 binlog,从库接收后写入 relay log,再由应用线程执行这些变更。接收和应用是两个阶段,所以从库可能落后。
异步复制不要求主库每次提交都等从库。半同步会等待配置要求数量的从库确认收到并落盘,但不等于它们已经应用事务,也就不能直接保证读后写一致性。
用户刚完成修改后必须读到新值时,简单做法是把这次相关读取路由到主库。更细的方案可以带事务位置,等待目标从库应用到该位置,再读取;等待必须有超时和回退。
排查延迟时,我会分开看接收、应用、大事务、锁等待和资源瓶颈,不只盯着一个延迟秒数。

知识点详解:收到日志,和能读到数据,是两件事
主库到从库之间还有一份中间日志
假设用户把昵称从 A 改成 B。主库提交后,它的查询可以看到 B;但从库需要再走一段流程。
主库发送 binlog;从库接收线程把事件写入 relay log;从库的应用线程或并行工作线程,再根据日志修改自己的数据。relay log 可以理解为从库已经收到、等待处理的变更记录,不是查询用的数据表。
因此网络很快也不代表复制很快。接收早已追上,应用仍可能被大事务、磁盘性能或锁等待拖住。
半同步解决的主要不是“马上读到”
半同步确认点针对日志接收及落盘,不是从库完成查询可见的数据更新。它提高故障场景下的日志保障,同时增加提交等待。
还要注意配置和运行状态:确认超时后可能退回异步模式。不能只看“开启了半同步”,就承诺任何故障下都绝不丢数据。
如果问题问的是用户读到旧昵称,核心仍然是读请求去了哪台机器,以及那台机器应用到哪里。复制保障与读取一致性不能混成一个开关。
读后写一致性,可以先从简单方案开始
对修改成功后的详情页,可以短期或针对相关请求读主库。它容易理解,但必须评估主库读取压力,而且不是“所有接口永远读主库”。
另一种做法是记录本次写入对应的 GTID 等进度标记,等选定从库执行到该进度,再发起读取。等待失败就回主库或返回明确结果。GTID 是事务身份与进度依据,不会自动把异步复制变成零延迟。
读取还要使用合适的事务视图。即使从库已经应用新事务,复用一个更早建立的一致性快照,也可能继续看到旧值。
定位延迟,要找到堵住的那一段
先检查复制连接和错误,再看接收位置与执行位置是否拉开。确认应用慢以后,检查工作线程、大事务、锁、CPU 和磁盘。
Seconds_Behind_Source 有适用条件,也可能为 NULL;它不是每笔业务写入的精确可见时间。监控应同时覆盖复制状态、队列进度和业务读写探针。
并行应用能提高吞吐,但事务依赖、提交顺序和单个大事务都会限制收益。直接增加工作线程,不一定能解决同一个热点记录造成的等待。
本题机制参考:复制线程、半同步复制、GTID 等待、复制状态。
面试官继续追问
从库适合拿来做备份吗?
可以减轻主库备份压力,但复制不是备份。误删也会复制过去,还需要保留独立备份和可验证的恢复流程。
延迟秒数是 0,就能保证刚写的数据读得到吗?
不能据此承诺。要确认本次事务的应用进度、读取目标和事务快照,指标的更新时间也存在间隔。
主库故障后随便选一台从库就行吗?
不能。要比较可用候选的事务进度,并隔离旧主库、更新路由,避免双写;不同复制和切换方案的保障不一样。
面试速记卡
- 链路:binlog → 接收 → relay log → 应用。
- 半同步:确认接收,不等于完成应用。
- 读后写:相关读取走主库,或等待具体事务进度。
- 延迟:区分网络接收慢与事务应用慢。
- 故障:复制不代替备份,也不自动完成安全切换。
公司面试真题
真题根据求职者公开面经整理,题意经过概括,非逐字原话或公司官方题库;本文为 Sunday 的独立解析。
字节跳动 · 后端(TikTok) · 日常实习
MySQL 主从如何同步,读写分离不一致怎样处理?(题意整理)
tiktok后端开发日常实习面经后续(已OC) ↗
面试记录为 2024-11-14;原帖编辑于 2024-11-16美团 · 后端(榛果民宿) · 原帖未明确批次
MySQL 读写分离如何实现,实时性读取怎样处理?(题意整理)
美团offer call还愿 ↗
历史面经;原帖编辑于 2019-09-18