升级前必须做完整逻辑备份,而非仅依赖物理拷贝
MySQL 升级(尤其是跨大版本,如 5.7 → 8.0)时,
mysqldump或
mydumper生成的逻辑备份是唯一可验证、可移植、兼容性可控的备份方式。直接拷贝
datadir在多数情况下不可靠:InnoDB 表空间格式可能变更(如 8.0 默认启用
innodb_file_per_table=ON且引入数据字典表),且 MySQL 8.0 的
mysql系统库结构与 5.7 不兼容,强行复用会导致启动失败或权限异常。
实操建议:
使用mysqldump --all-databases --single-transaction --routines --events --triggers --set-gtid-purged=OFF(若未启用 GTID)或
--set-gtid-purged=ON(若已启用 GTID)导出全量数据 避免使用
--skip-lock-tables,它在多事务场景下可能破坏一致性 对大库(>100 GB),优先选用
mydumper并配合
myloader,支持并行导出/导入,且默认按表粒度加锁,影响更小 务必校验导出文件末尾是否含
EOF或成功退出码(
$?为 0),常见错误如磁盘满、连接中断会导致 dump 截断但无明显报错
升级后恢复时需跳过系统库,手动初始化 mysql 数据库
MySQL 8.0 将原
mysql库中的权限表(
user、
db等)替换为数据字典表(存于
mysql.ibd和
ibdata1中),且结构完全不向下兼容。若在 8.0 实例中直接导入 5.7 的
mysqldump全库备份,会因
mysql库冲突导致恢复失败,甚至损坏新实例的数据字典。
正确做法是分两步:
先用mysqld --initialize --user=mysql初始化 8.0 实例,生成全新的
mysql系统库和 root 密码(记录在 error log 中) 再用
mysql -u root -p 恢复,但必须提前从 <code>backup.sql中剔除
CREATE DATABASE `mysql`及其所有
INSERT INTO `mysql`.*语句;可用
sed '/^CREATE DATABASE `mysql`/,/^\/\*/d' backup.sql > app_backup.sql快速过滤(注意匹配实际注释结尾) 若备份中含自定义函数/存储过程,需确认其语法兼容性(如 8.0 移除了
DEFINER的部分宽松校验,可能报
ERROR 1449 (HY000): The user specified as a definer ('xxx'@'%') does not exist),应提前用 SHOW CREATE FUNCTION检查并重写
DEFINER
GTID 模式下升级必须保持 gtid_mode=ON + enforce_gtid_consistency=ON 且校验 gtid_purged
若原实例启用了 GTID(
gtid_mode=ON),升级后若未正确继承
gtid_purged值,会导致主从复制断裂或新实例拒绝执行任何事务。MySQL 8.0 要求
gtid_mode和
enforce_gtid_consistency必须同时为
ON才允许启动,而 5.7 的 dump 默认不包含
SET @@GLOBAL.GTID_PURGED语句(除非显式加
--set-gtid-purged=ON)。
关键检查点:
导出前确认源库SELECT @@GLOBAL.gtid_purged;返回非空值;若为空,需先执行
FLUSH LOGS和
RESET MASTER(仅限测试环境,生产慎用) dump 文件开头应含类似
SET @@GLOBAL.GTID_PURGED='aaa-bbb-ccc:1-100';的语句;若缺失,需手动追加(值来自上一步查询结果) 恢复后立即执行
SELECT @@GLOBAL.gtid_executed, @@GLOBAL.gtid_purged;,确保二者一致且覆盖 dump 中声明的范围,否则后续开启复制会报
Could not execute Write_rows event on table
升级后必须运行 mysql_upgrade 吗?8.0 已废弃该工具
MySQL 5.7 及更早版本要求升级后运行
mysql_upgrade来更新系统表结构、修复权限视图。但该工具在 MySQL 8.0 中已被彻底移除——所有系统库升级操作由 mysqld 启动时自动完成。若在 8.0 中误执行
mysql_upgrade,会提示
Unknown suffix '.' encountered或直接报错退出。
替代方案只有两个:
确保以mysqld --upgrade=FORCE启动(仅首次启动必需,后续无需重复);该参数会触发内部数据字典升级流程 观察 error log,确认出现类似
Server upgraded from version '50732' to '80033'和
Created new data dictionary with version ...的日志条目,即表示升级成功 切勿手动修改
mysql库下的任何表(如
innodb_index_stats),8.0 的统计信息已转为数据字典内建表,直接 DML 会引发崩溃
最易被忽略的是字符集与排序规则的隐式变更:MySQL 8.0 默认
collation_server=utf8mb4_0900_ai_ci,而 5.7 是
utf8mb4_general_ci。即使备份恢复成功,应用若未显式指定
COLLATE,ORDER BY、GROUP BY 结果可能不同,且
utf8mb4_0900_ai_ci对某些 emoji 的排序行为也与旧版不一致。
