MySQL 9.x 创新发布线正在快速迭代,9.7 即将到来。如果你还在跑 8.0 或更早版本,升级窗口不会永远敞开——旧版本的 bug 修复和安全补丁终会停止。与其等到被迫迁移,不如现在就开始规划。本文梳理升级前必须做的检查、常见的踩坑点,以及一套可落地的分阶段迁移流程。
先搞清楚你当前站在哪里
升级的第一步不是下载新包,而是盘点现状。你需要回答三个问题:
- 当前 MySQL 版本是多少?(8.0.x?还是更老的 5.7?)
- 用了哪些已废弃或即将移除的特性?
- 有多少存储引擎、字符集、SQL 模式的自定义配置?
快速摸底可以用下面这段 SQL,跑一遍就能拿到关键信息:
-- 收集当前实例的版本、字符集、SQL 模式和引擎信息
SELECT VERSION() AS current_version;
SELECT @@global.sql_mode AS sql_mode;
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM information_schema.SCHEMATA
WHERE SCHEMA_NAME NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys');
SELECT ENGINE, SUPPORT, COMMENT
FROM information_schema.ENGINES
WHERE SUPPORT = 'YES' OR SUPPORT = 'DEFAULT';
把结果存下来,这是你后续对比的基准。
逐项排查废弃特性
MySQL 每个大版本都会移除一批之前标记为 deprecated 的功能。9.x 相比 8.0,已经移除或变更的包括但不限于:
mysql_upgrade命令——9.x 中升级检查已内嵌到服务器启动流程,不再需要单独跑这个工具。- 部分旧密码认证插件——
mysql_native_password在 9.0 中默认禁用,必须切换到caching_sha2_password。 SHOW PRIVILEGES语句行为变更——输出格式和权限名称有调整,依赖其结果集的脚本需要验证。- 一些旧系统变量——例如与
query_cache相关的变量早已在 8.0 移除,9.x 继续清理遗留。
最直接的排查方式是翻官方 Release Notes 的 "Deprecated and Removed Features" 章节,然后对照你的配置和代码做 grep。下面这个 shell 脚本可以批量扫描 SQL 文件和配置中常见的废弃关键词:
#!/usr/bin/env bash
# scan_deprecated.sh — 在项目目录中扫描 MySQL 废弃特性关键词
# 用法: bash scan_deprecated.sh /path/to/project
SCAN_DIR="${1:-.}"
# 废弃/移除关键词列表,可根据目标版本扩展
KEYWORDS=(
"mysql_native_password"
"query_cache"
"mysql_upgrade"
"SHOW PRIVILEGES"
"OLD_PASSWORD"
"DES_ENCRYPT"
"SPATIAL_REF_SYS"
)
echo "=== 扫描目录: $SCAN_DIR ==="
for kw in "${KEYWORDS[@]}"; do
matches=$(grep -r --include="*.sql" --include="*.cnf" --include="*.conf" \
--include="*.py" --include="*.yaml" --include="*.yml" \
-l "$kw" "$SCAN_DIR" 2>/dev/null)
if [ -n "$matches" ]; then
echo "[命中] $kw →"
echo "$matches"
echo ""
fi
done
echo "=== 扫描完成 ==="
跑一遍,命中的文件就是你需要逐个审查的目标。
认证插件迁移:最容易断连接的坑
从 8.0 到 9.x,认证方式的变更是最容易导致大面积连接失败的改动。caching_sha2_password 成为默认后,老版本的客户端驱动(比如 MySQL Connector/J 5.x、部分 PHP mysqli 扩展)无法直接握手。
升级前必须做两件事:
- 确认所有应用使用的 MySQL 驱动版本支持
caching_sha2_password。不支持的必须先升级驱动。 - 在当前 8.0 实例上提前切换用户认证方式,观察是否正常:
-- 在 8.0 上提前迁移认证方式,验证应用兼容性
ALTER USER 'app_user'@'%' IDENTIFIED WITH caching_sha2_password BY 'your_password';
-- 查看所有用户的认证插件,找出还在用旧方式的
SELECT user, host, plugin
FROM mysql.user
WHERE plugin = 'mysql_native_password';
逐个迁移,每次改一个用户,观察对应服务的连接日志。全部通过后再做版本升级,就不会被认证问题打懵。
分阶段升级流程
不要一步跳到 9.7。推荐三步走:
阶段一:在 8.0 上做兼容性准备
- 切换认证插件(如上所述)。
- 清理配置文件中已废弃的变量。
- 把
sql_mode中与 9.x 不兼容的选项(如NO_AUTO_CREATE_USER,8.0 已移除但配置残留仍会报错)去掉。 - 更新所有客户端驱动到兼容版本。
阶段二:搭建 9.x 测试环境,做逻辑迁移
用 mysqldump 或 MySQL Shell 的 util.dumpInstance 把数据导出,导入到 9.x 测试实例:
# 用 MySQL Shell 的并行 dump,速度比 mysqldump 快得多
mysqlsh --user root --password --host source-host \
--util dumpInstance /tmp/dump_dir \
--threads 4 --compatibility mysql9
# 在目标 9.x 实例上恢复
mysqlsh --user root --password --host target-host \
--util loadDump /tmp/dump_dir \
--threads 4
--compatibility mysql9 参数会自动处理已废弃的语法转换,这是 MySQL Shell 8.0.32+ 提供的便利。
阶段三:验证与切换
在测试实例上跑你的完整回归测试套件。重点验证:
- 所有业务 SQL 语句的执行结果是否一致。
- 存储过程、触发器、视图是否正常编译和运行。
- 复制拓扑是否正常(如果用 replica 做滚动升级,先升级 replica,观察复制延迟和错误日志)。
# 检查 9.x 实例启动后的错误日志,关注升级相关的警告
grep -i "upgrade\|deprecated\|removed\|warning" /var/log/mysql/error.log | head -30
确认无误后,按 replica → primary 的顺序做滚动切换,或者选择低峰期直接 in-place 升级。
升级前的自检清单
最后,把关键检查项压缩成一份清单,升级当天逐项打勾:
| 检查项 | 状态 |
|---|---|
所有用户认证插件已迁移到 caching_sha2_password |
☐ |
| 配置文件中无废弃变量 | ☐ |
| 客户端驱动版本已确认兼容 9.x | ☐ |
sql_mode 与 9.x 兼容 |
☐ |
| 测试实例数据导入完成、回归测试通过 | ☐ |
| 复制拓扑在 9.x 测试实例上运行正常 | ☐ |
| 回滚方案已准备(8.0 备份 + 恢复流程验证) | ☐ |
| 错误日志中无升级相关 warning | ☐ |
升级不是一锤子买卖。准备做得越细,升级窗口就越短,出事时回滚就越从容。MySQL 9.7 带来的新特性值得拥抱,但前提是你稳稳地站到了新版本的地基上。