数据库连接失败排查方法:按这六步从网络查到配置
凌晨遇到 Communications link failure 或 Access denied 报错时,先别急着重启数据库。这套数据库连接失败排查方法从网络连通、服务状态、账号权限、连接数、防火墙到超时配置逐个环节验证,附带可直接执行的诊断命令,帮你在线上环
凌晨告警群里弹出几十条 SQLException:Communications link failure、Access denied、Connection refused……这时候最怕手忙脚乱。其实绝大多数连接故障逃不出六个环节,按顺序排查,通常十分钟内就能定位根因。
第一步:先看网络通不通
在应用服务器上直接执行 telnet 数据库IP 端口。不通的话,先确认两边是不是同一个 VPC,跨地域有没有走对专线或 VPN。有时候端口能 telnet 通但瞬间被断开,大概率是安全组或防火墙在中间拦了一道,别急着去动数据库配置。
第二步:确认数据库进程状态
能连上主机就看服务状态:systemctl status mysqld 或者 ss -tlnp | grep 3306。没监听的话,去翻错误日志。线上遇到过最多的是磁盘写满导致 MySQL 直接拒绝启动,或者是改完配置重启时报错没起来。先把配置回滚,把服务拉起来再说。
第三步:验证账号登录权限
报错是 Access denied 时,别光猜密码。先在数据库服务器本地用 mysql -h127.0.0.1 -u用户 -p 试一遍。本地能进、远程不行,去查 mysql.user 表里的 host 字段,很多时候是只允许了 localhost,没加应用服务器的 IP 段。
如果命令行也登不上,确认密码有没有过期、账号是否被锁。改完权限记得执行 FLUSH PRIVILEGES。另外检查应用配置文件里的密码有没有特殊字符没转义,比如 @、# 在连接 URL 里容易出问题。
第四步:排查连接数是否打满
Too many connections 这种报错太常见。进数据库先看 SHOW PROCESSLIST,如果大量 Sleep 状态的空闲连接占着坑,多半是应用连接池配置不合理,最小空闲数设得太大。可以临时执行 set global max_connections=500 顶一下,但根本办法是调小连接池的最大空闲时间,同时把 wait_timeout 和 interactive_timeout 降到合理值,别让僵尸连接一直挂着。
第五步:检查安全组与本地防火墙
云环境里,安全组规则是重灾区。数据库实例的入方向必须显式放行应用服务器的安全组 ID 或 IP 段,端口要对(3306、5432 等)。两边不在同一个安全组时,千万别以为同账号就默认互通。
同时扫一眼 iptables -L -n,有些机器本地防火墙还开着。如果用了云防火墙或者运营商 NAT,长连接可能被静默丢弃,抓个包看有没有 RST 或重传,比盲猜快得多。
第六步:核对超时与连接池配置
连接不是瞬间断掉,而是报 timeout,先测一下网络延迟。跨地域访问时,MySQL 默认的 connect_timeout 10 秒可能不够,适当加大。更重要的是连接池要开启探活,比如 HikariCP 的 connectionTestQuery 或 keepalive 参数,不然数据库端 wait_timeout 一到把连接杀了,应用池子里还拿着死连接,下次取出直接报错。
另外,connect_timeout 和 wait_timeout 两边要匹配,不要一个设 30 秒一个设 8 小时,中间断层最容易出灵异问题。