14.6.6 与MHA/Orchestrator的联动
在主从架构中,ProxySQL负责读写路由与连接管理,而MHA/Orchestrator负责主库故障检测与切换。两者联动的关键在于主库切换后,ProxySQL能及时感知并更新写节点与读节点列表,避免写入落到旧主或不可用节点。
原理草图(事件驱动闭环):
联动流程要点:
- MHA/Orchestrator完成主库提升与复制链路重建,确保新主可写且从库追上。
- 切换完成后,通过事件脚本或API回调通知ProxySQL更新配置,包括mysql_servers表中的hostgroup与读写标记。
- ProxySQL自身监控与自动主库检测需与MHA/Orchestrator分工明确,避免双重决策。
安装与准备(示例环境)#
示例假设:
- ProxySQL admin 端口 6032
- 写组 hostgroup=10,读组 hostgroup=20
- Orchestrator已部署并可执行故障切换
- ProxySQL管理用户:admin:admin
安装(示例,基于Debian/Ubuntu):
# 安装 ProxySQL
sudo apt-get update
sudo apt-get install -y proxysql
# 启动服务
sudo systemctl enable --now proxysql
# 验证管理端口
mysql -uadmin -padmin -h127.0.0.1 -P6032 -e "SELECT * FROM global_variables LIMIT 1;"
准备ProxySQL后端节点(示例):
-- 登录管理端口
mysql -uadmin -padmin -h127.0.0.1 -P6032
-- 添加写组与读组
INSERT INTO mysql_servers(hostgroup_id, hostname, port, weight, max_connections, comment)
VALUES
(10, '10.0.0.11', 3306, 100, 200, 'writer'),
(20, '10.0.0.12', 3306, 100, 200, 'reader1'),
(20, '10.0.0.13', 3306, 100, 200, 'reader2');
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
事件脚本联动示例(Orchestrator WebHook)#
当Orchestrator完成切换后触发脚本,更新ProxySQL写组节点与读组成员。
脚本路径示例:/opt/orch/hooks/update_proxysql.sh
#!/usr/bin/env bash
# 参数:new_master_ip old_master_ip
NEW_MASTER="$1"
OLD_MASTER="$2"
ADMIN_USER="admin"
ADMIN_PASS="admin"
ADMIN_HOST="127.0.0.1"
ADMIN_PORT="6032"
# 将新主加入写组,旧主降级到读组或移除
mysql -u${ADMIN_USER} -p${ADMIN_PASS} -h${ADMIN_HOST} -P${ADMIN_PORT} -e "
UPDATE mysql_servers
SET hostgroup_id=10, status='ONLINE', weight=100, comment='writer'
WHERE hostname='${NEW_MASTER}';
UPDATE mysql_servers
SET hostgroup_id=20, status='ONLINE', weight=100, comment='former_master'
WHERE hostname='${OLD_MASTER}';
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
"
echo "ProxySQL updated: new master=${NEW_MASTER}, old master=${OLD_MASTER}"
Orchestrator配置示例(WebHook触发):
{
"PostMasterFailoverProcesses": [
"/opt/orch/hooks/update_proxysql.sh {successor} {failedMaster}"
]
}
预期效果:
- ProxySQL写组(hostgroup=10)仅保留新主
- 旧主在读组(hostgroup=20)或被移除
- 应用写入自动指向新主库
管理端SQL联动示例(API驱动)#
适合中间层服务调用ProxySQL管理接口:
-- 假设新主IP 10.0.0.12 旧主IP 10.0.0.11
UPDATE mysql_servers
SET hostgroup_id=10, status='ONLINE', weight=100, comment='writer'
WHERE hostname='10.0.0.12';
UPDATE mysql_servers
SET hostgroup_id=20, status='ONLINE', weight=100, comment='former_master'
WHERE hostname='10.0.0.11';
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
关键配置关注点#
- 读写组划分:
SELECT hostgroup_id, hostname, status, weight, comment
FROM mysql_servers
ORDER BY hostgroup_id, hostname;
- 复制组关系(若使用replication hostgroups):
INSERT INTO mysql_replication_hostgroups(writer_hostgroup, reader_hostgroup, comment)
VALUES (10, 20, 'rw_split');
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
- 监控用户权限最小化:
-- 在MySQL后端创建监控用户
CREATE USER 'proxymon'@'%' IDENTIFIED BY 'proxymon';
GRANT REPLICATION CLIENT, PROCESS, SELECT ON *.* TO 'proxymon'@'%';
验证与观测命令#
-- 1) 检查运行时配置生效
SELECT * FROM runtime_mysql_servers;
-- 2) 查看写组只有一个主
SELECT hostgroup_id, hostname, status
FROM runtime_mysql_servers
WHERE hostgroup_id=10;
-- 3) 路由规则
SELECT * FROM mysql_query_rules ORDER BY rule_id;
应用侧读写验证(示意):
# 写入检查(必须落到新主)
mysql -uapp -papp -hproxysql -P6033 -e "INSERT INTO test.t1 VALUES (NOW());"
# 读取检查(读组分散)
mysql -uapp -papp -hproxysql -P6033 -e "SELECT @@hostname;"
常见故障与排错#
- 切换后写仍落旧主
排查:
SELECT * FROM runtime_mysql_servers WHERE hostgroup_id=10;
SELECT * FROM mysql_servers WHERE hostname='旧主IP';
处理:确保旧主在写组移除或状态设为OFFLINE_SOFT。
- ProxySQL更新无效
排查是否未加载运行时:
SHOW WARNINGS;
SELECT * FROM runtime_mysql_servers;
处理:执行 LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK;
- Orchestrator钩子未执行
排查:
sudo journalctl -u orchestrator -n 200
ls -l /opt/orch/hooks/update_proxysql.sh
处理:确认脚本可执行、参数占位符正确。
练习任务#
- 模拟主库故障,手动执行脚本更新ProxySQL,观察
runtime_mysql_servers变化。 - 将旧主下线为只读,从读组移除,验证读请求是否仍可用。
- 修改写组权重为200/100,测试写路由是否仅落写组节点。