根本原因是ssh免密未通透——mha要求所有节点(含从库间、从库与管理机)两两免密互通,且需配置sudo nopasswd:/usr/bin/env权限,否则切换时无法拉取relay log或执行清理操作。

为什么 masterha_manager 启动后立刻退出
根本原因几乎总是 SSH 免密没通透——MHA 不只要求管理节点能免密登录所有 MySQL 节点,还要求所有 MySQL 节点之间两两免密互通(比如从库 A 必须能免密登录从库 B)。否则切换时无法拉取 relay log 或执行清理操作。
常见误判点:
-
masterha_check_ssh显示 OK,不代表真实可用:它不校验sudo NOPASSWD:/usr/bin/env权限、不检查~/.bashrc里是否有exit、也不验证 shell 类型是否为 bash/sh - 只测了管理机 → 主库、管理机 → 从库,漏掉从库 → 从库、从库 → 管理机
- 用非 root 用户(如
mysql)运行 MHA,但未在所有节点配置sudo -l可执行env
实操建议:
- 逐台执行:
ssh -o ConnectTimeout=5 mysql@other_host date,必须全部秒回 - 手动运行脚本验证权限:
ssh mysql@node2 'sudo -n env | grep PATH',确认无密码报错 - 删掉所有节点
~/.bashrc末尾的exit或return
master_ip_failover 脚本绑错 VIP 怎么办
脚本被调用两次:一次是 --command=stop(旧主还在,准备下线),一次是 --command=start(新主已提升,要绑 IP)。如果没做判断,就可能把 VIP 绑到旧主、删掉新主上的 IP,甚至导致双主冲突。
关键约束:
- 必须用
if [ "$1" = "--command=start" ]包裹绑定逻辑,stop分支只做解绑或清空 - 禁用
ifconfig(已被废弃),改用ip addr add 192.168.1.100/24 dev eth0,且确保所有节点网卡名一致(别一个叫eth0,一个叫ens33) - 脚本开头加
set -e,避免某条命令失败后继续执行
测试方法:
- 手动运行:
./master_ip_failover --command=start --ssh_user=root --orig_master_host=192.168.1.10 --new_master_host=192.168.1.11 - 再查新主网卡:
ip addr show eth0 | grep 192.168.1.100,确认存在
masterha_check_repl 报 “Seconds_Behind_Master: NULL”
这不是复制断了,而是 MHA 拒绝切换的明确信号:它要求所有从库的 Slave_SQL_Running 必须为 Yes,且 Seconds_Behind_Master 是可读数字(不能是 NULL 或空字符串)。
典型成因:
- relay log 文件被手动删除或磁盘满导致写入失败
- 从库处于
START SLAVE UNTIL的临时状态,SQL 线程已停 -
RESET SLAVE后未START SLAVE,残留Slave_SQL_Running: No
修复步骤(在对应从库上执行):
- 先看状态:
SHOW SLAVE STATUS\G,确认Slave_SQL_Running是否为No - 若为
No,不要直接START SLAVE;先STOP SLAVE; RESET SLAVE ALL;清理残留 - 再
START SLAVE;,等Seconds_Behind_Master变成数字(如0)后再跑masterha_check_repl
原主库恢复后怎么重新接入新主库链路
最危险的操作就是直接在原主库上 CHANGE REPLICATION SOURCE TO 新主 IP —— 如果新主库在切换后已有写入,位点早已漂移,强行指定旧位点会触发主键冲突或数据覆盖。
安全路径分两种:
- 启用 GTID:原主库上直接执行
CHANGE REPLICATION SOURCE TO SOURCE_HOST='新主IP', SOURCE_AUTO_POSITION = 1;,MHA 切换时已自动开启gtid_mode=ON,无需找位点 - 未启用 GTID:必须在新主库上用
SELECT MASTER_POS_WAIT('mysql-bin.000002', 123456789);等待该位置落盘成功(返回非-1),再把此时的File和Position传给原主库
注意:MASTER_POS_WAIT 的参数不是随便写的,必须来自新主库当前 SHOW MASTER STATUS 输出的最新位点,且该位点需大于原主库崩溃前最后记录的 Exec_Master_Log_Pos(如果你有定期采集的话)。











