MySQL 8.0权限失效源于user@host精确匹配、caching_sha2_password插件不兼容及mysql.user变为只读视图三处断裂,必须分别核查Host值、ALTER USER切换认证插件并用GRANT/REVOKE授予权限,不可直接UPDATE表。

权限失效不是“丢了”,而是 MySQL 8.0 拒绝按旧规则解释你存的那些权限数据——根本原因在 user@host 匹配逻辑、认证插件、系统表结构三处断裂,不修复就永远连不上、授不了权。
user@host 从模糊匹配变成精确字符串匹配
MySQL 5.7 会把 'admin'@'localhost' 和 'admin'@'127.0.0.1' 当成差不多的连接来源,8.0 则完全分开处理:它们是两个独立账户,权限互不继承,也不 fallback。
- 应用用 JDBC 连
jdbc:mysql://127.0.0.1:3306/db,但你只给'admin'@'localhost'授了权?那就 Access denied - Navicat 默认走 TCP(即
@'127.0.0.1'),而你只创建了@'localhost'?连都连不上 - 执行
SELECT User, Host FROM mysql.user;看到一堆同名不同 Host 的记录,别删——它们各自负责不同连接路径
caching_sha2_password 插件导致客户端压根无法完成认证
升级后用户账号的 plugin 字段大概率是 caching_sha2_password,但老客户端(PHP 7.4 mysqli、JDBC 5.x、Navicat 12、Node.js mysql)根本不认识它,报错如 Authentication plugin 'caching_sha2_password' cannot be loaded 或 ER_NOT_SUPPORTED_AUTH_MODE。
- 这不是密码错了,是客户端连握手阶段就失败了
- 用
SELECT User, Host, plugin FROM mysql.user WHERE User = 'your_user';确认插件值 - 临时兼容:执行
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd';,再FLUSH PRIVILEGES; - 注意 Host 必须和实际连接来源一致,
'your_user'@'192.168.1.100'和'your_user'@'%'是两回事
mysql.user 不再是可写的表,直接 UPDATE 会静默失败
MySQL 8.0 把 mysql.user 改成了只读视图,背后由 InnoDB 表 + 数据字典支撑。任何 INSERT INTO mysql.user 或 UPDATE mysql.user SET Select_priv = 'Y' 都会报错 ERROR 1356 (HY000): View 'mysql.user' references invalid table(s),且不会提示你哪里错了。
- 权限必须用
GRANT/REVOKE或ALTER USER修改,这是唯一合法途径 - 旧备份脚本若含
mysqldump --all-databases并还原了 mysql 库,会导致权限字段被置空(比如Select_priv变成 NULL) - 升级前导出权限要用
SHOW GRANTS FOR 'u'@'h';,而不是 dump 整个 mysql 库
最常被忽略的是:你看到 Access denied for user 'xxx'@'localhost',但实际连接来源可能是 127.0.0.1;你改了 plugin 却仍连不上,大概率是 FLUSH PRIVILEGES; 漏了,或 Host 写错了。这些点不逐个核对,光重启服务或重设密码毫无意义。


















