不行,直接拷贝data目录会导致表损坏或启动失败;必须用xtrabackup等热备工具,经prepare后才能恢复,且需注意版本、权限、配置一致性。

直接用 cp 或 rsync 拷贝 data 目录行不行?
不行,除非 MySQL 完全关闭且确认没有写入、没有未刷盘的脏页、没有正在运行的 InnoDB 后台线程。多数情况下,直接拷贝 datadir 会导致表损坏或启动失败,尤其 InnoDB 表——因为 ibdata1、ib_logfile* 和每个表的 .ibd 文件必须状态一致。
- 若源库启用了
innodb_file_per_table=ON,单表迁移看似简单,但依然依赖全局事务 ID(gtid_executed)、redo log 位点、undo log 状态,不能脱离实例单独使用 - 若目标 MySQL 版本不同(如从 5.7 迁到 8.0),
.frm和.ibd文件结构可能不兼容,强行拷贝会报错Tablespace is missing for table xxx -
mysqld启动时校验ibdata1的 checkpoint LSN,与ib_logfile*不匹配就拒绝启动
物理备份迁移唯一可靠方式:用 mysqlbackup(MySQL Enterprise Backup)或 Percona XtraBackup
这两者是专为 InnoDB 设计的热备工具,能保证数据文件、日志、元数据三者一致性。XtraBackup 更常用(开源免费),但注意版本对齐:
- XtraBackup 2.4 只支持 MySQL 5.6/5.7;8.0 需用 XtraBackup 8.0,且要求 MySQL 开启
innodb_directories(若用通用表空间) - 备份后必须执行
xtrabackup --prepare(回放 redo、截断 undo),否则恢复时会卡在 crash recovery 阶段 - 恢复时目标
datadir必须为空,且my.cnf中server_id、datadir、innodb_data_home_dir等路径配置要与备份时一致,否则启动报Unknown/unsupported storage engine: InnoDB
恢复后启动失败常见错误及应对
即使备份和 prepare 正确,恢复后首次启动仍常出问题,核心是配置与权限没对齐:
-
InnoDB: Operating system error number 13 in a file operation→ Linux 下chown -R mysql:mysql /var/lib/mysql缺失,或 SELinux 强制限制,临时可setenforce 0排查 -
Can't start server: Bind on TCP/IP port. Got error: 98: Address already in use→ 旧 mysqld 进程没杀干净,ps aux | grep mysql+kill -9清理 - 启动日志末尾卡在
Starting crash recovery...→--prepare没做全,或备份时加了--no-timestamp导致xtrabackup_binlog_info丢失,无法定位 binlog 位置
物理迁移不适合哪些场景?
物理备份迁移本质是“实例级克隆”,它快但缺乏灵活性:
- 只迁移某几个库或表?不行,必须整实例或整库(XtraBackup 支持
--include,但恢复时仍需重建整个 datadir 结构) - 跨架构迁移(x86 → ARM)?不行,
.ibd是平台相关二进制格式,需逻辑导出再导入 - 需要跳过某些 DDL(比如删掉某个大表的索引重建过程)?不行,物理层无法编辑
- 目标环境磁盘空间比源小?不行,
ibdata1不会自动收缩,--compact参数仅影响.ibd,且 8.0+ 已弃用
真正要注意的是:物理备份不是“复制完就能跑”,prepare 和 restore 两步缺一不可,而 prepare 的耗时往往被低估——一个 100GB 的备份,prepare 可能持续 20 分钟以上,期间 CPU 和 I/O 峰值很高,别在业务高峰期做。











