14.10.2 连接异常与认证失败排查
本节聚焦 ProxySQL 连接异常与认证失败的定位与处理,覆盖客户端、ProxySQL 与后端 MySQL 三端的排查思路、关键命令、修复示例与练习。
一、原理草图:连接与认证链路
二、快速定位流程(带命令与解释)
1) 确认端口监听与进程
# 作用:确认 ProxySQL 是否在 6033/6032 监听
ss -lntp | egrep '6033|6032'
# 预期:看到 LISTEN 以及 proxysql 进程
2) 客户端直连后端排除 MySQL 本身问题
# 作用:绕过 ProxySQL 验证 MySQL 可用性
mysql -h 10.0.0.10 -P3306 -u app -p -e "SELECT 1;"
# 预期:返回 1;失败则优先处理后端 MySQL
3) 进入管理端检查配置与运行态
# 作用:进入 ProxySQL 管理端
mysql -h 127.0.0.1 -P6032 -u admin -p
4) 查看后端与连接池状态
-- 作用:确认后端地址、端口、主机组状态
SELECT hostgroup_id, hostname, port, status FROM mysql_servers;
-- 作用:确认连接池是否枯竭/错误
SELECT hostgroup, srv_host, srv_port, ConnUsed, ConnFree, ConnOK, ConnERR
FROM stats_mysql_connection_pool;
三、常见报错与排错示例
1) 连接拒绝(Connection refused)
- 常见原因:进程未启动、端口未监听、监听地址错误、防火墙阻断
# 作用:检查服务状态
systemctl status proxysql
# 作用:确认监听地址是否正确
mysql -h 127.0.0.1 -P6032 -u admin -p -e \
"SHOW VARIABLES LIKE 'mysql-interfaces';"
# 作用:放通 6033(示例为 firewalld)
firewall-cmd --add-port=6033/tcp --permanent
firewall-cmd --reload
预期效果:ss -lntp 显示 6033 监听,客户端可连接。
2) 连接超时(Connection timed out)
- 常见原因:网络链路、连接池枯竭、连接数上限过小
-- 作用:查看连接池是否耗尽
SELECT hostgroup, srv_host, ConnUsed, ConnFree, ConnERR
FROM stats_mysql_connection_pool;
-- 作用:查看运行时连接参数
SHOW VARIABLES LIKE 'mysql-max_connections';
SHOW VARIABLES LIKE 'mysql-thread_pool_size';
修复示例:
-- 作用:提高运行时连接上限
SET mysql-max_connections=5000;
SET mysql-thread_pool_size=8;
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;
3) 认证失败(Access denied)
- 常见原因:ProxySQL 用户与 MySQL 用户密码不一致、主机组不匹配
-- 作用:查看 ProxySQL 用户表
SELECT username, password, default_hostgroup, active FROM mysql_users;
-- 作用:检查后端 MySQL 用户
-- 在 MySQL 上执行
SELECT user, host, plugin FROM mysql.user WHERE user='app';
修复示例(同步密码):
-- ProxySQL 管理端执行
UPDATE mysql_users
SET password = 'app_pass'
WHERE username='app';
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;
预期效果:客户端重新连接成功。
4) 握手错误/协议不匹配
- 常见原因:MySQL 8.0 的 caching_sha2_password,ProxySQL 版本较旧
-- MySQL 端切换认证插件(示例)
ALTER USER 'app'@'%' IDENTIFIED WITH mysql_native_password BY 'app_pass';
FLUSH PRIVILEGES;
5) TLS/SSL 失败
- 常见原因:证书不完整、链路不匹配
-- 作用:检查 TLS 相关变量
SHOW VARIABLES LIKE 'mysql-ssl%';
临时验证(仅排错使用):
-- 作用:关闭对后端 SSL 要求验证,验证链路是否可通
SET mysql-ssl_p2s_ca="";
LOAD MYSQL VARIABLES TO RUNTIME;
四、完整排错示例:从失败到修复
场景:客户端连接报 Access denied,后端可直连成功。
# 1) 客户端报错
mysql -h proxysql.example.com -P6033 -u app -p
# ERROR 1045 (28000): Access denied for user 'app'@'10.0.0.21'
# 2) 直连后端成功
mysql -h 10.0.0.10 -P3306 -u app -p -e "SELECT 1;"
-- 3) 进入 ProxySQL 管理端检查用户
SELECT username, password, default_hostgroup FROM mysql_users WHERE username='app';
-- 4) 修复密码并加载
UPDATE mysql_users SET password='app_pass' WHERE username='app';
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;
预期效果:客户端可通过 6033 正常连接。
五、关键日志与诊断工具
# 作用:实时查看 ProxySQL 日志
tail -f /var/lib/proxysql/proxysql.log
# 作用:抓包定位握手失败或 TLS 错误
tcpdump -i eth0 port 6033 -nn -vv
六、练习与自测
1) 练习:创建一个错误密码用户并修复
- 目标:触发 Access denied 并修复
- 步骤:
1. 在 ProxySQL 插入错误密码
2. 连接失败
3. 更新密码并加载
INSERT INTO mysql_users(username,password,default_hostgroup,active)
VALUES('test','badpass',1,1);
LOAD MYSQL USERS TO RUNTIME;
-- 连接失败后修复
UPDATE mysql_users SET password='rightpass' WHERE username='test';
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;
2) 练习:模拟连接池枯竭并调整
- 目标:观察 ConnUsed/ConnFree 变化
-- 降低连接上限制造压力
SET mysql-max_connections=50;
LOAD MYSQL VARIABLES TO RUNTIME;
-- 查看连接池
SELECT hostgroup, ConnUsed, ConnFree FROM stats_mysql_connection_pool;
恢复:
SET mysql-max_connections=2000;
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;
七、排障要点总结
- 先排除网络与后端 MySQL,再定位 ProxySQL 层。
- 运行时修改优先用 LOAD ... TO RUNTIME,稳定后再 SAVE ... TO DISK。
- 认证问题优先比对 mysql_users 与 mysql.user 的一致性。