数据库 Access denied 与 can't connect 的区别
发布时间:2026-04-10 20:00       
更新时间:2026-04-11 15:29
Access denied 和 can't connect 看着都是"连不上",实际指向两个方向:前者网络已经通了,是账号认证被拒绝;后者请求根本没到达数据库。排查之前先分清这一点,能少走很多弯路。
## 为什么会报 Access denied
MySQL(常见的关系型数据库)返回 1045 错误码时,说明 mysqld 进程活着、端口也通,卡在认证环节。常见原因有三类:密码错误;账号不存在;账号限制了来源地址。MySQL 的账号由"用户名+来源主机"共同构成,app@192.168.1.% 和 app@% 是两个不同账号,本机能登不代表远程也能登。
先在服务器本机验证账号密码:
mysql -u app -p -h 127.0.0.1
本机能进而远程报 Access denied,就查账号的 host 范围:
SELECT user,host FROM mysql.user WHERE user='app';
必要时补一条允许内网网段的账号再授权:
CREATE USER 'app'@'10.0.%' IDENTIFIED BY '强密码';
GRANT ALL ON mydb.* TO 'app'@'10.0.%';
FLUSH PRIVILEGES;
还有一类隐蔽情况:密码里带特殊字符,命令行不加引号会被 shell 转义,传到数据库的已经不是原密码。用单引号把密码包裹起来再试,能排除一大半"明明密码没错"的案例。
## can't connect 卡在哪一步
这类报错出现在连接建立之前,错误码常见 2003,伴随 connection refused 或直接超时。可能性按顺序排:数据库进程没起来;只监听 127.0.0.1,拒绝了外部地址;3306 端口被防火墙或安全组拦住。
用两条命令缩小范围:
systemctl status mysqld
ss -lntp | grep 3306
第二行输出如果显示 127.0.0.1:3306,说明绑定地址有问题,把配置文件里的 bind-address 改成 0.0.0.0 或内网 IP,重启后生效。端口监听正常仍超时,就往防火墙和安全组方向查。
云环境里还要多看一层:安全组只放行了 SSH、没放 3306,现象同样是超时。数据库端口不必对公网开放,按需最小化放行即可。另有一种剧本:数据库装了却没设开机自启,服务器重启后 mysqld 没跟上来,systemctl enable mysqld 顺手开上,重启场景就少一类事故。
## 实际排查怎么分叉
判断标准很朴素:能 telnet 通 3306 端口却报 Access denied,走认证排查;telnet 直接超时或拒绝,走网络排查。
telnet 10.0.0.5 3306
预防上,给应用配独立账号、只授予必需库的权限、host 尽量收敛到内网网段,比图省事直接用 root 加 % 稳妥得多。顺带记一条边界:报错原文永远比猜测可靠,把错误码记下来再动手,比在配置里乱试一通效率高得多。