通过ProxySQL连接MySQL主从集群频繁出现Access Denied问题求助
我来帮你排查这个ProxySQL连接时好时坏的问题,结合你给出的环境信息,咱们一步步分析可能的原因和解决办法:
- Azure Ubuntu 18.04实例,部署3台MySQL 8.0.18主从节点:
- xxx.xxx.xxx.73(从库)
- xxx.xxx.xxx.75(主库)
- xxx.xxx.xxx.79(从库)
- ProxySQL版本:2.0.6-73-gc746bf7f(代号Truls)
- MySQL客户端版本:mysql Ver 8.0.19 for Linux on x86_64(社区版GPL)
- 已配置MySQL节点参数:
collation-server = utf8mb4_general_ci、default-authentication-plugin = mysql_native_password
问题现象
使用同一用户名密码通过ProxySQL(地址10.5.0.80,端口6033)连接时,成功和失败随机出现。执行以下命令:
mysql -h 10.5.0.80 -u <mysql_user> -p <password> -P 6033 -e " SELECT @@hostname ; "
有时能正常返回节点主机名,有时会触发错误:
ERROR 1045 (28000): ProxySQL Error: Access denied for user 'app_user'@'10.5.0.80' (using password: YES)
可能的原因及排查解决步骤
1. 后端MySQL节点的用户配置不一致
ProxySQL只是路由请求,最终验证权限的是后端MySQL节点。如果某台从库的app_user密码、权限或允许连接的主机范围和其他节点不一致,当ProxySQL把请求路由到这台节点时就会报错。
- 排查动作:分别登录每台MySQL节点,执行以下SQL确认用户信息:
-- 查看用户的加密密码和允许的连接主机 SELECT user, host, authentication_string FROM mysql.user WHERE user = 'app_user'; -- 查看用户的权限范围 SHOW GRANTS FOR 'app_user'@'%'; -- 这里的%要替换成实际允许的主机,比如10.5.0.80 - 解决方法:确保所有MySQL节点的
app_user用户名、加密密码、权限完全一致。如果有节点密码不同,重新设置统一密码:ALTER USER 'app_user'@'%' IDENTIFIED BY '你的统一密码'; FLUSH PRIVILEGES;
2. ProxySQL的后端节点状态或路由规则异常
ProxySQL可能会因为健康检查失效,把请求发送到状态异常的节点;或者路由规则配置错误,导致部分请求分配到未正确配置用户的节点。
- 排查动作:
- 登录ProxySQL管理端口(默认6032),查看后端节点状态:
确认所有节点的SELECT hostgroup_id, hostname, port, status, weight FROM mysql_servers;status都是ONLINE,如果有节点是SHUNNED或OFFLINE,说明健康检查有问题。 - 查看用户的路由配置:
确认SELECT username, default_hostgroup, active FROM mysql_users;app_user的default_hostgroup指向包含所有正常节点的主机组,且active=1。
- 登录ProxySQL管理端口(默认6032),查看后端节点状态:
- 解决方法:
- 如果节点状态异常,先检查ProxySQL的监控用户配置(
mysql-monitor_username、mysql-monitor_password)是否有权限访问所有MySQL节点,然后手动恢复节点状态:UPDATE mysql_servers SET status='ONLINE' WHERE hostname='异常节点IP'; LOAD MYSQL SERVERS TO RUNTIME; SAVE MYSQL SERVERS TO DISK; - 调整主机组配置,确保所有包含的节点都正确配置了
app_user。
- 如果节点状态异常,先检查ProxySQL的监控用户配置(
3. ProxySQL的用户配置未同步到运行时
有时候修改了ProxySQL的用户配置,但没有加载到运行时环境,导致部分请求仍使用旧配置。
- 排查动作:登录ProxySQL管理端口,对比运行时和磁盘上的用户配置:
再查看磁盘配置文件-- 查看运行时的用户配置 SELECT username, password FROM mysql_users WHERE username='app_user';/var/lib/proxysql/mysql_users.conf中的对应内容,确认是否一致。 - 解决方法:如果配置不一致,执行以下命令加载并保存配置:
LOAD MYSQL USERS TO RUNTIME; SAVE MYSQL USERS TO DISK;
4. MySQL节点连接数或防火墙限制
偶尔的连接失败可能是某台MySQL节点的连接数达到上限,或者Azure安全组/本地防火墙偶尔拦截了ProxySQL到MySQL的连接。
- 排查动作:
- 查看MySQL节点的连接状态:
确认SHOW GLOBAL STATUS LIKE 'Threads_connected'; SHOW VARIABLES LIKE 'max_connections';Threads_connected远小于max_connections。 - 检查Azure安全组是否允许ProxySQL的IP(10.5.0.80)访问所有MySQL节点的3306端口,同时检查Ubuntu本地防火墙状态:
ufw status
- 查看MySQL节点的连接状态:
- 解决方法:
- 如果连接数接近上限,调整
max_connections参数,或者优化应用的连接池配置(比如减少空闲连接时长)。 - 确保安全组和本地防火墙规则稳定允许ProxySQL与所有MySQL节点的通信。
- 如果连接数接近上限,调整
5. ProxySQL版本兼容性问题
你使用的ProxySQL 2.0.6版本相对较老,可能存在与MySQL 8.0.18的认证兼容性bug,这类问题在后续版本中已经被修复。
- 解决方法:尝试升级ProxySQL到较新的稳定版本(比如2.4.x系列),新版本对MySQL 8.x的认证逻辑支持更完善。
优先排查建议
先从所有MySQL节点的用户一致性和ProxySQL后端节点状态入手,这两个是此类间歇性连接问题最常见的原因。如果确认用户配置完全一致,再依次排查ProxySQL配置加载、连接限制和版本兼容性问题。
内容的提问来源于stack exchange,提问作者Debashis Mallick




