来源:未知来源 | 发布日期:2026-07-14
MySQL 连接失败排查指南
核心思路: 先明确报错类型对应的层面(本地 socket / 网络层 / 认证层 / 资源层),再用对应命令逐层验证证据,避免在错误方向上反复尝试。
本文按"现象 → 信息收集 → 初步判断 → 命令检查 → 证据分析 → 根因 → 修复 → 验证 → 复盘"展开。命令基准为 MySQL 8.0(部分兼容 5.7)。
一、典型报错与对应层面
| 错误码 | 报错信息 | 指向层面 |
|---|---|---|
| ERROR 2002 | Can't connect to local MySQL server through socket | 本地 socket |
| ERROR 2003 | Can't connect to MySQL server (111) / (110) | 网络层 |
| ERROR 1045 | Access denied for user | 认证层 |
| ERROR 1130 | Host 'x.x.x.x' is not allowed | 白名单/权限 |
| ERROR 1040 | Too many connections | 资源层 |
| ERROR 2013 | Lost connection during query | 连接中途断开 |
二、排查前必须收集的信息
- 客户端类型:本机 CLI 还是远程应用服务器?
- 连接方式:Unix Socket 还是 TCP(
-h指定 IP)? - MySQL 版本:
SELECT VERSION();或mysqld --version - 部署方式:物理机/虚拟机、Docker 容器、Kubernetes Pod?
- 完整错误码和错误信息
- 问题性质:全新环境从未连接成功,还是之前正常现在突然失败?
"从未连接成功" → 配置或权限问题;"之前正常现在失败" → 资源耗尽、网络变化、密码被修改。
三、本地 Socket 连接失败(错误 2002)
排查步骤
1. 检查服务状态:
systemctl status mysqld
# 或某些发行版服务名为 mysql
systemctl status mysql
2. 服务 running 但仍报 2002 → socket 路径不匹配:
# 查看配置中定义的 socket 路径
grep -i "^socket" /etc/my.cnf /etc/mysql/my.cnf /etc/mysql/mysql.conf.d/mysqld.cnf 2>/dev/null
# 确认文件是否存在
ls -l /var/run/mysqld/mysqld.sock
# 检查目录权限
ls -ld /var/run/mysqld/
3. 目录被删除(/var/run 是 tmpfs,重启清空):
cat /usr/lib/tmpfiles.d/mysql.conf
# 应有:d /var/run/mysqld 0755 mysql mysql -
4. 手动指定 socket 验证:
mysql -u root -p --socket=/var/run/mysqld/mysqld.sock
四、网络层不可达(错误 2003)
关键判断依据
| 错误码 | 含义 | 排查方向 |
|---|---|---|
| (111) Connection refused | 网络通,但端口无进程监听或被防火墙 REJECT | 查服务是否监听、监听地址 |
| (110) Connection timed out | 请求包无响应,网络不通或被防火墙 DROP | 查网络链路、安全组、防火墙 |
命令检查
1. 验证端口是否在监听:
ss -ltnp | grep 3306
- 监听
0.0.0.0:3306→ 正常 - 监听
127.0.0.1:3306→ 只监听回环,远程连不上(bind-address 问题) - 无输出 → mysqld 没启动或启动后退出,查错误日志
2. 客户端侧验证 TCP 连通性:
telnet <MySQL服务器IP> 3306
# 或
nc -zv <MySQL服务器IP> 3306
3. 检查防火墙:
# firewalld
firewall-cmd --list-ports
# iptables
iptables -L -n | grep 3306
4. 查看 MySQL 错误日志:
tail -100 /var/log/mysqld.log
# Debian/Ubuntu
tail -100 /var/log/mysql/error.log
# 查日志路径
grep -i "log-error\|log_error" /etc/my.cnf /etc/mysql/mysql.conf.d/mysqld.cnf 2>/dev/null
Docker/K8s 场景额外检查
# Docker:确认容器状态和端口映射
docker ps --filter "name=mysql"
docker logs --tail 100 <容器名>
# K8s:确认 Pod、Service、NetworkPolicy
kubectl get pods -n <namespace> -l app=mysql
kubectl logs -n <namespace> <pod> --tail=100
kubectl get svc -n <namespace> mysql
kubectl get networkpolicy -n <namespace>
五、认证与权限问题
5.1 用户白名单限制(错误 1130)
SELECT user, host FROM mysql.user WHERE user = 'app_user';
如果客户端来源 IP 不在已授权的 host 范围内,需添加授权:
-- 创建用户时指定来源
CREATE USER 'app_user'@'192.168.1.%' IDENTIFIED BY 'password';
GRANT SELECT, INSERT ON db.* TO 'app_user'@'192.168.1.%';
5.2 密码认证失败(错误 1045)
排查步骤:
- 确认密码正确性
- 检查账号是否被锁定(MySQL 8.0.19+):
SELECT user, host, account_locked, password_expired FROM mysql.user WHERE user = 'app_user';
- 检查认证插件兼容性:
SELECT user, host, plugin FROM mysql.user WHERE user = 'app_user';
MySQL 8.0 默认
caching_sha2_password,老版本客户端驱动不支持会报握手异常。
修复锁定:
ALTER USER 'app_user'@'10.0.0.%' ACCOUNT UNLOCK;
修复认证插件兼容性(过渡方案):
ALTER USER 'app_user'@'10.0.0.%' IDENTIFIED WITH mysql_native_password BY '原密码';
5.3 连接数耗尽(错误 1040)
SHOW VARIABLES LIKE 'max_connections';
SHOW STATUS LIKE 'Threads_connected';
SHOW STATUS LIKE 'Max_used_connections';
查看连接来源分布:
SELECT db, user, host, COUNT(*) AS cnt
FROM information_schema.processlist
GROUP BY db, user, host
ORDER BY cnt DESC LIMIT 10;
调大 max_connections 只是临时缓解,治本需排查应用端连接池配置和连接泄漏。
5.4 连接中途断开(错误 2013)
| 场景 | 检查参数 |
|---|---|
| 大查询/大导入时断开 | max_allowed_packet(默认 4MB) |
| 空闲一段时间后断开 | wait_timeout / interactive_timeout |
SHOW VARIABLES LIKE 'max_allowed_packet';
SHOW VARIABLES LIKE 'wait_timeout';
SHOW VARIABLES LIKE 'interactive_timeout';
根本修复:连接池启用连接有效性检测(如
testOnBorrow),而非一味调大 wait_timeout。
六、根因归纳表
| 现象 | 根因 | 修复 |
|---|---|---|
| 2002 + 服务未运行 | 服务故障 | 查服务状态和错误日志 |
| 2002 + 服务运行中 | socket 路径或权限 | 查配置和目录权限 |
| 2003 (111) | 端口无监听/防火墙 REJECT | ss -ltnp 查监听 |
| 2003 (110) | 网络不通/安全组 DROP | telnet/nc 查连通 |
| 1130 | 白名单不匹配 | 查 mysql.user host 字段 |
| 1045 | 密码错误/锁定/插件不兼容 | 分别验证 |
| 1040 | 连接数耗尽 | 查 processlist 分布 |
| 2013 | 查询断开看 max_allowed_packet,空闲断开看 wait_timeout | 针对性调整 |
七、修复与验证流程
- 本机 socket 验证 — 排除网络因素
- 客户端网段 telnet/nc — 确认网络层通
- 实际账号登录验证:
mysql -h <MySQL服务器IP> -P 3306 -u app_user -p -e "SELECT 1;"
- 权限验证 — 执行一次实际业务 SQL(不仅是 SELECT 1)
- 持续观察 — 连接数、内存使用率
八、高风险操作原则
| 操作 | 注意事项 |
|---|---|
| 重启 MySQL | 检查无大事务/长 DDL;先重启从库验证;低峰期操作 |
| 防火墙放通 3306 | 优先 --source 限定来源网段,避免暴露公网 |
| 调大 max_connections | 评估内存开销;先用 SET GLOBAL 临时调整观察 |
| 账号解锁 | 先确认失败来源 IP 是否异常,防暴力破解 |
九、复盘与预防
- 新环境部署后做标准化连通性验证清单(本地 socket + 跨网段 TCP + 业务账号登录)
- bind-address、白名单、防火墙规则变更要记录文档
- 应用连接池配置与数据库端 max_connections/wait_timeout 匹配设计
- 部署连接数监控(mysqld_exporter → Prometheus)
- 账号锁定机制需配合来源 IP 分析,防拒绝服务攻击
关联页面
| 页面 | 关联点 |
|---|---|
| mysql-performance-config | MySQL 性能调优:慢查询/锁分析/索引失效 |
| mysql-replication-guide | MySQL 主从复制原理与故障排查 |
| mysql-disk-space-cleanup-guide | MySQL 磁盘空间不足时的安全清理指南 |
| mysql-slow-query-case-study | MySQL 慢查询排查案例复盘 |
| mysql-backup-selection-guide | MySQL 备份方案完整工程手册 |