error 1045 是连接阶段的认证失败,非权限问题;因用户名、密码或 host 不匹配,或认证插件不兼容导致,发生在身份验证环节而非权限检查环节。

MySQL 报错 1045 是认证失败,不是权限不足——根本原因是用户名或密码不被服务器接受,而不是用户没有某张表的 SELECT 权限。
为什么 ERROR 1045 (28000) 不是权限问题?
这个错误的完整提示通常是:Access denied for user 'xxx'@'yyy' (using password: YES/NO)。它发生在连接阶段,MySQL 还没走到“检查你有没有权限执行某条 SQL”的环节,连用户身份都没验过。
-
using password: YES表示客户端传了密码,但服务端查不到匹配的user+host+authentication_string记录 -
using password: NO表示客户端根本没传密码,但该用户在mysql.user表里要求密码(authentication_string非空) - 常见诱因:root 密码被重置后未刷新权限、用 localhost 连却只建了 'user'@'%'、MySQL 8.0 默认用
caching_sha2_password插件但客户端不支持
检查 mysql.user 表里的实际账户记录
必须用已有高权限账号(比如已知能登录的 root)进到 MySQL 后执行:
SELECT host, user, authentication_string, plugin FROM mysql.user WHERE user = 'your_username';
重点看三列:
-
host:注意'localhost'和'127.0.0.1'在 MySQL 里是两个不同账户,Unix socket 连接认localhost,TCP 连接认127.0.0.1 -
authentication_string:为空表示无密码;非空但长度不是 41 位(老版 MySQL)或 60+ 位(MySQL 8.0+ SHA2),可能已被异常清空或损坏 -
plugin:MySQL 8.0 默认是caching_sha2_password,如果用老版本客户端(如 MySQL 5.7 客户端、某些 PHP PDO 驱动),需改成mysql_native_password
重置密码时必须 FLUSH PRIVILEGES 吗?
不一定。用 ALTER USER 或 SET PASSWORD 修改密码后,新密码立即生效,不需要 FLUSH PRIVILEGES;但如果你直接 UPDATE mysql.user 表并 SET authentication_string = ...,就必须执行 FLUSH PRIVILEGES 才能让内存缓存同步。
- 安全做法:优先用
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'newpass'; - 避免直改表:除非进入安全模式(
mysqld --skip-grant-tables),否则直接UPDATE mysql.user可能因权限校验机制导致写入失败或不一致 - MySQL 8.0 注意:不能用
password()函数加密,必须用SHA2('xxx',256)或让ALTER USER自动处理
本地连接报 1045 却确定密码没错?试试 127.0.0.1 替代 localhost
这是最常被忽略的点。很多客户端库(包括 mysql 命令行工具)默认把 localhost 解析为 Unix socket 连接,而 socket 连接只认 'user'@'localhost' 账户;但如果你只创建了 'user'@'%',那用 localhost 就永远连不上。
- 验证方式:用
mysql -h 127.0.0.1 -u your_user -p强制走 TCP,看是否成功 - 临时解决:加一个
'user'@'localhost'账户,或统一用'user'@'127.0.0.1'(但注意这会限制只能本机 IP 连) - 长期建议:开发环境明确区分连接方式,生产环境用
'user'@'app-server-ip'而非'%'
真正卡住人的往往不是密码记错,而是 host 匹配规则和认证插件这两个隐形开关。先查 mysql.user,再比对连接时用的 host 和客户端能力,比盲目重置密码快得多。










