前言
MySQL 8 作为里程碑式的版本,带来了诸多重磅特性(如窗口函数、CTE、更强的 JSON 支持、默认 UTF8MB4 编码、性能优化等),但从 MySQL 5.7 升级并非'一键无脑更',涉及语法、配置、权限、数据类型等多维度兼容问题。本文结合实战经验,梳理升级核心注意事项、实操步骤与常见坑点,帮你平稳完成升级。
一、升级前必看:核心兼容性差异
1. 默认字符集与排序规则变更
- MySQL 5.7:默认字符集为 latin1,排序规则 latin1_swedish_ci;
- MySQL 8.0:默认字符集改为 utf8mb4,排序规则 utf8mb4_0900_ai_ci(基于 Unicode 9.0,区分语言特性)。
- 风险点:若原库未显式指定字符集,升级后可能出现乱码、排序异常;若业务依赖 latin1,需提前规划字符集迁移。
- 建议:升级前全库检查字符集,执行
SELECT table_schema, table_name, column_name, character_set_name FROM INFORMATION_SCHEMA.COLUMNS WHERE character_set_name != 'utf8mb4';,提前将核心表字段改为 utf8mb4。
2. 认证插件与密码策略变更
- MySQL 5.7:默认认证插件为 mysql_native_password;
- MySQL 8.0:默认改为 caching_sha2_password,且强化了密码策略(默认要求密码长度≥8、包含大小写 / 数字 / 特殊字符)。
- 风险点: 旧客户端(如 PHP5.x、Python2.x)不支持 caching_sha2_password,会导致连接失败; 原弱密码用户升级后可能无法登录。
- 建议:
若需兼容旧客户端,可临时改回旧认证插件:
ALTER USER 'user'@'%' IDENTIFIED WITH mysql_native_password BY 'new_password';; 升级前梳理所有数据库用户,提前更新弱密码,避免升级后登录失败。
3. 系统表与数据字典重构
- MySQL 8 彻底移除了 MyISAM 存储的系统表,改用 InnoDB 的事务型数据字典,mysql 库结构大幅调整: 原 mysql.user/mysql.db 等权限表变为视图,直接修改表的操作(如 INSERT INTO mysql.user)失效; 不再支持 mysql_upgrade(5.7 升级 8.0 需用 mysqld --upgrade=FORCE); 移除 information_schema 中部分冗余表(如 INNODB_SYS_*)。
- 建议:检查业务中是否有直接操作系统表的 SQL,改为官方推荐的 CREATE USER/GRANT 等语法。
4. SQL 模式与语法兼容性
- 默认 SQL 模式增强:MySQL 8 默认启用 ONLY_FULL_GROUP_BY、STRICT_TRANS_TABLES 等,5.7 中未开启的严格模式可能导致原有'不规范 SQL'执行失败(如 GROUP BY 中未包含非聚合字段);
- 关键字新增:MySQL 8 新增 ROLE、WINDOW、CTE 等关键字,若表名 / 字段名与这些关键字重名(如 CREATE TABLE role (id INT);),需加反引号 `包裹;
- 函数行为变更:NOW()、SYSDATE() 等函数精度提升,JSON_EXTRACT 语法更严格,旧 JSON 操作 SQL 可能报错。
5. 存储引擎与功能移除
- 移除 QUERY_CACHE(查询缓存):MySQL 8 彻底删除查询缓存功能,若 my.cnf 中配置了 query_cache_type、query_cache_size 等参数,启动会报错;
- 移除 NO_AUTO_CREATE_USER SQL 模式:5.7 中 GRANT 语句若未指定密码会自动创建用户,8.0 中此行为被禁止,需先 CREATE USER 再授权;
- 不支持 MYSQL40 密码格式:仅保留 MYSQL56 和 caching_sha2_password,极旧的用户密码需重置。
二、升级实操:分步执行(推荐离线升级)
步骤 1:升级前准备
- 全量备份:使用 mysqldump 或物理备份工具(如 xtrabackup)备份整个数据库,命令示例:
# 全量备份(包含存储过程、触发器、事件)
mysqldump -uroot -p --all-databases --routines --triggers --events > mysql57_full_backup.sql

