检查用户是否存在且密码正确
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配置这两个点——它们不在权限表里,却决定连接能否建立。先确认你能连上,再谈能不能查。
