不能直接rsync datadir跨机房迁移,因lsn不一致、文件系统差异、selinux上下文丢失及innodb日志与数据页逻辑不一致,易致启动报错innodb: database page corruption或卡在recovery阶段。

物理备份迁移不是“拷过去就能用”,XtraBackup 跨机房迁移成败关键在三点:LSN一致性、datadir权限与MySQL版本对齐,缺一不可。
为什么不能直接 rsync datadir 跨机房?
直接复制 /var/lib/mysql 在同机同版本下可能侥幸成功,但跨机房意味着网络延迟、文件系统差异(如 ext4 vs xfs)、SELinux 上下文丢失、MySQL 进程残留锁文件等问题。更致命的是:ibdata1 和每个 .ibd 文件内部的 LSN(Log Sequence Number)必须严格递增且连续,手动拷贝无法保证 redo log 与数据页的逻辑一致,启动时大概率报错 InnoDB: Database page corruption 或卡在 recovery 阶段。
xtrabackup --backup 必须加 --no-lock 和 --slave-info
跨机房迁移通常从从库发起(避免主库压力),此时需兼顾速度与复制位点可追溯性:
-
--no-lock:跳过FLUSH TABLES WITH READ LOCK,避免阻塞业务写入 —— 跨机房网络延迟高,锁表几秒就可能引发应用超时 -
--slave-info:生成xtrabackup_slave_info,记录当前MASTER_LOG_FILE和MASTER_LOG_POS,后续在目标机房搭建新从库时可直接CHANGE MASTER TO - 不加
--safe-slave-backup:它会停 SQL 线程,导致主从延迟突增,且仍需 FTWRL,违背“低影响”初衷
命令示例:xtrabackup --backup --target-dir=/backup/20260603 --user=backup --password=xxx --no-lock --slave-info --parallel=4
准备阶段必须分两步:先 --apply-log-only,再 --prepare
跨机房传输备份集后,不能直接 --copy-back。InnoDB 需要重放 redo log 并回滚未提交事务,但这个过程必须分步做:
- 对全备执行:
xtrabackup --prepare --apply-log-only --target-dir=/backup/20260603(只重放日志,不回滚) - 若用了增量备份,按顺序对每个增量集执行:
xtrabackup --prepare --apply-log-only --target-dir=/backup/20260603 --incremental-dir=/backup/inc1 - 最后对全备执行一次不带
--apply-log-only的--prepare:xtrabackup --prepare --target-dir=/backup/20260603(完成回滚,生成一致性快照)
漏掉 --apply-log-only 直接最终 prepare,会导致增量日志被错误回滚,恢复后数据缺失。
恢复时 chown -R mysql:mysql 不够,还要检查 my.cnf 中 innodb_log_group_home_dir
目标机房 MySQL 启动失败常见原因不是权限,而是日志路径不匹配:
- 备份时源库
innodb_log_group_home_dir指向/var/lib/mysql,但目标机房该路径下已有旧ib_logfile0/1,xtrabackup 不覆盖它们 - 必须手动删除目标
datadir下的ib_logfile*和ibtmp1(MySQL 8.0+),否则启动报错InnoDB: Invalid checkpoint lsn -
my.cnf中datadir、innodb_data_home_dir、innodb_log_group_home_dir三者路径必须完全一致,且指向--copy-back的目标目录
操作顺序:systemctl stop mysqld → rm -f /var/lib/mysql/ib_logfile* /var/lib/mysql/ibtmp1 → xtrabackup --copy-back --target-dir=/backup/20260603 → chown -R mysql:mysql /var/lib/mysql → systemctl start mysqld
真正容易被忽略的是:跨机房迁移后首次启动时,MySQL 会尝试从 ib_logfile 恢复,而你刚删了它 —— 这是预期行为,只要 --prepare 正确完成,MySQL 会自动重建日志文件并校验页校验和。盯着错误日志里反复出现的 “log file not found” 别慌,看最后一行是否出现 “InnoDB initialization completed” 才算真正过关。











