mysql 5.7 升级到 8.0 前必须验证 sql_mode 默认值、认证插件、系统表结构、保留关键字冲突,并优先选用 dump & restore 而非 in-place 升级,升级后需调整 default_authentication_plugin、sql_mode 等关键配置,同时关注权限继承和密码过期策略变更。

MySQL 5.7 升级到 8.0 前必须验证的兼容性断点
MySQL 8.0 不是“平滑升级”,而是存在多个**不兼容变更**,跳过校验直接 in-place 升级可能引发服务中断或数据不可读。重点检查以下几类:
-
sql_mode默认值变化:STRICT_TRANS_TABLES在 8.0 中默认启用,而 5.7 可能未开启——这会导致原本插入成功的语句(如空字符串插非空字段)在 8.0 直接报错ERROR 1364 (HY000) - 认证插件变更:8.0 默认使用
caching_sha2_password,5.7 客户端(尤其是老版本 JDBC、PHP mysqlnd)可能不支持,连接时抛出Authentication plugin 'caching_sha2_password' cannot be loaded - 系统表结构升级:
mysql.user表字段大幅调整(如plugin字段长度扩大、新增account_locked),升级后无法降级回 5.7 - 关键字冲突:8.0 新增了
rank、json、group等保留字,若你的表名/列名恰好撞上,查询会报ERROR 1064
升级路径选择:in-place 还是 dump & restore?
官方虽支持 in-place 升级(停机执行 mysqld --upgrade),但生产环境更推荐 mysqldump + 重建方式,原因很实际:
- in-place 升级失败后恢复成本极高,且日志中常出现
InnoDB: Upgrade after a crash is not supported类警告 -
mysqldump --single-transaction --routines --triggers --databases能规避表结构锁,同时导出视图定义和存储过程(注意:8.0 的CREATE VIEW语法更严格,需确认 5.7 导出的 view 定义不含隐式排序) - dump 后在 8.0 实例中导入前,建议先用
mysql_upgrade(8.0.16+ 已弃用)或运行mysql --execute="CHECK TABLE ... FOR UPGRADE"扫描潜在问题
升级后必调的几个关键配置项
新版本默认行为变化直接影响应用表现,这些配置不手动覆盖,很可能第二天就收到慢查询告警:
-
default_authentication_plugin=caching_sha2_password→ 若客户端不兼容,临时改回mysql_native_password(仅限过渡期,非长期方案) -
sql_mode需显式重置:例如加回NO_AUTO_CREATE_USER(8.0 已移除该模式,但某些 ORM 生成的语句仍依赖它),或去掉ONLY_FULL_GROUP_BY(若业务 SQL 有 select 列不在 group by 中) -
innodb_file_format和innodb_large_prefix在 8.0 中已废弃,对应逻辑由innodb_file_per_table=ON和页大小隐式控制,旧配置残留可能导致启动失败 - 时间类型精度:8.0 默认支持
DATETIME(6),但 5.7 导入的 dump 文件若含微秒字段,需确认客户端是否解析正确,否则出现Truncated incorrect datetime value
权限模型变更带来的真实踩坑点
8.0 的角色(ROLE)和动态权限(如 BACKUP_ADMIN)是亮点,但升级后最常出问题的是权限继承逻辑重构:
- 原 5.7 中通过
GRANT ALL ON *.* TO 'user'@'%'赋予的权限,在 8.0 中不再自动包含对performance_schema和information_schema的访问权,监控脚本可能突然报ERROR 1142 -
SHOW GRANTS输出格式变化:8.0 返回结果中不再显示USAGE权限,但实际仍需该权限才能连接——某些权限同步工具据此误判“权限丢失” - 密码过期策略默认启用:
default_password_lifetime=0表示永不过期,但若没显式设,8.0 默认为 360 天,上线后某天用户连不上才查日志发现ERROR 1820 (HY000): You must reset your password using ALTER USER statement
真正麻烦的不是升级动作本身,而是那些藏在 SQL 模式、权限继承、客户端协议细节里的隐性依赖——它们不会在升级日志里报错,却会在某个凌晨三点的订单写入失败时集中爆发。










