真正可行的就地升级必须用mysql_upgrade工具,且必须先运行util.checkforserverupgrade()扫描修复语义级不兼容项,否则将导致启动失败、权限丢失或乱码。

不能靠 mysqldump --all-databases 导出再导入实现“平滑”,真正可行的就地升级(in-place upgrade)必须用官方 mysql_upgrade 工具,且前提是先通过 util.checkForServerUpgrade() 扫描并修复所有语义级不兼容项——否则 mysqld 启动失败、权限丢失、中文乱码都是大概率事件。
必须先跑 util.checkForServerUpgrade() 才能动手
这个检查不是可选项,是 Oracle 官方唯一推荐的跨大版本前置扫描入口。它能发现 mysqldump 和 mysqlcheck 完全看不见的问题:
-
utf8mb3字符集使用(5.7 的utf8实际是utf8mb3,8.0 已弃用) - 表/列名撞了 8.0 保留字,比如
rank、groups -
password字段名在自定义表中存在(会和系统表mysql.user冲突) - 认证插件不兼容提示:如
caching_sha2_password plugin not supported by client
执行时注意三点:mysqlsh 必须用目标 8.0 版本(如升到 8.0.42 就得用 mysql-shell-8.0.42),连接走 socket(-S /tmp/mysql.sock),报告里 overallStatus 必须是 "OK" 才能继续。
mysqldump --all-databases 是高危操作,业务库必须手动指定
导出时绝不能用 --all-databases,它会把 5.7 的 mysql 系统库一并打包,而 8.0 的 mysql.user 表结构已重构(password → authentication_string,引擎强制 InnoDB),导入后轻则 root 登不进,重则 mysqld 启动卡死。
- 只导业务库:
mysqldump --default-character-set=utf8mb4 -u root -p --databases myapp shop_core > business.sql - 如果误用了
--all-databases,必须手动删掉所有含CREATE DATABASE mysql或USE mysql的段落,再删光所有INSERT INTO mysql.开头的行 - 导入前确认目标 8.0 实例的
mysql库是全新初始化的,不是从 5.7 恢复来的
启动 8.0 前必须清理三类残留
替换二进制后 mysqld 卡在 “Starting MySQL” 或秒退,基本是配置或数据字典校验失败,不是服务没起来,是被拒载了:
- 删掉
my.cnf里已废弃参数:query_cache_type、innodb_file_format、explicit_defaults_for_timestamp - 显式设置认证插件:
default_authentication_plugin=mysql_native_password(除非你已统一升级 JDBC/PyMySQL 驱动) - 查并转换 MyISAM 表:
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE ENGINE = 'MyISAM',结果非空就得逐个ALTER TABLE ... ENGINE=InnoDB
宝塔面板的「升级」按钮能用,但有硬前提
宝塔 7.9+ 的 MySQL 升级功能本质就是调用 mysql_upgrade 做原地替换,这是目前最接近“平滑”的路径,但它要求:
- 当前 5.7 版本 ≥ 5.7.26(低于此版本需先升到 5.7.26)
- 升级前必须停掉所有依赖 MySQL 的服务(PHP、网站、计划任务)
- 升级包必须匹配系统架构(x86_64/aarch64)和 glibc 版本
- 升级后立刻改三处配置:
default_authentication_plugin、collation-server、sql_mode(避免 PHP 连接层因校验规则不匹配拒绝连接)
最易被忽略的是:升级后 sql_mode 会被重置为 8.0 默认值,而 STRICT_TRANS_TABLES 和取消 GROUP BY 隐式排序这两项变更,会让大量旧 SQL 行为突变——这不是 bug,是设计使然,必须提前审查业务代码。











