“access denied”错误主因是用户主机组合不匹配,而非密码错误;需核对select user,host from mysql.user结果与连接时的'user'@'host'是否完全一致,并检查bind-address、防火墙、安全组及认证插件兼容性。

“Access denied”不是密码错了,而是 MySQL 根本没让你走到输密码那步——它直接拒绝了 'user'@'host' 这个组合的连接请求。
查清楚你连的是哪个 'user'@'host' 组合
错误信息里写的 'root'@'192.168.1.100' 或 'app'@'localhost' 就是真实匹配目标。MySQL 把它们当完全不同的账号处理:
-
'localhost'走 Unix socket,'127.0.0.1'走 TCP,两者不等价 - 只创建了
'dev'@'localhost',却用mysql -h 127.0.0.1 -u dev连,必报错 - 远程连接必须显式存在
'dev'@'%'或'dev'@'192.168.1.%',不能靠“本地能连”来推断
登录 MySQL 后执行:
SELECT User, Host FROM mysql.user WHERE User = 'dev';看结果是否和你连接时的 host 完全一致。
授权后权限没生效?重点盯 FLUSH PRIVILEGES 和认证插件
用 GRANT 创建用户通常自动生效,但以下情况必须手动刷新:
- 直接
UPDATE mysql.user改了Host或authentication_string - 执行完
CREATE USER+GRANT后仍连不上,先验证:SHOW GRANTS FOR 'dev'@'%';—— 返回空就说明权限根本没加载 - MySQL 8.0+ 默认用
caching_sha2_password,老版 Navicat、PHP 5.x、某些 Docker 镜像不兼容;临时切回:ALTER USER 'dev'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd';
连都连不到?检查 bind_address、防火墙和云平台安全组
哪怕用户和权限全对,只要这三者之一卡住,最终也报 Access denied(不是 Connection refused):
- 运行
netstat -tlnp | grep :3306,如果只显示127.0.0.1:3306,说明bind_address = 127.0.0.1没改 - Linux 本地防火墙:确认
3306端口放行(sudo ufw allow 3306或iptables规则) - 云服务器(阿里云/腾讯云)必须进控制台配安全组,只开本地防火墙没用
最容易被忽略的细节:Host 匹配是精确字符串匹配
'user'@'%.example.com' 不会匹配 IP 地址 192.168.1.100;'user'@'192.168.1.%' 也不会匹配 IPv6 地址 ::1。别猜,要查:
- 连不上时立刻查日志:
/var/log/mysql/error.log,里面常有更细的拒绝原因(比如 “no matching entry in user table”) - 用
SELECT USER(), CURRENT_USER();看 MySQL 实际认定你是谁——CURRENT_USER()才是权限校验依据 - 容器或云数据库环境里,
host往往是网关 IP 或%,不是localhost











