确认当前 MySQL 版本及已启用的特性
升级前必须明确当前实例的真实版本和运行模式,避免误判为“小版本升级”而忽略不兼容变更。执行
SELECT VERSION();仅返回主版本号,需进一步查
SHOW VARIABLES LIKE 'version_compile_machine';和
SHOW VARIABLES LIKE 'sql_mode';,尤其注意是否启用了
STRICT_TRANS_TABLES、
ONLY_FULL_GROUP_BY等在 5.7→8.0 中默认开启或行为收紧的模式。
常见错误现象:应用查询突然报错
Expression #1 of ORDER BY clause is not in GROUP BY clause,实则是 8.0 默认启用
ONLY_FULL_GROUP_BY,而旧版未开启或被显式禁用。 检查
information_schema.PLUGINS中是否有已废弃插件(如
FEDERATED在 8.0.23+ 被移除) 运行
SELECT plugin_name, plugin_status FROM information_schema.PLUGINS WHERE plugin_status = 'DISABLED';,确认无依赖禁用插件的业务逻辑 导出当前
mysqld启动参数:
mysqld --verbose --help | grep "Default options" -A 1,比对新版文档中已被移除的选项(如
query_cache_type在 8.0.3 已彻底删除)
扫描 SQL 兼容性问题(特别是 GROUP BY、JSON、关键字)
MySQL 8.0 对 SQL 语法更严格,且引入新保留字,旧 SQL 可能在解析阶段直接失败。不能只靠人工扫代码,需工具辅助。
使用
mysql_upgrade并不能提前暴露语法问题;它只在升级后校验系统表。真正有效的做法是用目标版本的
mysqld以
--sql-mode=STRICT_TRANS_TABLES,ONLY_FULL_GROUP_BY启动临时实例,重放慢日志或典型 SQL。 重点检查含隐式
GROUP BY的查询(如
SELECT a, b FROM t GROUP BY a),8.0 要求所有非聚合字段必须出现在
GROUP BY中或被函数包裹 搜索代码中是否把
rank、
json、
window当作列名或别名——它们在 8.0 是保留关键字,需用反引号包裹 验证 JSON 字段操作:旧版用
JSON_EXTRACT(col, '$.field')没问题,但若用了
col->'$.field'语法,需确认客户端驱动支持(如 MySQL Connector/J 8.0.12+ 才完全支持)
验证客户端驱动与连接协议兼容性
MySQL 8.0 默认启用 caching_sha2_password 认证插件,老版本驱动(如 MySQL Connector/J Public Key Retrieval is not allowed 或
Authentication plugin 'caching_sha2_password' cannot be loaded。
这不是配置问题,是协议层不兼容。绕过方式(如降级为
mysql_native_password)只是临时缓解,不能代替驱动升级。 列出所有接入该库的应用,检查其数据库驱动版本:
pip show PyMySQL、
mvn dependency:tree | grep mysql测试连接字符串是否显式指定
?allowPublicKeyRetrieval=true&useSSL=false(仅限测试环境,生产禁用) 若使用连接池(如 HikariCP、Druid),确认其底层驱动版本 —— 连接池版本 ≠ 驱动版本
评估性能回归风险(尤其是排序、索引统计、直方图)
8.0 引入了持久化统计信息、直方图、改进的排序算法(
sort_buffer_size行为变化),某些查询可能变慢而非变快。不要假设“新版本一定更快”。
典型场景:分页查询
ORDER BY created_at LIMIT 10000, 20在 5.7 可能走索引覆盖,但在 8.0 因优化器成本模型调整,可能改走全表扫描 + filesort。 在升级前用
EXPLAIN FORMAT=TREE对核心慢 SQL 重分析(8.0 新增),对比
EXPLAIN FORMAT=TRADITIONAL输出差异 备份并检查当前
innodb_stats_persistent是否为
ON;若为
OFF,升级后首次重启会触发统计信息重建,可能导致查询计划突变 直方图不是自动创建的,但若手动建了(
ANALYZE TABLE t UPDATE HISTOGRAM ON col),需确认业务是否依赖其提升范围查询精度
SELECT table_name, column_name, histogram FROM information_schema.COLUMN_STATISTICS WHERE schema_name = 'your_db';
真正麻烦的从来不是“能不能升”,而是“升完谁的定时任务开始超时”“哪个报表接口突然 504”。留出足够时间做灰度验证,尤其关注凌晨批处理和低频但关键的管理后台 SQL。
