数据库连接失败怎么排查
应用连不上数据库,报错原文其实已经把排查范围缩小到某一层:连接被拒(refused)说明目标端口没有监听或访问被拒,方向是服务状态、监听地址与端口;访问被拒绝(Access denied)说明连上了但账号授权不足;超时说明链路或规则拦截;连接数过多说明并发上限被占满。按报错分层处理,比从应用代码开始猜要快得多。
基本信息
| 服务检查 | systemctl status 查看数据库实例状态 |
|---|---|
| 监听检查 | ss -lntp 查看端口与绑定地址 |
| 链路测试 | 从应用主机测试端口可达性 |
| 授权检查 | 查询账号与其允许的来源主机 |
| 服务端日志 | 数据库错误日志通常直接写明原因 |
典型使用场景
- 应用启动报连接数据库失败,需要快速分层定位
- 数据库迁移或重启后应用无法连接,核对监听地址变化
- 新增应用主机后连接失败,通常是来源授权未加白名单
- 并发高峰出现连接数超限报错,需要评估连接池与上限
- 核对账号授权范围,确认主机字段是否覆盖应用网段
- 排查网络设备变更后连接超时,验证防火墙与安全组
服务与网络层
服务与网络层
systemctl status mysqld --no-pager | head # 服务名按实际替换
ss -lntp | grep -E '3306|5432' # 监听端口与地址
# 从应用主机测试端口可达性:
timeout 3 bash -c '</dev/tcp/<数据库IP>/3306' && echo ok || echo fail
firewall-cmd --list-all 2>/dev/null | grep -iE '3306|mysql' # 防火墙放行
mysql -uroot -p -e 'SELECT user,host FROM mysql.user' # 账号与来源
mysql -uroot -p -e "SHOW GRANTS FOR '<用户>'@'<来源>'" # 授权范围
tail -50 /var/log/mysqld.log 2>/dev/null | grep -iE 'error|denied|refus'报错分层对照
| 报错关键词 | 所在层 | 处理方向 |
|---|---|---|
| Connection refused | 服务或端口 | 启服务、查监听地址与端口 |
| Access denied | 账号与授权 | 核对账号、口令与来源主机 |
| Connection timed out | 网络与规则 | 检查链路、防火墙与安全组 |
| Too many connections | 并发与上限 | 调整连接池与最大连接数 |
| Unknown database | 目标库配置 | 核对连接串中的库名是否存在 |
数据库默认只监听本机地址的情况很常见,外部应用连不上时先确认监听地址,再决定是否调整监听配置;这一步比反复改应用连接串更有效。
只测端口不看服务端日志容易漏掉根因:数据库错误日志里常直接写明认证失败、来源不允许或资源不足,优先读取服务端记录。