必须用mysqlsh的util.checkforserverupgrade()扫描兼容性,修复所有error和warning项;停写后执行mysqlcheck --check-upgrade校验表结构;清理废弃参数、显式配置认证插件、转换myisam表为innodb;升级后立即验证版本、sql模式、认证插件、校对规则及系统表访问。

不能靠 mysqldump --all-databases 导出再导入,也不能直接替换二进制文件后启动——这两条路在生产环境几乎必然导致服务中断、权限丢失或半夜告警。真正的平滑升级必须走原地升级(in-place)路径,但前提是做完三道硬性检查和清理。
必须用 mysqlsh 的 util.checkForServerUpgrade() 扫描兼容性
这是 Oracle 官方唯一推荐的前置检查工具,mysqlcheck --check-upgrade 或 mysqld --validate-config 都无法识别跨版本语义变更(比如 utf8mb3 字符集、caching_sha2_password 插件、保留字列名)。
- 必须使用与目标 MySQL 8.0 版本一致的
mysql-shell(如升到 8.0.42,就得用mysql-shell-8.0.42),混用 5.7 的 shell 会漏检 - 连接优先走 socket:
./mysqlsh -uroot -p -S /tmp/mysql.sock -e "util.checkForServerUpgrade({'configPath': '/etc/my.cnf'})" - 报告中
overallStatus必须是OK;出现ERROR级条目(如Usage of utf8mb3 charset、Column name 'rank' is a reserved keyword)必须逐条修复 -
WARNING级也不能跳过:例如caching_sha2_password plugin not supported by client,说明 JDBC 驱动太老,需提前升级mysql-connector-java ≥ 8.0.13或改认证方式
停写后必须运行 mysqlcheck --check-upgrade 校验表结构
这个命令不是只查损坏,而是校验 5.7 表结构是否满足 8.0 元数据要求。跳过它,升级后 mysqld 很可能卡在 “Starting MySQL” 或启动后查表报 Table doesn't exist。
- 必须在业务停写后执行:
mysqlcheck -u root -p --all-databases --check-upgrade - 常见触发 ERROR 的原因包括:
ENUM默认值为空字符串、TEXT字段写了DEFAULT ''、列名用了rank等 8.0 保留字 - 对含
JSON字段的表,mysqlcheck不报错也不代表安全,建议手动跑:SELECT * FROM tbl WHERE json_valid(col) = 0扫一遍 - 若报
The table does not comply with the current version of MySQL且提示孤立.frm文件或 MyISAM 分区表,必须先ALTER TABLE ENGINE=InnoDB或删掉对应表
启动失败基本都卡在这三个地方
替换二进制、停旧服务、启新 mysqld 后卡在 “Starting MySQL” 或秒退,90% 是配置或数据字典没清理干净,不是数据坏了。
- 残留已废弃参数:如
query_cache_type、explicit_defaults_for_timestamp、log_warnings,必须从my.cnf中彻底删除或注释,否则日志只报unknown variable,无具体位置提示 - 没设认证插件:
default_authentication_plugin=mysql_native_password必须显式写进[mysqld]段,否则老 PHP/Java 客户端连不上,报错Client does not support authentication protocol - 存在 MyISAM 表:8.0 已移除 MyISAM 支持,启动直接失败;先查
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE ENGINE = 'MyISAM',再逐个ALTER TABLE ENGINE=InnoDB - SELinux 上下文损坏(尤其 CentOS 7):执行
chcon -R --reference=/var/lib/mysql /usr/local/mysql恢复上下文
升级后第一分钟必须验证这四条 SQL
进程起来了 ≠ 数据库就绪。漏掉任一都可能埋下半夜告警。
-
SELECT VERSION(), @@sql_mode;—— 确认是 8.0.x 且ONLY_FULL_GROUP_BY在列表中(8.0 默认开启) -
SHOW VARIABLES LIKE 'default_authentication_plugin';—— 若返回caching_sha2_password,说明配置未生效 -
SELECT DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = 'your_db';—— 确认默认校对规则是utf8mb4_0900_ai_ci -
SELECT COUNT(*) FROM mysql.user;—— 验证系统表能正常访问,避免权限模型重构导致的静默失败
最易被忽略的是:util.checkForServerUpgrade() 报告里的 WARNING 条目,很多人看到不是 ERROR 就跳过,结果上线后 JDBC 连接池反复重连失败,排查半天才发现驱动版本不匹配。











