MHA 在 MySQL 8.0+ 上基本不可用,因其官方已停止维护,最新版仅支持到 MySQL 5.6,不兼容 8.0 的 GTID event 格式、新权限表结构及移除的 mysqlbinlog 参数。

为什么 MHA 在 MySQL 8.0+ 上基本不可用
MHA(Master High Availability)官方早已停止维护,最新版 mha4mysql-manager 仅支持到 MySQL 5.6,对 MySQL 5.7 兼容性差,MySQL 8.0 完全不支持——它依赖的 mysqlbinlog --base64-output=DECODE-ROWS 已被移除,且无法解析 8.0 的 GTID event 格式和新权限表结构。
常见错误现象包括:Can't exec "mysqlbinlog": No such file or directory、Failed to get binlog position from slave、切换后从库报 ER_NO_DEFAULT_FOR_FIELD 或复制中断。
- MySQL 5.7 起默认启用
enforce_gtid_consistency=ON,MHA 的 binlog 解析逻辑不兼容 GTID 模式下的 event 位置计算 - MHA 的
apply_diff_relay_logs脚本硬编码了旧版 mysqlbinlog 参数,8.0 中--short-form和--read-from-remote-server行为已变更 - 它依赖
mysql客户端执行CHANGE MASTER TO,但 8.0+ 默认禁用password字段明文传参,而 MHA 不支持mysql_config_editor或 socket 认证
替代方案:用 Orchestrator + VIP 实现自动故障切换
Orchestrator 是目前最活跃的 MySQL 高可用开源工具,原生支持 MySQL 5.7/8.0、GTID、PXC、MGR,能自动检测主库宕机、选举新主、重置从库拓扑,并通过调用自定义 hook 脚本完成 VIP 漂移或 DNS 更新。
部署关键点:
- 必须开启
relay_log_info_repository = TABLE和master_info_repository = TABLE,否则 Orchestrator 无法准确读取复制元数据 - 所有节点需配置统一的
report_host和report_port,否则发现拓扑时会把同一台机器识别成多个实例 - Orchestrator 自身需部署在独立节点(不能和 MySQL 同机),并配置
MySQLInstancePoolSize避免连接打满 - 故障切换触发前,它会执行
SELECT MASTER_POS_WAIT(...)确保从库追平,若超时(默认 30 秒)则跳过该从库——这点比 MHA 更可控
示例 hook 脚本片段(切换后漂移 VIP):
#!/bin/bash # $1 = old master host, $2 = new master host if [ "$2" = "db-prod-02" ]; then ssh db-prod-02 "ip addr add 10.0.1.100/24 dev eth0" fi
如果必须用 MHA:降级 MySQL 版本 + 关键补丁
仅限存量 MySQL 5.6 环境,且无法升级的场景。MHA 本身无更新,但社区有少量修复 patch 可缓解部分问题。
必须做的三件事:
- 将 MySQL 降级至
5.6.51(最后一个稳定版),关闭innodb_strict_mode和sql_mode=STRICT_TRANS_TABLES,避免 MHA 内部 SQL 报错 - 手动替换
/usr/bin/apply_diff_relay_logs,把其中mysqlbinlog --base64-output=DECODE-ROWS改为mysqlbinlog --base64-output=DECODE-ROWS --skip-gtids(适用于非 GTID 环境) -
master_ip_failover脚本里禁止使用mysql -u root -p$PASS,改用mysql --defaults-file=/etc/my.cnf.d/mha.cnf,且该文件中[client]段必须包含user=root和password=xxx
注意:mha4mysql-node 必须和 MySQL 同版本编译,CentOS 7 上直接装 RPM 包大概率因 glibc 版本不匹配导致 Can't load /usr/lib64/mysql/plugin/dialog.so 错误。
真正决定高可用成败的,是监控与人工兜底机制
无论用 Orchestrator 还是降级后的 MHA,自动切换都可能误判——比如主库只是临时卡住(慢查询阻塞、IO hang)、网络分区导致脑裂、或从库延迟过大却未被正确识别。
必须同步做:
- 用
pt-heartbeat单独监控真实复制延迟,不能只信Seconds_Behind_Master - Orchestrator 的
PostGracefulTakeoverProcesses必须配置告警通知(如调用企业微信 webhook),而非仅写日志 - 所有切换操作需记录到审计表(例如插入
ha_failover_log表),字段含trigger_reason、old_master、new_master、executed_sql
最常被忽略的一点:切换后应用连接池不会自动刷新地址。哪怕 VIP 漂移成功,若应用没配置 autoReconnect=true&failOverReadOnly=false(JDBC)或没启用 mysqlnd_ms(PHP),流量仍打向旧主地址,直到连接池自然淘汰。











