mysql 5.7 升级到 8.0 后权限系统最直接的破坏性变化是用户标识匹配更严格、默认认证插件不兼容旧驱动、系统权限表不可直写;localhost 与 127.0.0.1 不再等价,caching_sha2_password 导致旧客户端连接失败,mysql.user 已变为只读视图,必须用 alter user/grant 等标准语句管理权限。

MySQL 5.7 升级到 8.0 后,权限系统最直接的破坏性变化是:用户标识(user@host)匹配更严格、默认认证插件不兼容旧驱动、系统权限表不可直写——这三个点不处理,连不上库是常态,不是偶然。
user@host 匹配不再“模糊”:localhost ≠ 127.0.0.1 ≠ %
MySQL 8.0 把 'ODBC'@'localhost'、'ODBC'@'127.0.0.1'、'ODBC'@'%' 当作三个完全独立的账户,不会自动 fallback。
- 用
mysql -h localhost -u ODBC连,走的是 UNIX socket(或 Windows 命名管道),只匹配@'localhost'条目 - 用
mysql -h 127.0.0.1 -u ODBC连,走 TCP/IP,只匹配@'127.0.0.1'或@'%'(如果 host 是通配符) - 某些 ODBC/JDBC 驱动(如老版 Navicat、DBeaver 默认配置)会强制使用
127.0.0.1,哪怕你填的是localhost - 升级后若只给
'ODBC'@'localhost'授权,但应用连的是127.0.0.1,就会报错:Access denied for user 'ODBC'@'localhost'(注意错误里显示的是localhost,但实际请求来源可能是127.0.0.1)
caching_sha2_password 认证插件导致客户端连接失败
MySQL 8.0 默认把所有新用户和升级后的用户认证插件设为 caching_sha2_password,而很多老客户端根本不认识它。
- 典型报错:
Authentication plugin 'caching_sha2_password' cannot be loaded - 受影响范围包括:PHP 7.2 以下 + mysqlnd、Java JDBC 5.x/6.x、Python MySQLdb(非 PyMySQL)、部分 Node.js mysql2 旧版本
- 临时解法是显式改回旧插件:
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password'; - 但要注意:
mysql_native_password在 MySQL 8.4 已被彻底移除,8.0 只是过渡期,长期必须升级驱动 - 别在配置文件里全局设
default_authentication_plugin=mysql_native_password,这会让所有新建用户都继承该插件,掩盖真实兼容性问题
权限表结构变更:不能再直接 INSERT/UPDATE mysql.user
MySQL 8.0 彻底废弃了 MyISAM 系统表,mysql.user 等变成基于 InnoDB 的视图,直接 DML 操作会报错。
- 执行
INSERT INTO mysql.user ...会提示:ERROR 1356 (HY000): View 'mysql.user' references invalid table(s) or column(s) - 所有权限操作必须走 SQL 接口:
CREATE USER、GRANT、DROP USER、ALTER USER - 如果你的应用或运维脚本里有硬编码修改
mysql.user表字段(比如手动更新password_expired字段),升级后全部失效 - 角色(
ROLE)功能在 8.0 正式可用,建议用CREATE ROLE+GRANT role_name TO user替代一堆重复GRANT语句
真正容易被忽略的,是权限变更和字符集、SQL 模式、保留字这些坑交织在一起——比如你修复了认证插件,但用户建在 @'localhost',结果应用因 DNS 解析异常连到了 @'192.168.1.100',又没授权;或者 GRANT 时用了 RANK 列名却忘了加反引号,语句直接语法报错。升级不是单点切换,得当成一次权限拓扑重检。











