主从复制不是简单复制数据文件,而是复制已经提交的变更事件。源库写 binlog,副本拉取后写 relay log,再由 SQL 应用线程重放,这条链路上每一段都有自己的边界。
理解复制,不能只停在“主库写、从库同步”。真正要看的,是 binlog 格式、GTID、relay log、应用线程和切换边界如何共同决定延迟、一致性和恢复能力。
先把机制边界说清楚
MySQL 复制的核心是把源库已经提交的变更记录到 binlog,再由副本拉取并写入 relay log,最后由 SQL 应用线程在副本上重放。它复制的是变更事件,不是简单复制数据文件。
整体路径
上面这张图先看粗线条:宏观上,复制链路有三段:源库事务提交时写 binlog;副本 I/O 线程从源库读取 binlog 并落到 relay log;副本 SQL 线程或多线程 applier 按顺序应用事件。任何一段慢下来,都会表现为复制延迟或断链。
底层流程
底层拆解先看数据结构。「主从复制」至少涉及下面几类结构:
- binlog:源库提交后的逻辑变更日志,也是复制的源头。
- relay log:副本本地保存的待应用日志。
- GTID:全局事务标识,用来描述事务复制进度和断点。
- applier worker:副本上真正执行复制事件的线程。
再看完整执行流程:
- 源库事务提交,按一致性要求写入 binlog。
- dump 线程把 binlog 事件发送给副本。
- 副本 I/O 线程接收事件并写入 relay log。
- SQL coordinator 分发事件给应用线程。
- 副本重放事件,更新复制元数据和 GTID 集合。
复制有三种模式,这是复制章节的骨架,必须能说清区别:异步复制(默认)——主库提交事务后不等从库确认就返回,延迟最低但主库宕机可能丢已提交未同步的事务;半同步复制(semi-sync)——主库提交后要至少等一个从库确认收到 binlog(rpl_semi_sync_master_wait_for_slave_count 默认 1)才返回,更安全但有等待开销;全同步复制——主库等所有从库都应用完成才返回,一致性最强但性能代价极大,实际极少用,强一致场景更多走组复制(MGR)。半同步有一个关键行为:等待从库 ACK 有超时,由 rpl_semi_sync_master_timeout 控制(默认 10000 毫秒,即 10 秒),超时后会自动降级回异步复制——所以半同步不是绝对保证,而是「在超时窗口内保证至少一个从库收到了 binlog」。三线程模型也要记牢:主库的 Binlog Dump 线程负责推送 binlog,从库的 I/O 线程负责接收并写 relay log,从库的 SQL 线程(8.0 多线程下是 coordinator + worker)负责重放。binlog 还有三种格式需要区分:STATEMENT(记录 SQL,紧凑但含 UUID()/RAND() 等非确定函数时不安全)、ROW(8.0 默认,记录行变更,严格但体积大)、MIXED。
取舍与边界
版本差异上,MySQL 5.7 已经具备较成熟的 GTID 和多线程复制能力。MySQL 8.0 在复制元数据表、并行复制、崩溃恢复、源/副本术语和可观测性上继续增强,但异步复制的基本语义仍然是先提交源库,再由副本追赶。
主从复制的短板是它默认不提供强一致读。源库提交成功不代表副本马上可见;大事务、DDL、网络抖动、从库慢 SQL 都可能拉开差距。切主时如果没有明确的 GTID 边界和数据校验,还可能把隐性不一致带到新拓扑。
典型问题:用机制化例子排查
读写分离问题要先承认复制是异步链路。写入在主库提交,不等于副本已经重放完成;一致性敏感的读请求,必须有主库读、等待位点或降级策略。
可以落到这些动作:
- 按一致性要求划分读请求,写后读、支付状态和库存确认优先走主库或等待复制位点。
- 启用 GTID 管理复制拓扑,降低断点续传和故障切换复杂度。
- 复制链路同时监控 IO 线程、SQL 应用线程和 relay log 积压。
- 大事务和 DDL 避免直接冲击复制链路,必要时拆批或低峰执行。
收束:复制不是透明缓存
主从复制不是一个透明缓存层,而是一条异步日志回放链路。架构上要先定义一致性边界,再谈读写分离收益。
关于十三Tech
我是十三,All in AI Agent 方向的架构师,专注 AI 工程实践。
我相信 AI 是程序员的最佳搭档,也希望帮助每一位开发者更好地驾驭 AI。
如果你想继续跟完这套「图解 MySQL」,欢迎关注公众号 「十三Tech」。后续会继续按机制、图解和实战排查这条线更新。

