MySQL MHA-Go 部署说明

本文说明 mha_go.yml 的支持边界与基础使用方式。mha_go.yml 部署的是 Go 重写的 MHA 管理器(mha-go),它不依赖 Perl MHA 工具链,以一个静态二进制和一份 YAML 配置运行在 manager 节点上。

当前 mha_go.yml 的定位是:在已经由 dbbot master_slave.yml 部署完成的一主多从 GTID 拓扑上部署 mha-go manager。如果还没有 MySQL 主从拓扑,请先运行 master_slave.yml

1. 原理

mha-go 围绕 GTID 单主复制做故障检测、在线切换与故障转移:

  • GTID-only:只支持 GTID 复制,不支持 binlog file/position 模式。
  • 拓扑发现:通过 SQL 探测主从角色、GTID、只读状态、复制线程、复制延迟与半同步状态。
  • 候选主选择slave_ips 的顺序映射为 candidate_priority,第一个从库优先级最高。
  • 写入口抽象:默认 writer_endpoint.kind: none;开启 VIP 后由 /usr/local/bin/mha_ip_failover.sh 切换写入口。
  • 执行形态:manager 以 mysql 用户通过 systemd 常驻,日志使用 JSON 输出到 journal。

2. 与传统 MHA 的对比

维度传统 MHA (mha.yml)MHA-Go (mha_go.yml)
实现语言PerlGo,单个静态二进制
MySQL 支持主要面向 5.7 历史拓扑8.4.x9.7.0 ER/EA
复制模式binlog 位置 / GTID 均可仅 GTID
配置格式INI (app1.cnf)YAML (cluster.yaml)
运行形态masterha_manager 前台或 nohupmha-manager.service
运行用户通常 rootmysql 用户
写入口传统 VIP hook 脚本writer_endpoint 抽象,默认不启用
Dry-runswitch / failover-execute 原生支持 --dry-run

新建 MySQL 8.4/9.7 GTID 主从集群优先使用 mha_go.yml;只有维护 MySQL 5.7 历史拓扑时才继续使用传统 mha.yml

3. 支持边界

  • 目标架构:一主多从 + 一个 MHA-Go manager。
  • MySQL 版本:8.4.x9.7.0 ER/EA。
  • 复制模式:必须开启 gtid_mode=ONenforce_gtid_consistency=ON
  • 默认部署:纯异步复制,semi_sync.policy: disabled
  • 半同步:只有已经安装并启用 MySQL semi-sync 插件时,才建议把策略改为 preferredrequired
  • 不支持:MySQL 5.78.09.6、非 GTID 复制。

MySQL 9.7.x 使用 glibc2.28 包,不支持 CentOS/RHEL 7 系列;这类系统请使用 MySQL 8.4.x 作为 MHA-Go 前置主从集群。

4. 拓扑约定

mha_go.yml 复用 [dbbot_mysql] 主机组,通过 master_ip / slave_ips / manager_ip 区分节点:

  • master_ip:当前主库,在 cluster.yaml 中登记为 db1
  • slave_ips:从库列表,在 cluster.yaml 中登记为 db2db3 等。
  • manager_ip:运行 mha-manager 的节点,必须出现在 master_ipslave_ips 中。默认是 master_ip,与当前手工部署指南和 dbbot 默认测试环境一致。

dbbot 默认测试环境:

192.168.161.11  primary / manager
192.168.161.12  replica
192.168.161.13  replica

5. 关键变量

编辑 mysql_ansible/playbooks/vars/var_mha_go.yml

master_ip: 192.168.161.11
slave_ips:
  - 192.168.161.12
  - 192.168.161.13
sub_nets: "192.168.161.%"

manager_ip: "{{ master_ip }}"
mha_go_cluster_name: app1

mha_go_semi_sync_policy: disabled
mha_go_semi_sync_wait_for_replica_count: 0
mha_go_semi_sync_timeout: 5s
mha_go_salvage_policy: salvage-if-possible
mha_go_salvage_timeout: 30s

常用变量:

