Skip to content

概念卡片:MySQL 高可用与主备切换

一句话机制

MySQL 高可用 = 主备 + 故障切换(VIP 漂移);主备延迟(同一个事务在备库执行完 vs 主库执行完的时间差 T3-T1)是可用性的关键,延迟越小、切换恢复越快。切换策略有「可靠性优先」(保证一致但有不可用时间)和「可用性优先」(几乎无不可用但可能不一致),默认选可靠性优先。

主从 vs 主备

维度主从(Master-Slave)主备(Master-Standby)
流量主库写、从库读,都对外服务备库不对外,只同步待命
目标读写分离、分摊压力高可用 HA、故障切换
切换主库挂了从库不会自动变主库心跳检测 + VIP 漂移,自动切换
组件VIP + Keepalived/Heartbeat

实际常见组合:一主一备(做 HA)+ 挂几个从库(做读写分离)

主备延迟(seconds_behind_master)

T1 = 主库执行完事务写 binlog
T2 = 备库接收完 binlog
T3 = 备库执行完事务
主备延迟 = T3 - T1(备库执行完 vs 主库执行完的差值)

show slave statusseconds_behind_master(秒级)就是 T3-T1。备库会自动校准主备系统时间差,不会因时钟不同而误报。

延迟三大来源

来源原因解法
备库性能差备库用差机器/多备库挤一台对称部署(同规格)
备库压力大运营查询/分析语句跑备库,占 CPU一主多从分担,或 binlog 输出到 Hadoop
大事务一次删大量数据/大表 DDL分批删、DDL 用 gh-ost

备库并行复制能力不足(sql_thread 单线程串行重放)是第四大来源,5.7 起用并行复制(按库/组提交)加速。

切换策略

可靠性优先(默认推荐)

5 步流程,有不可用时间(步骤 2-5 之间主备都只读):

1. 判断备库 seconds_behind_master < 阈值(如 5s),否则重试
2. 主库设为 readonly
3. 等备库 seconds_behind_master 降为 0
4. 备库设为可读写
5. 业务流量切到备库

不可用时间主要耗在步骤 3(等同步),可能几秒。所以步骤 1 要先确认延迟足够小,否则切换后系统会长时间不可用。

可用性优先

把步骤 4、5 提前(不等同步直接切),几乎 0 不可用,但可能数据不一致

经典不一致例子:主库插入 c=4 后切换,备库没同步到 c=4 就接收客户端 c=5 → 主库多出 (5,4)、备库多出 (5,5),两边数据漂移。

⚠️ row 格式能「更早暴露」不一致:row 记录完整行数据,重放时撞主键冲突会报 duplicate key error 停止;而 statement/mixed 会「悄悄」不一致、事后难查。这也是推荐 row 的又一理由。

怎么选

策略一致性可用性适用
可靠性优先✅ 保证有短暂不可用绝大多数业务(数据准确是底线)
可用性优先❌ 可能不一致✅ 几乎无不可用操作日志等可事后修补、且业务强依赖写入的场景

常见误解(避坑)

  1. ❌ "主库挂了从库会自动接管"。→ 主从架构从库不会自动变主库;要 VIP + Keepalived 等 HA 组件才自动切换。
  2. ❌ "切换就是无脑把流量切过去"。→ 可靠性优先要先等备库追平延迟,否则切换后数据丢失/长时间不可用。
  3. ❌ "可用性优先只是快一点"。→ 代价是数据不一致,且 statement/mixed 下不一致会悄悄发生、难以发现。
  4. ❌ "备库延迟只能靠换好机器"。→ 大事务(一次删大量数据)是常见人为来源,分批删 + DDL 用 gh-ost 更关键。

关联

最近更新