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) |
|---|---|---|
| 实现语言 | Perl | Go,单个静态二进制 |
| MySQL 支持 | 主要面向 5.7 历史拓扑 | 8.4.x、9.7.0 ER/EA |
| 复制模式 | binlog 位置 / GTID 均可 | 仅 GTID |
| 配置格式 | INI (app1.cnf) | YAML (cluster.yaml) |
| 运行形态 | masterha_manager 前台或 nohup | mha-manager.service |
| 运行用户 | 通常 root | mysql 用户 |
| 写入口 | 传统 VIP hook 脚本 | writer_endpoint 抽象,默认不启用 |
| Dry-run | 弱 | switch / 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.x或9.7.0ER/EA。 - 复制模式:必须开启
gtid_mode=ON和enforce_gtid_consistency=ON。 - 默认部署:纯异步复制,
semi_sync.policy: disabled。 - 半同步:只有已经安装并启用 MySQL semi-sync 插件时,才建议把策略改为
preferred或required。 - 不支持:MySQL
5.7、8.0、9.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中登记为db2、db3等。manager_ip:运行mha-manager的节点,必须出现在master_ip或slave_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/mha | manager 节点上的二进制路径 |
mha_go_config_dir | /etc/mha | cluster.yaml 目录 |
mha_go_log_dir | /var/log/mha | 日志目录 |
mha_go_service_enabled | true | 是否 enable systemd 服务 |
mha_go_semi_sync_policy | disabled | disabled、preferred 或 required |
mha_go_writer_endpoint_enabled | false | 是否启用 VIP 写入口切换 |
6. 前置条件
make_mha_go 执行前会检查:
- 每个节点的
datadir下存在master_slave_finish.flag,即已经完成master_slave.yml。 - 每个节点都开启
gtid_mode=ON和enforce_gtid_consistency=ON。 master_ip、slave_ips、manager_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-primary,replication.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-plan 和 failover-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 规则。vip、vip_netmask、net_work_interface 必须与真实网络一致。dbbot 192.168.161.* 默认测试 inventory 中的样例环境通常使用 enp1s0;其他环境请先用 ip route 或 ip 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用户读取它。