变量默认值说明
manager_ip{{ master_ip }}运行 mha-manager 的 MySQL 节点
mha_go_binary_dest/usr/local/bin/mhamanager 节点上的二进制路径
mha_go_config_dir/etc/mhacluster.yaml 目录
mha_go_log_dir/var/log/mha日志目录
mha_go_service_enabledtrue是否 enable systemd 服务
mha_go_semi_sync_policydisableddisabledpreferredrequired
mha_go_writer_endpoint_enabledfalse是否启用 VIP 写入口切换

6. 前置条件

make_mha_go 执行前会检查:

  • 每个节点的 datadir 下存在 master_slave_finish.flag,即已经完成 master_slave.yml
  • 每个节点都开启 gtid_mode=ONenforce_gtid_consistency=ON
  • master_ipslave_ipsmanager_ip 都能在 inventory 中找到。

mha_go.yml 当前 role 顺序:

pre_check_and_set -> make_mha_go

它不会重装 MySQL,也不会重建复制关系。

7. 执行入口

cd /usr/local/dbbot/mysql_ansible/playbooks
python3 /usr/local/dbbot/portable-ansible/ansible-playbook \
  -i ../inventory/hosts.ini \
  mha_go.yml \
  -e dbbot_confirmation_input=confirm

使用 dbbot 公开默认密码测试时,还需要显式允许:

-e '{"fcs_allow_dbbot_default_passwd": true}'

8. 执行后产物

manager 节点上会生成:

  • /usr/local/bin/mha:当前 dbbot 内置的 mha-go 静态二进制。
  • /etc/mha/cluster.yaml:集群配置,topology.kind: mysql-replication-single-primaryreplication.mode: gtid
  • /etc/systemd/system/mha-manager.service:以 mysql:mysql 运行 mha manager --log-format json
  • /var/log/mha/:日志目录。

manager 节点的 datadir 下会生成 mha_go_finish.flag

9. 常用命令

在 manager 节点执行:

mha version
mha check-repl --config /etc/mha/cluster.yaml
mha switch --config /etc/mha/cluster.yaml --new-primary db2 --dry-run
mha failover-plan --config /etc/mha/cluster.yaml
systemctl status mha-manager
journalctl -u mha-manager -f

failover-planfailover-execute 会在主库仍存活时阻断,这是正常保护。

10. 卸载

mha_go_unsafe_uninstall.yml 会先停止并禁用 mha-manager.service,删除 mha-go manager 文件和配置的 VIP,再按当前 mysql_port 清理 MySQL 实例数据、日志和运行目录:

cd /usr/local/dbbot/mysql_ansible/playbooks
python3 /usr/local/dbbot/portable-ansible/ansible-playbook \
  -i ../inventory/hosts.ini \
  mha_go_unsafe_uninstall.yml \
  -e dbbot_confirmation_input=confirm

如果你只想保留 MySQL 主从拓扑,不要执行这个入口;它会一并清理当前 mysql_port 对应的 MySQL 实例。

11. 启用 VIP 写入口

默认不启用 VIP。如果需要固定写入口:

mha_go_writer_endpoint_enabled: true
vip: 192.168.161.10
vip_netmask: "32"
net_work_interface: enp1s0

开启后剧本会额外部署 VIP 脚本,并为 mysql 用户添加必要 sudo 规则。vipvip_netmasknet_work_interface 必须与真实网络一致。dbbot 192.168.161.* 默认测试 inventory 中的样例环境通常使用 enp1s0;其他环境请先用 ip routeip addr 确认真实网卡名。

12. 注意事项

  • mha_go.yml 是增量部署入口,不是 MySQL 主从初始化入口。
  • manager_ip 可以是主库或从库,但必须是本次 [dbbot_mysql] 中的节点。
  • MySQL 9.7.0 的 cluster.yaml 会自动写入 version_series: "9.7";MySQL 8.4.x 会写入 "8.4"
  • dbbot 默认半同步策略是 disabled,避免在未安装 semi-sync 插件的纯异步主从上误报。
  • cluster.yaml 权限为 0640,属主为 mysql:mysql,因为 systemd 服务以 mysql 用户读取它。