跨版本物理恢复必须确保innodb_file_per_table、innodb_page_size和explicit_defaults_for_timestamp三者配置一致,并严禁拷贝旧版mysql等系统库目录,否则启动失败。

恢复前必须检查 innodb_file_per_table 是否开启
新版本 MySQL(尤其是 8.0+)默认启用 innodb_file_per_table=ON,而老版本备份(如 5.6 或未显式配置的 5.7)很可能关闭它,导致共享表空间 ibdata1 包含用户表数据。直接拷贝物理文件到新实例会失败——mysqld 启动时发现表定义与实际文件结构不匹配,报错类似 Table 'xxx' doesn't exist in engine。
实操建议:
- 从原库查:
SHOW VARIABLES LIKE 'innodb_file_per_table';;若为OFF,备份中所有 InnoDB 表都存于ibdata1,不能单独恢复单个库或表 - 新实例必须保持一致:若原库是
OFF,新实例也得设为OFF(且不能用 8.0.30+ 默认禁用共享表空间的版本) - 更稳妥的做法:在兼容版本(如 5.7.40)中先导入再导出为逻辑备份,避开物理格式差异
MySQL 5.7 备份恢复到 8.0 需跳过 mysql 系统库文件
8.0 的 mysql 系统库结构大幅变更(如 user 表字段、权限模型),直接拷贝老版 mysql/ 目录会导致启动失败,常见错误是 Unknown table 'mysql.role_edges' 或 Incorrect information in file: './mysql/user.frm'。
实操建议:
- 物理恢复时,只复制业务库目录(如
/var/lib/mysql/myapp/)和ibdata1、ib_logfile*、undo_*等全局文件 - 绝对不要复制源库的
mysql/、performance_schema/、sys/目录 - 恢复后首次启动必须加参数:
--skip-grant-tables --shared-memory,再执行mysqld --upgrade触发系统表升级
innodb_page_size 不匹配会直接拒绝启动
物理备份要求源库与目标库的 innodb_page_size 完全一致。5.7 默认是 16K,但某些定制部署或旧硬件可能设为 4K 或 8K;而 MySQL 8.0.28+ 开始支持 64K,但不向下兼容。一旦不匹配,mysqld 启动时立即报错:InnoDB: Error: page size mismatch,进程退出。
实操建议:
- 查源库:
SELECT @@innodb_page_size;(单位字节,16384 = 16K) - 新实例配置文件必须显式声明:
innodb_page_size = 16384,不能依赖默认值——尤其跨大版本时,8.0 某些小版本默认值有变动 - 如果源库是 4K,别硬试恢复:只能用
mysqldump或mydumper做逻辑迁移
时间戳字段兼容性陷阱:explicit_defaults_for_timestamp
MySQL 5.6 默认 explicit_defaults_for_timestamp=OFF,意味着没显式定义 NOT NULL 的 TIMESTAMP 字段会自动加 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;而 5.7+ 默认为 ON,行为不同。物理恢复后若未重载表定义,插入空值可能报错 Invalid default value for 'created_at'。
实操建议:
- 恢复前在新实例配置中显式设:
explicit_defaults_for_timestamp = OFF(与源库一致) - 启动后执行
SELECT @@explicit_defaults_for_timestamp;确认生效 - 后续可逐步改造表结构,但恢复阶段必须对齐,否则 DML 就会失败
物理备份跨版本恢复不是“拷过去就能用”,最易被忽略的是系统库处理方式和页大小硬约束——这两个点一错,连启动都过不去,别急着跑 SQL。











