MySQL MHA 部署说明
本文说明 mha.yml 的支持边界和基础使用方式。
1. 支持边界
- 当前仅按
CentOS 7 / Red Hat 7环境维护 - 目标架构:一主多从 + MHA Manager
- 适用版本:MySQL
5.7 - 切换范围:仅支持当前主库不可用后由 MHA Manager 触发的自动故障转移,不支持主库存活时的在线计划切换
mha.yml 属于传统高可用方案。对于新建集群,优先建议使用 MGR 或 InnoDB Cluster。
192.168.161.* 是 dbbot 默认三节点回归网段,不等同于传统 MHA 专项环境。若要验证 mha.yml,请单独准备 CentOS 7 或 Red Hat 7,并使用 MySQL 5.7。
2. inventory 与角色
mha.yml 仍然使用 [dbbot_mysql] 主机组,实际角色通过变量区分:
[dbbot_mysql]
192.0.2.131 ansible_user=root ansible_ssh_pass="'密码'"
192.0.2.132 ansible_user=root ansible_ssh_pass="'密码'"
192.0.2.133 ansible_user=root ansible_ssh_pass="'密码'"
3. 关键变量
编辑 mysql_ansible/playbooks/common_config.yml:
mysql_version: "5.7.44"
mysql_port: 3306
fcs_allow_dbbot_default_passwd: true
说明:
mha.yml只支持 MySQL5.7,不能沿用默认的 MySQL9.7.x配置。fcs_allow_dbbot_default_passwd: true仅适合临时实验环境。如果继续使用 dbbot 公开默认密码,必须显式开启;生产环境应改成自定义密码并保持该开关为false。
编辑 mysql_ansible/playbooks/vars/var_mha.yml:
master_ip: 192.0.2.131
slave_ips:
- 192.0.2.132
- 192.0.2.133
manager_ip: 192.0.2.133
vip: 192.0.2.130
vip_netmask: "32"
net_work_interface: ens33
mha_secondary_check_script: ""
说明:
manager_ip不能与master_ip相同manager_ip应放在从库节点上vip、vip_netmask、net_work_interface需要与实际网络环境一致ens33只是示例网卡名。执行 VIP 相关剧本前请先用ip route get <网关地址>或ip -o -4 addr show确认真实网卡;CentOS 7 KVM 测试环境中常见网卡名也可能是eth0。mha_secondary_check_script默认为空,表示使用传统 MHA 默认行为。生产环境建议按网络拓扑配置多路径探测命令,降低 manager 单路径误判风险。
3.1 VIP sudo 权限
mha.yml 在每个数据库节点生成 /etc/sudoers.d/dbbot-mha-vip。该文件归 root:root 所有、权限为 0440,只允许 mysql_user(默认为 mysql)以 root 身份执行按当前变量完整展开的三条命令:
<mysql_user> ALL=(root) NOPASSWD: /usr/sbin/ip addr add <vip>/<prefix> dev <interface>
<mysql_user> ALL=(root) NOPASSWD: /usr/sbin/ip addr del <vip>/<prefix> dev <interface>
<mysql_user> ALL=(root) NOPASSWD: /sbin/arping -c 5 -U -I <interface> <vip>
master_ip_failover 使用 sudo -n;策略不匹配时,sudo 命令会立即返回失败,不会等待密码输入。MHA 在节点之间传输差异日志使用普通 scp 和 ssh_user 权限,不需要也不会获得 sudo scp。剧本不会授权无参数限制的 ip 或 arping。
执行新版传统 MHA role 时,剧本会先安装并校验精确策略,再删除 /etc/sudoers 中由旧版 dbbot 生成的以下宽泛规则:
mysql ALL=(ALL) NOPASSWD: /usr/sbin/ip,/sbin/arping,/usr/bin/scp
可用 visudo -c 校验完整 sudo 配置;不要直接手工放宽受管策略。
4. 执行入口
cd /usr/local/dbbot/mysql_ansible/playbooks
ansible-playbook mha.yml
执行过程中按提示输入 confirm 后继续。
非交互执行请显式追加确认变量:
python3 /usr/local/dbbot/portable-ansible/ansible-playbook mha.yml -e dbbot_confirmation_input=confirm
如果命令行同时临时覆盖布尔变量,请使用 JSON extra-vars,避免 key=true 被解析为字符串:
python3 /usr/local/dbbot/portable-ansible/ansible-playbook mha.yml \
-e dbbot_confirmation_input=confirm \
-e '{"fcs_allow_dbbot_default_passwd": true}'
4.1 部署后修改 VIP
当前没有单独的传统 MHA VIP 重配置 Playbook。mha.yml 还会处理 MySQL、复制、SSH 和 MHA 部署,不应作为运行中集群只修改 VIP 的快捷入口;mha_unsafe_uninstall.yml 会删除 MySQL 数据目录,更不能用于该操作。
纯 VIP 变更不需要修改 /etc/masterha/app.cnf。该文件只引用 /usr/local/bin/master_ip_failover,不保存 VIP。节点成员或复制拓扑变化不属于本流程;这类变更必须另行完整重配置并同步更新 app.cnf。变更 VIP 时必须同步以下四类状态:
- 源配置
mysql_ansible/playbooks/vars/var_mha.yml - 各数据库节点的
/usr/local/bin/master_ip_failover - 各数据库节点的
/etc/sudoers.d/dbbot-mha-vip - 数据库节点网卡上的实时 VIP
请在维护窗口按以下顺序操作:
开始前必须由网络管理系统、IPAM 或同等可信来源确认新 VIP 已预留,并确认相关二层网络中没有其他设备占用该地址。ping 无响应不能证明地址空闲;无法确认时不要继续切换。
在
manager_ip节点停止 MHA Manager,并确认进程已经退出:su - <mysql_user> -c 'masterha_stop --conf=/etc/masterha/app.cnf' pgrep -af 'masterha_manager.*--conf=/etc/masterha/app.cnf'确认当前实际可写主库以及旧 VIP 的唯一持有节点。发生过故障切换后,不能假定它仍然是变量中的
master_ip。记录当前实时 VIP,备份源配置、failover 脚本和 sudoers,再更新
var_mha.yml。在所有数据库节点用临时文件准备新的master_ip_failover和精确 sudoers,分别执行perl -c <临时脚本>与visudo -cf <临时 sudoers>,验证通过后再替换正式文件;sudoers 必须保持root:root 0440,替换后再执行visudo -c。由
root从实际持有节点删除旧 VIP,在当前主库绑定新 VIP并发送 gratuitous ARP:/usr/sbin/ip addr del <old-vip>/<old-prefix> dev <old-interface> /usr/sbin/ip addr add <new-vip>/<new-prefix> dev <new-interface> /sbin/arping -c 5 -U -I <new-interface> <new-vip>在全部数据库节点确认旧 VIP 为零份、新 VIP 只存在一份且位于当前主库。
在 Manager 节点完成检查并重新启动:
su - <mysql_user> -c 'masterha_check_ssh --conf=/etc/masterha/app.cnf' su - <mysql_user> -c 'masterha_check_repl --conf=/etc/masterha/app.cnf' /usr/local/start_mha.sh su - <mysql_user> -c 'masterha_check_status --conf=/etc/masterha/app.cnf'
任何步骤失败时都应保持 Manager 停止,恢复旧的源配置、failover 脚本、sudoers 和实际 VIP,验证旧状态后再启动 Manager。
4.2 从库重启后的只读状态
传统 MHA 使用与单机、普通主从相同的异步复制基础配置,my.cnf 保持 super_read_only=OFF。mha.yml 首次建立复制时会在从库运行时设置 super_read_only=ON,但该状态不会通过基础模板持久化;传统 MHA Manager 也不会在 mysqld 重启后自动修复从库只读状态。
每次数据库实例或主机重启后,在恢复业务流量前必须重新确认当前真实主库和所有从库。只在已经确认的从库上执行:
SHOW SLAVE STATUS\G
SELECT @@GLOBAL.read_only, @@GLOBAL.super_read_only;
SET GLOBAL super_read_only = ON;
SELECT @@GLOBAL.read_only, @@GLOBAL.super_read_only;
验收时应保证当前主库的 read_only 和 super_read_only 均为 0,每个从库均为 1,并重新执行 masterha_check_repl。不要根据旧的 master_ip 变量判断角色,也不要在当前真实主库上执行 SET GLOBAL super_read_only=ON。
异步拓扑没有把 super_read_only=ON 写死到通用 my.cnf,是为了避免当前主库 crash 后在尚未发生故障切换时自行恢复为只读。重启后的从库只读状态属于运维巡检和恢复流程的一部分,当前剧本只保证首次部署状态。
4.3 切换能力边界与故障演练
dbbot 的传统 MHA 实现不支持 masterha_master_switch --master_state=alive 在线计划切换。部署后即使存在 /usr/local/bin/master_ip_online_change,并且 /etc/masterha/app.cnf 引用了该文件,也不代表该钩子可用;它不是 dbbot 的公开执行入口,不应在运行中的集群上调用。
当前支持的是故障触发路径:MHA Manager 发现当前主库 mysqld 持续不可用后,选择候选从库、执行故障转移并调用 master_ip_failover 迁移 VIP。只应在隔离的测试环境或已经批准的故障演练窗口验证该流程:
在 Manager 节点执行
masterha_check_ssh和masterha_check_repl,确认 Manager 正在运行,并记录当前真实主库、复制状态和 VIP 持有节点。停止业务写入或将演练环境与业务隔离,并确保旧主库不会在切换过程中自行恢复写入。dbbot 生成的 MySQL systemd unit 使用
Restart=on-failure;不要只对mysqld执行kill -9后便假定它会持续离线。若必须模拟进程 crash,应先采用经过批准的 fencing 或临时自动拉起阻断措施。默认端口
3306的受控演练可在当前真实主库执行以下命令,使 Manager 按故障路径处理:systemctl stop mysql3306非默认端口应使用实际的
mysql_service_name。不要在未隔离的生产环境直接执行该命令。在 Manager 节点观察
/var/log/masterha/manager.log,等待故障转移结束。传统 MHA 完成一次故障转移后 Manager 会退出;不要在旧主库完成隔离、重建或重新接入前直接重启 Manager。独立验收数据库和写入口:旧主库必须保持不可写或已被 fencing,新主库必须可写,其余从库复制正常;在所有数据库节点执行
ip -o -4 addr show,确认 VIP 只存在一份且位于新主库,并通过 VIP 完成实际连接和写入验证。
master_ip_failover 的输出或退出状态不能代替上述 VIP 实际验收。远程网络命令异常时,钩子结果不一定能可靠反映 VIP 是否迁移成功,因此每次故障切换后都必须检查所有节点的实时地址状态。需要主库存活状态下的计划切换时,应采用 dbbot 之外的受控人工流程,或选择明确支持在线切换的架构。
5. 卸载
mha_unsafe_uninstall.yml 会先停止传统 MHA manager、删除配置的 VIP 和 MHA 运行文件,再按当前 mysql_port 清理 MySQL 实例数据、日志和运行目录:
cd /usr/local/dbbot/mysql_ansible/playbooks
ansible-playbook mha_unsafe_uninstall.yml
执行过程中按提示输入 confirm。如需在非交互场景执行,请追加 -e dbbot_confirmation_input=confirm。
默认不会删除 MHA RPM 包。如确需删除 mha4mysql-manager / mha4mysql-node RPM,可追加 -e '{"mha_uninstall_remove_packages": true}'。
6. 注意事项
mha.yml当前文档只覆盖CentOS 7和Red Hat 7使用前提。- 不满足
CentOS 7/Red Hat 7与 MySQL5.7条件的三节点回归环境会被mha.yml前置校验拦截,属于预期行为。 - 如果你在其他发行版上使用,需要先自行验证 Perl 依赖和 MHA RPM 兼容性。
- 默认不配置
secondary_check_script。生产环境应结合网络拓扑补充 MHA 二次探测配置。 - 失败后如需重跑,建议先确认 MHA Manager 配置、VIP 状态和 MySQL 实例状态,再决定是否清理残留文件。