vip切换必须与数据库角色变更严格同步,否则必然导致脑裂或连接中断;核心是vip归属由数据库真实状态(如read_only、复制延迟等)决定,而非仅依赖keepalived进程或端口检测。

Keepalived 本身不感知 MySQL 主从状态,VIP 漂移必须靠自定义脚本触发优先级降级,否则切换就是“假高可用”。
为什么健康检查脚本不能只 ping MySQL 端口
MySQL 进程在、3306 端口通,不代表服务可用:可能 SHOW SLAVE STATUS 显示 Slave_IO_Running: No,或主库已只读但复制中断,或磁盘写满导致无法写入。只检测端口会掩盖这些致命异常。
- 必须检查三项核心状态:
mysql -e "SELECT 1"(连得上)、SHOW SLAVE STATUS\G中Slave_IO_Running和Slave_SQL_Running均为Yes(仅对从节点)、SELECT @@read_only为OFF(仅对主节点) - 脚本返回非 0 时,Keepalived 才会执行
vrrp_script定义的降级动作;返回 0 才认为健康 - 不要用
systemctl is-active mysqld替代连接检查——进程活着但无法响应 SQL 请求,照样该切不切
keepalived.conf 里 priority 和 nopreempt 的坑
主节点配 priority 100、从节点配 priority 90 是常见做法,但实际生产中容易翻车:
- 如果主节点故障恢复后自动抢回 VIP,可能引发脑裂:新主还在处理写请求,旧主一上线就绑 VIP,应用流量打过去直接写冲突
-
nopreempt必须加在 BACKUP 节点配置块里(不是全局),且仅当该节点当前不是 MASTER 时才生效;误加在 MASTER 节点会导致它永远不降级 - 更稳妥的做法是:两节点都设为
state BACKUP,靠priority+ 健康脚本动态决定谁升 MASTER,避免角色硬编码
VIP 漂移后 MySQL 角色没同步怎么办
VIP 切了,但原从节点没自动提升为主节点,应用连上 VIP 后仍只能读——这是最典型的“半截高可用”。Keepalived 不负责数据库角色变更,这部分必须由脚本闭环:
- 在从节点的健康检查脚本里,一旦检测到自己成为 MASTER(可通过
ip addr show | grep VIP判断),立即执行:mysql -e "STOP SLAVE; RESET SLAVE ALL;"清除从库状态 - 主节点降级脚本里,应主动执行
mysql -e "SET GLOBAL read_only=ON;"防止故障恢复后误写 - 不要依赖
CHANGE MASTER TO手动配置——脚本里要固化好对方 IP、用户、密码,失败时记录日志并退出,避免静默失败
ARP 刷新失败导致客户端连不上 VIP
VIP 绑定到新网卡后,局域网交换机/客户端 ARP 缓存仍指向旧 MAC,流量发不出去。这不是 Keepalived 配置问题,而是网络层细节:
- 确保
notify_master脚本末尾调用arping -c 3 -A -I eth0 192.168.71.100(替换为你的 VIP 和网卡名),强制广播免费 ARP - 检查防火墙是否拦截了
arping发出的 ARP 包:iptables -L -n | grep arp,必要时放行-p 0x0806 - 某些云厂商(如阿里云)禁用 Gratuitous ARP,此时需改用云平台提供的 VIP 绑定 API,Keepalived 只做状态协调
真正难的从来不是配置文件写几行,而是让 VIP 漂移、MySQL 角色切换、ARP 刷新、应用连接这四件事在 10 秒内原子性完成——任何一环异步或超时,都会让高可用变成单点故障的放大器。











