MHA切换失败主因是底层依赖未就绪:relay_log_purge=OFF未配、read_only=1被手动关闭、SSH免密未通全节点;切换前须确认Seconds_Behind_Master=0且IO/SQL线程均为Yes、所有从库my.cnf含relay_log_purge=0、候选新主无read_only=0残留。

主库宕机后 MHA 切换失败的典型现象
最常见的表现是 MHA Manager 日志卡在 Waiting for shutdown of MySQL 或报错 SSH is not available,接着超时退出。这往往不是 MySQL 本身问题,而是底层依赖没准备好:比如从库 relay_log_purge=OFF 没配、read_only=1 被手动关过、或者 ssh 免密没通到所有节点(包括自己)。MHA 不会帮你修权限或补配置,它只按预设流程走——缺哪一环,就停在哪。
切换前必须确认的三个 MySQL 状态项
MHA 不校验这些,但缺一不可,否则切完立刻主从断裂:
-
show slave status\G中Seconds_Behind_Master必须为0(或极小值),且Slave_IO_Running和Slave_SQL_Running均为Yes - 所有从库
my.cnf中必须有relay_log_purge=0—— 否则 MHA 提权时找不到未回放的 relay log - 候选新主库不能有
read_only=0的残留(尤其被人工改过之后),MHA 默认不重置该参数,提权后仍可写会导致双写
masterha_master_switch 手动切换的实操要点
自动切换常因网络抖动误触发,生产环境更推荐带 --manual_failover=1 的手动模式,全程可控:
- 执行前先跑
masterha_check_repl --conf=/etc/mha/app1.cnf,重点看输出末尾是否含MySQL Replication Health is OK. - 切换命令必须加
--skip_shutdown_script(避免误杀还在运行的旧主),并指定新主:masterha_master_switch --conf=/etc/mha/app1.cnf --master_state=alive --new_master_host=192.168.1.12 --manual_failover=1 - 切换完成后立刻连上新主执行
show master status,比对File和Position是否与原主最后的Exec_Master_Log_Pos对齐 —— 这是数据不丢的唯一证据
从库提权后最易忽略的两件事
提权完成不等于服务可用,运维动作必须跟上:
- 应用连接串里的
host和port要立刻更新,MHA 不改 DNS 也不发通知,靠监控告警或配置中心同步 - 原主库恢复后,别急着
start slave;先用CHANGE MASTER TO ... MASTER_LOG_FILE='xxx', MASTER_LOG_POS=yyy指向新主的当前 binlog 位点,否则大概率报Error 1236
真正麻烦的从来不是切换动作本身,而是那些没写进脚本、但必须人眼确认的状态细节——比如 relay log 是否清空、GTID_EXECUTED 是否连续、甚至从库磁盘空间是否够存新主传来的 binlog。这些没法自动化,只能靠 checklist 卡住。

















