数据库连接调试步骤详解
项目做到一半,突然连不上数据库,页面报错“无法连接数据库”或者“Connection refused”,这种问题开发人员几乎都遇到过。别急,按步骤一步步排查,通常很快就能定位问题所在。
检查网络是否通畅
如果数据库部署在远程服务器上,第一步先确认网络能不能通。比如你本地写代码,数据库在公司内网的某台机器上,那得先 ping 一下数据库服务器的 IP 地址。
ping 192.168.10.50如果 ping 不通,可能是网络配置、防火墙或路由器规则的问题。也有可能是数据库服务器宕机了。这时候可以问问运维同事,是不是服务器出问题了,或者自己登录服务器看看状态。
确认数据库服务是否运行
即使网络通了,数据库服务本身没启动也白搭。比如 MySQL、PostgreSQL 这类服务,有时候重启系统后没自动启动。
登录数据库服务器,执行命令查看服务状态:
systemctl status mysql如果是 PostgreSQL:
systemctl status postgresql如果看到 inactive 或者 dead,那就手动启动:
systemctl start mysql检查端口监听情况
数据库服务虽然启动了,但可能没监听正确的端口,或者只监听了本地(127.0.0.1),导致外部连不上。
用 netstat 查看端口占用情况:
netstat -tuln | grep 3306正常应该看到类似 0.0.0.0:3306 或 :::3306 的监听状态。如果只看到 127.0.0.1:3306,说明只能本机访问,需要修改数据库配置文件,比如 MySQL 的 my.cnf 中的 bind-address 设置为 0.0.0.0。
验证用户名和密码
有时候程序配置的是 test/test123,但数据库里实际用户是 root/rootpass,这种低级错误也不少见。尤其是测试环境交接时,文档没更新,新人直接照抄配置就容易出问题。
可以手动用命令行登录试试:
mysql -h 192.168.10.50 -u root -p输完密码后能进入 MySQL 命令行,说明账号密码没问题。如果提示 Access denied,那就得去数据库查 user 表,确认用户是否存在、密码是否正确、是否允许从当前 IP 登录。
检查数据库远程访问权限
MySQL 默认安装后,root 用户通常只允许本地登录。如果你是从办公室电脑连公司的数据库,IP 不在授权范围内,自然连不上。
登录数据库后执行:
SELECT host, user FROM mysql.user WHERE user = 'root';如果 host 是 localhost,就得改权限:
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'your_password';
FLUSH PRIVILEGES;这样 root 就可以从任意 IP 登录了(生产环境慎用 %,建议指定具体 IP)。
查看应用程序配置文件
代码里的配置写错了也是常见原因。比如把 port 写成 3307,或者 host 写成了 dbserver 而不是 dbserver.local,DNS 解析失败。
检查项目的配置文件,比如 application.yml:
spring:
datasource:
url: jdbc:mysql://192.168.10.50:3306/mydb?useSSL=false&serverTimezone=UTC
username: root
password: wrongpass
driver-class-name: com.mysql.cj.jdbc.Driver注意 URL 拼写、端口号、数据库名、时区参数,还有密码是不是复制错了。有时候多一个空格都会导致连接失败。
启用数据库日志辅助排查
如果前面都检查过了还是连不上,可以打开数据库的错误日志。MySQL 的日志通常在 /var/log/mysql/error.log 或通过配置文件指定的位置。
查看日志内容:
tail -f /var/log/mysql/error.log然后在应用端再试一次连接,观察日志有没有新的错误记录。比如出现“Too many connections”或者“Host is blocked”,就知道是连接数超限或被临时封禁了。
使用 telnet 测试端口连通性
在客户端机器上,可以用 telnet 看看数据库端口能不能通:
telnet 192.168.10.50 3306如果卡住或者提示连接失败,说明中间有防火墙拦截。可能是服务器的 iptables 规则,也可能是云服务商的安全组策略。比如阿里云 ECS 需要在控制台开放 3306 端口的入方向规则。
这类问题在云环境特别常见,明明配置都对,就是连不上,最后发现是安全组没开端口。