人人都会AI编程

20.1 主从切换方案:MHA、Keepalived + VIP

更新时间:2026-07-11

主从复制解决了数据冗余和读写分离的问题,但它本身不包含故障自动切换能力。当主库宕机时,必须有机制能快速、准确地将一个从库提升为新的主库,并让应用层感知到这一变化,否则服务将中断。本节介绍的 MHA 和 Keepalived + VIP 是两种经典的主从切换方案,分别适用于注重数据完整性和追求极简部署的不同场景。

20.1.1 主从切换要解决的核心问题

在讨论具体方案之前,先明确一个合格的主从切换方案必须处理的几个关键点:

  • 故障发现:如何判断主库真的挂了,而不是短暂网络抖动?
  • 选主决策:多个从库中选哪一个成为新主库?要保证它的数据最新、延迟最小。
  • 数据补齐:旧主库上已提交但还没来得及传给从库的数据怎么办?不能丢掉已提交的事务。
  • 拓扑变更:其他从库如何自动指向新主库继续复制?
  • 应用路由切换:应用如何尽快连接到新主库,避免长时间的写入中断?

接下来我们看看两种经典方案如何解决这些问题。

20.1.2 MHA(Master High Availability)

MHA 是 MySQL 生态中久经考验的高可用切换工具,由日本开发者 Yoshinori Matsunobu 创建,目前由社区和多家公司维护。它的核心思路是:尽可能利用故障主库的 Binlog 来补齐所有从库的数据差异,然后选择最合适的从库提升为主,确保数据零丢失或接近零丢失

架构组成

MHA 由两个组件构成:

  • MHA Manager(管理节点):负责监控主库、检测故障、调度切换流程。通常部署在一台独立的中控机上,可以用 masterha_manager 命令启动监控进程。
  • MHA Node(数据节点):安装在每一台 MySQL 服务器上,Manager 通过 Node 来执行具体任务,如保存 Binlog、应用差异日志、提升从库等。

监控时,Manager 通过周期性执行探测脚本(如 pingmysqladmin ping)来判断主库是否存活,一般配合 secondary_check_script 做二次确认,避免误判。

切换流程(以经典模式为例)

  1. 主库宕机检测:Manager 多次探测均无法连接主库,确认需进行切换。
  2. 候选主库选择:Manager 从所有从库中根据 SHOW SLAVE STATUS 选出同步位点最新、中继日志最全的一个作为新主库。
  3. 数据补全:Manager 尝试 SSH 到故障主库保存 Binlog 文件(如果还能访问),并将其中的差异部分传给新主库,尽量补齐其他从库的同步日志,避免丢失。
  • 如果故障主库完全不可访问,则只能依赖从库已有的中继日志,此时可能丢失少量数据(取决于半同步复制等配置)。
  1. 提升从库为主库:在新主库上执行 STOP SLAVE 以及 RESET SLAVE ALL,使其变为独立主库,并生成新的 Binlog。
  2. 重定向其他从库:Manager 自动在其他从库上执行 CHANGE MASTER TO 指向新主库,并启动复制。
  3. VIP 切换或应用路由变更:旧主库的虚拟 IP 被漂移到新主库(如果配合使用 VIP 脚本),或者通过修改中间件配置(如 ProxySQL)完成应用流量的切换。

整个过程通常可在几十秒内完成,且 MHA 支持在线切换(主库还在线但计划性维护)和故障切换两种模式。在线切换可以做到平滑、无数据丢失且极短时间中断。

实际部署要点

  • SSH 免密信任:Manager 需要能 SSH 到所有数据库节点执行命令,且 MHA Node 之间需要能 SCP 传输 Binlog 文件。
  • 完善的监控脚本masterha_check_repl 可检查复制环境是否健康,masterha_check_ssh 检查 SSH 连通性。
  • Binlog 备份:MHA 依赖故障主库的 Binlog,平时应确保 Binlog 不会过早被清理,最好配合定期备份或 Binlog Server。
  • 至少一主两从:为了确保切换后仍能正常复制,推荐至少部署一台主库加两台从库。
  • 避免脑裂:MHA 自身会尝试在旧主库恢复后阻止其继续作为主库运行(通过对业务用户加锁等),但生产环境最好配合幂等脚本或 STONITH 机制。

优缺点总结

  • 优点:开源成熟、切换速度快、可做到极高程度的数据完整性;支持复杂拓扑(多级复制);提供在线切换能力。
  • 缺点:部署和维护稍复杂,依赖 SSH 和 Perl 环境,对有大量从库的场景 Manager 压力较大;需要额外中控机。

20.1.3 Keepalived + VIP

