升级前必须用 mysqldump
做逻辑备份,而非直接拷贝文件
MySQL 版本跨大版本升级(如 5.7 → 8.0)时,
datadir下的物理文件结构、系统表格式、字符集默认行为都可能不兼容。直接复制
ibdata1或
.ibd文件极大概率导致启动失败或数据损坏。必须使用
mysqldump导出为 SQL 文本——它能自动适配源版本语法,并在恢复时由目标版本的 MySQL Server 解析执行。
实操建议:
用--single-transaction --routines --triggers --events参数保证一致性与完整性 显式指定字符集:
--default-character-set=utf8mb4,避免 5.7 默认
utf8(即
utf8mb3)在 8.0 中被拒绝 排除
mysql系统库:
--ignore-table=mysql.user --ignore-table=mysql.db...,升级后应由
mysql_upgrade(8.0.16+ 已移除)或初始化流程重建权限表 若库多、数据大,分库导出:
mysqldump -u root -p --databases db1 db2 > backup.sql
mysql
客户端恢复时要禁用外键检查和唯一性校验
导入 dump 文件时,尤其是含大量关联表的场景,直接执行会因外键约束或唯一索引冲突中断。必须在恢复前临时关闭校验,否则常见错误如:
ERROR 1215 (HY000): Cannot add foreign key constraint或
ERROR 1062 (23000): Duplicate entry。
实操建议:
在 SQL 文件开头插入:SET FOREIGN_KEY_CHECKS=0; SET UNIQUE_CHECKS=0; SET AUTOCOMMIT=0;导入完成后手动执行:
SET FOREIGN_KEY_CHECKS=1; SET UNIQUE_CHECKS=1; COMMIT;不要依赖
mysqldump --skip-extended-insert来规避问题——它只影响 INSERT 格式,不解决约束冲突 若用
source命令导入,确保客户端连接时已设置
--init-command="SET NAMES utf8mb4",否则中文可能乱码
升级后首次启动必须运行 mysql_upgrade
(仅限 8.0.16 之前)或检查系统表兼容性
MySQL 5.7 升级到 8.0.15 及更早版本时,
mysql_upgrade是强制步骤:它会检查并更新
mysql系统库中的表结构(如
user表字段变更)、修复权限视图、刷新帮助表。但自 8.0.16 起该工具已被移除,升级逻辑内建到服务启动流程中。
实操建议:
对 8.0.15 及以下版本:停掉旧实例 → 替换二进制 → 启动新mysqld→ 运行
mysql_upgrade -u root -p对 8.0.16+ 版本:启动时若检测到旧系统表,会自动执行升级并写入日志,需确认 error log 中出现
Upgrading system tables.和
Finished upgrading system tables.无论哪个版本,升级后务必验证:
SELECT VERSION();、
SELECT COUNT(*) FROM mysql.user;、
SHOW GRANTS FOR CURRENT_USER;注意:8.0 默认认证插件变为
caching_sha2_password,老客户端(如 MySQL 5.7 客户端或旧版 JDBC)可能连不上,需在用户创建时显式指定
IDENTIFIED WITH mysql_native_password
字符集与排序规则迁移最容易被忽略的三个细节
MySQL 8.0 将默认字符集从
latin1(5.7)改为
utf8mb4,默认排序规则从
latin1_swedish_ci改为
utf8mb4_0900_ai_ci。这不是简单配置变更,会影响索引长度、比较行为、JSON 字段解析等。
实操建议:
检查所有表的CREATE TABLE语句,确认是否显式声明了
CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci;未声明的会继承库级设置,而库级设置又继承 server 级,容易层层覆盖出错
utf8mb4_0900_ai_ci对大小写不敏感且忽略重音,但比旧排序规则更严格——例如
'a' = 'A'仍为 true,但某些特殊字符组合的比较结果可能不同,业务有精确匹配逻辑的需回归测试 若应用依赖
utf8mb4_unicode_ci(如 PHP 的
mb_strtolower()行为),需在建表或连接时显式指定,不能依赖默认值 升级后执行:
SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME='your_db';逐库确认 实际升级最耗时的环节往往不是执行命令,而是验证每个业务查询在新版本下的执行计划是否变化、JSON 字段是否仍可被正确解析、触发器是否还按预期触发——这些没法靠一键脚本覆盖,得靠你盯着慢查询日志和应用日志看。
