mysql 5.7 升级到 8.0 必须修改:避开 --all-databases 导出系统库、删 sql_mode 中 no_auto_create_user、myisam 替换为 innodb、关键字字段加反引号、group by 必须显式 order by、认证插件兼容处理。

直接说结论:不是“能不能升”,而是“哪些地方不改就必然报错”。MySQL 5.7 到 8.0 是一次有明确断裂点的升级,跳过校验直接导入 SQL 文件,90% 的概率在 mysql.user 表或 GROUP BY 查询上卡住。
导出时必须避开 --all-databases
这是最常被忽略、也最致命的操作。5.7 的 mysqldump --all-databases 会把 mysql 系统库一起导出,而 8.0 的 mysql.user 表结构已变:password 字段没了,换成 authentication_string;plugin 默认值也不同。恢复后权限系统直接瘫痪,连 root 都登不上。
- 只导业务库:
mysqldump -u root -p --databases myapp_db --default-character-set=utf8mb4 > myapp.sql - 导出后手动删掉 SQL 文件开头的
SET sql_mode = '...'行(尤其含NO_AUTO_CREATE_USER的) - 全局搜索
ENGINE=MyISAM,替换成ENGINE=InnoDB(8.0 不允许 MyISAM 用于系统表,且已不推荐)
rank、json、group 这类字段名必须加反引号
MySQL 8.0 新增了至少 12 个保留关键字,rank 是最典型的一个。5.7 能跑的 SELECT @r:=@r+1 AS rank,到 8.0 直接报 ERROR 1064 (42000) —— 不是语法错,是关键字冲突。
- 所有疑似关键字的列名、别名、表名,一律用反引号包住:
SELECT @r:=@r+1 AS `rank` - 检查现有建表语句:
SHOW CREATE TABLE your_table,看有没有撞上JSON、ROW_NUMBER、VISIBLE等新保留字 - ORM 自动生成的 SQL 如果没加反引号,升级后要同步改模板或加 escape logic
GROUP BY 结果不再自动排序
5.7 中 GROUP BY a 默认等价于 GROUP BY a ORDER BY a,很多业务代码隐式依赖这个行为。8.0 彻底取消隐式排序,GROUP BY 后如果不显式写 ORDER BY,返回顺序完全不确定——前端分页错乱、导出数据每次都不一样,都是这个原因。
- 所有生产环境的
GROUP BY查询,必须补全ORDER BY子句 - 特别注意聚合 + 排序混用场景,例如:
SELECT user_id, COUNT(*) c FROM t GROUP BY user_id ORDER BY c DESC - 测试阶段用
SELECT @@sql_mode确认是否含ONLY_FULL_GROUP_BY,它会让“非 group by 字段出现在 select 列表”直接报错
连接报 Authentication plugin 'caching_sha2_password' cannot be loaded
这是升级后第一波报错高峰。8.0 默认认证插件从 mysql_native_password 换成 caching_sha2_password,但老版本 JDBC(mysql-connector-java )、PHP <code>mysqlnd、Navicat 12 以下都认不了。
- 临时解法(仅限过渡):
ALTER USER 'your_user'@'%' IDENTIFIED WITH mysql_native_password BY 'xxx'; - 长期方案:升级客户端驱动,并在 JDBC URL 加参数:
?serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false - 注意:MySQL 8.4 已彻底移除
mysql_native_password,现在不处理,后面升级成本更高
真正麻烦的不是单个错误,而是多个变更叠加:比如一个用了 rank 别名的 GROUP BY 查询,在 8.0 上既因关键字报错,又因缺 ORDER BY 导致结果不可靠,还可能因驱动不兼容连不上数据库——得一层层剥开验证,不能只盯着日志第一行。











