MHA并非开箱即用,必须先确保主从复制稳定、SSH双向免密互通、权限与日志配置合规,否则masterha_check_repl和masterha_check_ssh将直接失败,阻塞全部后续操作。

MHA 不是开箱即用的“一键高可用”,必须先确保主从复制稳定、SSH 互通、权限和日志配置到位,否则 masterha_check_repl 和 masterha_check_ssh 会直接失败,后续所有操作都卡住。
主从复制必须满足 MHA 的硬性前提
MHA 对底层复制有明确要求:必须启用 log_bin、relay_log,且所有节点 server_id 唯一;从库必须开启 read_only=1(仅允许 SQL 线程写入),但 super_read_only=0(否则 MHA 提升时无法执行 RESET SLAVE 等操作)。
常见错误现象:masterha_check_repl 报错 “Slave is not running” 或 “Seconds_Behind_Master is NULL”,本质是 IO/SQL 线程没起来,或 relay_log_recovery=1 导致启动失败。
- 检查复制状态统一用
SHOW SLAVE STATUS\G,重点关注Slave_IO_Running、Slave_SQL_Running、Seconds_Behind_Master三项 - MySQL 5.7+ 必须关闭
enforce_gtid_consistency=OFF(除非你明确使用 GTID 复制并已配置gtid_mode=ON) - 推荐在主库上启用
binlog_format=ROW,避免语句级复制在故障切换时产生不一致
SSH 免密必须双向、无密码、无交互
MHA Manager 节点要能免密登录所有 MySQL 节点,反过来,每个 MySQL 节点也必须能免密登录其他所有节点(包括自己),因为 save_binary_logs 脚本依赖本地 scp 和远程 mysqlbinlog 调用。
容易踩的坑:ssh-copy-id 成功不代表真正可用——比如 sshd 配置了 PermitRootLogin without-password 但未放开 PubkeyAuthentication yes,或者 SELinux 拦截了 ~/.ssh 目录访问。
- 验证方式:在 Manager 上执行
ssh root@db251 date、ssh root@db253 date、ssh root@db254 date,再分别登录各节点执行ssh root@db250 date等反向命令 - 必须禁用
StrictHostKeyChecking:在/root/.ssh/config中添加StrictHostKeyChecking no,否则masterha_check_ssh会卡在首次连接确认 - 所有节点的
/root/.ssh/authorized_keys文件权限必须是600,目录权限700,否则 sshd 拒绝认证
mha.cnf 配置里最容易被忽略的三个参数
不是把 IP 和用户填进去就完事。[server default] 下的几个参数决定 MHA 是否真能安全切换,尤其在半同步或延迟敏感场景下。
典型错误:masterha_master_switch 执行后卡住,或切换后从库报错 “The slave I/O thread stops because master and slave have equal MySQL server ids”,其实是 candidate_master=1 和 check_repl_delay=0 配合不当导致。
-
candidate_master=1:仅加在你希望优先当选的从库段(如备主库),但必须配合check_repl_delay=0,否则延迟 > 1 秒的节点会被跳过——而生产环境从库偶尔延迟是常态 -
ping_interval=3:默认 3 秒探测一次 master,太短易误判,太长故障发现慢;建议结合心跳表或masterha_master_monitor定时任务综合判断 -
secondary_check_script:强烈建议配置,例如masterha_secondary_check -s db253 -s db254 --user=root --master_host=db251 --master_port=3306,避免单点网络抖动引发误切
监控脚本不能只靠 masterha_check_status
masterha_check_status 只告诉你 MHA Manager 进程是否在跑,不反映复制延迟、磁盘空间、binlog 是否可读等真实风险。线上出问题往往不是 Manager 挂了,而是 save_binary_logs 失败或 relay log 应用卡住。
真正有效的监控必须组合落地:
- 每 30 秒执行一次
masterha_check_repl --conf=/etc/mha/mha.cnf 2>&1 | grep -q "MySQL Replication Health is OK",失败则告警 - 定期检查各从库的
Relay_Log_Space(SHOW SLAVE STATUS输出),突增说明 SQL 线程积压,可能即将 OOM - 在主库部署定时任务,用
mysqlbinlog --base64-output=decode-rows -v抽样解析最新 binlog,验证日志格式是否损坏(尤其主库磁盘异常后)
最常被忽略的一点:MHA 自身不提供持久化状态存储,masterha_manager 进程退出后,所有 failover 记录丢失。必须配合外部日志收集(如 journalctl -u mha-manager)或自定义钩子脚本写入数据库归档,否则无法回溯“为什么切了”“切到了哪”。


















