MySQL报错“Access denied”时,应先确认用户是否存在、密码是否正确、Host是否匹配,再检查权限、bind-address、认证插件、账户状态及SQL_MODE等。

检查用户是否存在且密码正确
MySQL 报错 Access denied for user 'xxx'@'xxx' 时,第一件事不是调权限,而是确认这个用户真正在 mysql.user 表里、密码没输错、也没被意外删除。
- 用 root 登录后执行:
SELECT User, Host FROM mysql.user WHERE User = 'your_user';
- 注意
Host字段必须匹配——'user'@'localhost'和'user'@'127.0.0.1'是两个不同用户,前者走 Unix socket,后者走 TCP - 如果用户存在但密码忘了,别用
UPDATE mysql.user直接改authentication_string,优先用ALTER USER 'user'@'host' IDENTIFIED BY 'newpass';
确认权限是否已生效且范围匹配
执行了 GRANT 不代表立刻生效,也不代表权限覆盖你当前连接的 Host 和数据库名。
- 查权限:运行
SHOW GRANTS FOR 'user'@'host';
,看输出里有没有你期望的库/表级权限(比如GRANT SELECT ON `mydb`.* TO ...) - 注意通配符:如果只给了
GRANT SELECT ON *.*,那可以访问所有库;但若写成GRANT SELECT ON mydb.*,就不能访问otherdb - 权限变更后必须执行
FLUSH PRIVILEGES;——不过更推荐重启 mysqld 或直接用ALTER USER/GRANT,它们会自动刷新内存权限缓存
验证连接方式与 bind-address 冲突
用户权限全对,还是连不上?很可能是网络层拦住了。
- 检查 MySQL 配置:
bind-address默认是127.0.0.1或localhost,这意味着只接受本地回环连接;远程用户需要设为0.0.0.0或具体 IP,且防火墙放行 3306 端口 - 确认客户端连接时用的 host 是否和
GRANT中的Host一致:用mysql -h 127.0.0.1 -u user -p连,就要求有'user'@'127.0.0.1'权限;用mysql -h localhost连,则匹配'user'@'localhost' - 某些 MySQL 版本(如 8.0+)默认启用
caching_sha2_password插件,老客户端可能不兼容,可临时改用:ALTER USER 'user'@'host' IDENTIFIED WITH mysql_native_password BY 'pass';
排查 SQL_MODE 和账户状态限制
权限和连接都对,但一执行查询就报错?可能是账户被锁或 SQL_MODE 拦截了隐式操作。
- 检查账户是否过期或锁定:
SELECT User, Host, account_locked, password_expired FROM mysql.user WHERE User = 'your_user';
若account_locked是Y,需执行ALTER USER 'user'@'host' ACCOUNT UNLOCK; - 有些权限(如
CREATE TEMPORARY TABLES)在严格 SQL_MODE 下会被拒绝,尤其是开启STRICT_TRANS_TABLES时,建议先用SELECT @@sql_mode;查当前模式 - 如果用户只能访问特定库,但代码里写了
USE otherdb;或跨库查询(如SELECT * FROM otherdb.table),即使有该库权限,也可能因未显式授权而失败
实际中最容易卡住的地方,是 Host 匹配和 bind-address 配置这两个点——它们不在权限表里,却决定连接能否建立。先确认你能连上,再谈能不能查。










