mysql 5.7 升级到 8.0 后权限报错主因是系统表结构未升级、认证插件不兼容、动态权限/角色未显式授予及权限元数据损坏,需执行 mysqld --upgrade=force、调整 plugin、显式授权角色与动态权限,并修复 file 等默认禁用权限。

MySQL 5.7 升级到 8.0 后权限报错,根本不是“权限丢了”,而是 mysql 系统库的表结构、字段定义、默认行为全变了——旧数据没被正确迁移或适配,就会触发 Access denied、Unknown column 或 SHOW GRANTS 显示异常但实际不生效。
权限表结构不匹配:先看 mysql.user 缺不缺字段
升级后第一件事不是改用户,是确认系统表是否真正升级完成:
-
SELECT VERSION();确认已是 8.0.x(如 8.0.32) -
DESC mysql.user;检查是否存在plugin、authentication_string字段,且Password字段已消失 —— 若缺失或报Unknown column 'plugin',说明mysql_upgrade没跑或失败 - MySQL 8.0.16+ 不再支持
mysql_upgrade工具,必须用mysqld --upgrade=FORCE启动一次,否则user表仍为 5.7 结构,所有授权逻辑都会错乱 - 如果已跳过这步就直接启用了服务,需停库后加
--upgrade=FORCE再启动,不能靠FLUSH PRIVILEGES补救
认证插件不兼容:caching_sha2_password 导致连得上但权限无效
很多报错看起来像权限问题,其实是认证层没过——连接成功但 SHOW GRANTS 为空或不准,典型症状:
MySQL 9.6.0是面向Linux平台的2026年创新版本,核心架构迎来重大革新。其将外键约束与级联操作从InnoDB引擎层上移至SQL层,确保所有数据变更均被完整记录至Binlog,彻底解决了CDC(变更数据捕获)与主从复制中的数据不一致难题。此外,该版本引入container_aware启动选项以原生适配容器环境,并对审计日志进行了组件化重构,为追求极致数据一致性与云原生体验的开发者提供了全新选择。
- 客户端报
SQLSTATE[HY000] [2054] The server requested authentication method unknown to the client - 用 root 登录后执行
SELECT User, Host, plugin FROM mysql.user;发现老用户 plugin 是caching_sha2_password,但应用用的是旧版驱动(如 MySQLdb、Navicat 旧版、PHP 7.4 自带 mysqlnd) - 临时修复用
ALTER USER 'xxx'@'%' IDENTIFIED WITH mysql_native_password BY 'pwd';,但注意:这只改认证方式,不改密码哈希值;若原密码是 SHA2 加密,降级后可能无法解出明文,建议重置密码 - 生产环境不要全局改
default_authentication_plugin,它只影响新用户,已有用户仍保持原 plugin,必须逐个ALTER USER
SHOW GRANTS 正常但 SQL 执行失败:动态权限与角色未显式授予
MySQL 8.0 引入了角色(ROLE)和动态权限(如 BACKUP_ADMIN、CLONE_ADMIN),它们不会出现在传统 SHOW GRANTS 输出里,但缺失会导致特定操作失败:
- 执行
BACKUP DATABASE xxx报Access denied for user?检查是否授予了BACKUP_ADMIN动态权限:GRANT BACKUP_ADMIN ON *.* TO 'u'@'%'; - 用
CREATE ROLE r1; GRANT SELECT ON db.t TO r1;创建角色后,必须显式GRANT r1 TO 'u'@'%';并执行SET DEFAULT ROLE r1 TO 'u'@'%';,否则角色权限不激活 -
SHOW GRANTS FOR 'u'@'%'不会列出角色权限,得用SHOW GRANTS FOR 'u'@'%' USING r1;查看角色继承的权限 - 部分旧备份脚本导出的
GRANT语句含WITH GRANT OPTION但没带AS子句,在 8.0 中会被忽略,需手动补全
权限元数据损坏:别信 FLUSH PRIVILEGES 能修好一切
升级后发现部分用户权限时有时无,或者 FLUSH PRIVILEGES 后反而更乱,大概率是权限表本身有损坏或字段映射错误:
-
FLUSH PRIVILEGES只是重载内存缓存,不修复磁盘上的表结构缺陷;若mysql.db表中Db字段长度不足(如被意外改成VARCHAR(32)),可能导致库名截断,权限失效 - 批量修复前,先用
mysqldump --skip-triggers --compact mysql user db tables_priv columns_priv procs_priv > perms.sql导出干净权限语句,注意清理掉PASSWORD('xxx')这类 5.7 语法,替换为authentication_string值 - 导入前确保目标库已运行过
--upgrade=FORCE,否则INSERT INTO mysql.user会因字段数不匹配而失败 - 最易被忽略的一点:8.0 默认禁用
FILE权限,root 用户升级后也丢失该权限,需手动GRANT FILE ON *.* TO 'root'@'localhost';才能用LOAD DATA INFILE










