Skip to content

单机 MySQL 扛不住、也怕宕机,怎么办?—— 主从复制与高可用 ​

属于 S1 MySQL 深入 · 深入篇第五篇 上一篇:慢查询优化实战 下一篇:面试题集

前面三篇讲的都是"单机怎么把查询和事务做好"。但生产环境有两个绕不开的问题:读压力太大(一台机器扛不住所有查询),以及怕宕机(主库一挂,服务全停)。主从复制 + 高可用方案,就是为这两个问题而生的。

主从复制:让从库分担读、备份数据 ​

主从复制的基本形态是"一主多从":主库负责写,从库负责读和备份。它的原理一句话:把主库的变更日志(binlog)搬到从库,重放一遍。

具体有三个线程在协作:

text
主库 binlog dump 线程 ──推 binlog──▶ 从库 I/O 线程 ──写 relay log──▶ 从库 SQL 线程 ──回放──▶ 从库数据
  • 主库的 dump 线程把 binlog 事件推给从库
  • 从库的 I/O 线程接收并写进本地的中继日志(relay log)
  • 从库的 SQL 线程读 relay log,把变更应用到数据上

binlog 有三种格式:statement(记 SQL 语句,日志小但可能主从不一致)、row(记行变更前后值,一致性强、日志大,是默认)、mixed(折中)。

异步 vs 半同步:要快还是要稳 ​

默认是异步复制:主库写完 binlog 就返回客户端,不等等从库。优点是快,缺点是主库宕机时,刚提交的数据可能还没同步到从库,就丢了。

半同步复制(semi-sync)是折中:主库提交后等至少一个从库确认收到 binlog 才返回。降低了丢失窗口,代价是提交延迟变大。注意一个细节:如果等待超时,半同步会退化成异步——优先保证可用性,而不是卡死。

这里要厘清一个常被问混的点:半同步解决的是"丢数据",不是"主从延迟"。它只是保证"至少一台从库有数据",从库什么时候追上、延迟多大,它不管。

主从延迟:为什么从库总慢半拍 ​

从库延迟是主从架构最常见的毛病。根因在于:主库是多线程并发写,而从库的 SQL 线程是单线程回放,天然追不上。再加上大事务、无主键表(row 格式下无主键回放要全表扫)等因素,延迟就更严重。

应对手段:开并行复制(多线程回放)、拆小事务、表都加主键、读延迟敏感的业务强制走主库。监控上就看 SHOW SLAVE STATUS 里的 Seconds_Behind_Master。

读写分离带来的一个业务问题是"写后立刻读,读到旧数据"——因为从库还没同步。解决办法是:关键业务(下单后查订单)走主库,能容忍延迟的走从库。

主库挂了怎么办:高可用方案 ​

主从复制解决了"读压力"和"数据备份",但"主库宕机自动切换"要靠额外的高可用方案。常见的有:

方案原理特点
MHA监控主库,宕机后把某从库提升为主传统外挂式,需脚本切换
Orchestrator拓扑管理 + 自动故障转移更智能的拓扑感知
MGR(组复制)基于共识的多主/单主复制官方内置,数据强一致

理解时抓核心区别:MHA/Orchestrator 是"外挂"的故障转移工具,MGR 是"内置共识"的复制机制。面试说到概念级即可,但要把这个区别讲清楚。


串起来 ​

单机的两个痛点——读压力和宕机风险,分别由"主从复制"和"高可用方案"来解决:主从复制靠 binlog 搬运 + 三线程重放实现读写分离和数据冗余,半同步在"快"和"不丢"之间折中,主从延迟是单线程回放的代价,高可用靠 MHA/MGR 等实现故障自动切换。

到这里,MySQL 的存储、事务、索引、高可用四块就串成了一条完整的线。下一篇是面试题集,用六个高频问题把这些知识点收口,练到能连续回答三层追问。

持续学习,持续构建。