Keepalived 是 Linux 下实现 VRRP(虚拟路由冗余协议)的服务软件,它不是为 MySQL 专门设计的,但通过将 MySQL 主库绑定到一个虚拟 IP 上,可以实现简单的主备自动切换。这条方案的核心思想是:两台 MySQL 服务器之间用 VIP 对外提供单一入口,主库持有 VIP,备库检测到主库挂了就抢占 VIP,应用始终连接 VIP 即可

架构与原理

典型配置如下:两台 MySQL 服务器(一主一备或互为热备),每台安装 Keepalived 并配置同一个 VIP。Keepalived 通过心跳检测彼此状态:

  • 正常情况下,主库运行 Keepalived Master 实例,持有 VIP,应用通过 VIP 访问主库。
  • 主库宕机或 Keepalived 进程异常时,备库上的 Keepalived Backup 实例检测不到 Master 的 VRRP 广告包,自动提升为 Master 并绑定 VIP。
  • 应用无需修改连接地址,只要 VIP 正常可达,就自动连上新的主库。

为了防止两个节点同时绑定 VIP 造成脑裂,Keepalived 通常要配合健康检查脚本来精确判断 MySQL 的实际状态。脚本可以是一段简单的 Shell,例如:

#!/bin/bash
—检查 MySQL 是否存活
mysqladmin -uroot -p123456 ping 2>/dev/null || systemctl stop keepalived

当 MySQL 服务异常时,脚本主动停掉本机 Keepalived,迫使 VIP 迅速释放并飘移到备库。

常见部署模式

  1. 主备模式 + 异步复制:主库写,备库作为只读备机。发生切换时,旧主库的 VIP 漂到备库,备库提升为可写。但由于异步复制,可能会丢失已提交的事务。
  2. 主备模式 + 半同步复制:在事务提交时确保至少一台从库收到 Binlog,可大幅降低数据丢失风险,但会增加主库提交延迟。
  3. 双主模式(慎用):两台 MySQL 互为主从,都可写,通过 VIP 只让一个提供服务。双主配置复杂,易产生数据冲突,一般只建议在有丰富维护经验时才采用。

实际部署要点

  • 健康检查脚本必须可靠:不仅要检测 MySQL 进程,最好还能验证是否能正常执行查询,防止出现进程在但数据库已经僵死的情况。
  • 同网段 VIP:VIP 必须在两台服务器所在的同一子网内,否则无法漂移。
  • 避免脑裂:确保网络分区时只有一端能持有 VIP,例如配合 notify_master 脚本尝试远程关闭对端节点,或使用仲裁 IP 检测。
  • 应用重连机制:客户端在 VIP 漂移后可能会报连接断开,需要应用层或连接池有重连逻辑,建议配置合理的超时和重试。
  • 监控和告警:切换前后需要记录日志并发送告警,以便运维人员介入处理后的同步关系重建。

优缺点总结

  • 优点:极简、跨平台通用、无需额外中控节点,适合小规模或手动切换频繁的环境。
  • 缺点:本身不处理数据补齐问题,故障切换可能丢失部分已提交事务;无法自动重新搭建复制关系,切换后需要人工介入将从库重新指向新主库;不支持灵活的选择策略(无法挑一个最优从库);缺少自动化拓扑管理。

20.1.4 方案对比与选型建议

| 维度 | MHA | Keepalived + VIP |
|------|-----|------------------|
| 数据完整性 | 高,自动补齐 Binlog 差异 | 低,依赖半同步补足,可能丢数据 |
| 切换速度 | 通常 10~30 秒 | VIP 漂移数秒内,但数据库整体恢复较慢 |
| 自动化程度 | 全自动拓扑调整 | 仅 IP 漂移,复制关系需手修 |
| 部署复杂度 | 中高,需 SSH 免密,Perl 环境 | 低,只需要配置文件和健康脚本 |
| 适用规模 | 中大型、多从库场景 | 小型、一主一备或双主场景 |
| 脑裂风险 | 较低(内部有幂等保护) | 中等,需脚本防范 |

如果你是生产环境,对数据零丢失有要求,且至少有 2 个以上从库,推荐使用 MHA(或后续衍生版本)。如果只是小型项目、开发测试环境,或者主库短期内可以容忍少量数据丢失,Keepalived + VIP 是成本极低的选择。

需要特别指出的是,这两种方案都是基于主从异步复制或半同步复制之上的,真正的高可用最终还要结合复制架构的选型以及应用层的配合——例如使用中间件做读写分离和自动路由,才能真正实现业务无感知的故障切换。在云环境中,云厂商提供的 RDS 大多内置了这套切换逻辑,自建数据库则需要你根据自己的运维能力,选择其中一种或结合使用。