mysqldump 不适用于50gb以上大表迁移:导出拖慢查询、恢复慢超12小时、无法保证全局一致性;应采用xtrabackup物理备份,关键参数包括--backup、--target-dir、--no-timestamp、--parallel和--throttle。

为什么不用 mysqldump 迁移大表
超过 50GB 的单表或总库,mysqldump 基本不可行:导出时 SELECT 全表会严重拖慢查询响应,恢复时逐条执行 SQL,IO 和 CPU 压力集中,实测 100GB 库恢复常超 12 小时。更关键的是,它无法保证备份瞬间的全局一致性(除非加 --single-transaction,但对非 InnoDB 表无效,且长事务可能阻塞)。物理备份绕过 SQL 层,直接复制数据文件,这才是大表迁移的合理起点。
xtrabackup 全量备份命令必须带的关键参数
漏掉任一关键参数,备份可能不一致或无法恢复:
-
--backup:必须显式指定,表示执行备份动作(不是 prepare 或 copy-back) -
--target-dir=/path/to/backup:目标路径需有足够空间,且 MySQL 进程用户(如mysql)必须有读写权限 -
--no-timestamp:避免自动生成时间戳子目录,便于脚本控制路径 -
--parallel=4:多线程加速拷贝(建议设为 CPU 核数的 75%,过高反而因 IO 竞争变慢) -
--throttle=100:限速(单位 IOPS),防止备份压垮线上业务(根据磁盘负载动态调整)
示例命令:xtrabackup --backup --target-dir=/data/backup/full --no-timestamp --parallel=4 --throttle=80
流式备份到远程服务器的实操要点
本地磁盘不够?别先 rsync 整个备份目录——用流式直接传,但必须注意两件事:
- 流式输出(
--stream=tar)不生成可直接--prepare的目录结构,必须先解包还原出原始文件树 - 远程接收端不能用普通
ssh直接重定向,要确保 tar 解包路径与原--target-dir逻辑一致(比如都用绝对路径/data/backup/full) - 压缩必须在流式链路中完成,否则传输体积爆炸;推荐
gzip而非zstd(兼容性更好,xtrabackup 2.4 默认不支持 zstd 流)
正确写法:xtrabackup --backup --stream=tar --target-dir=/tmp/unused --parallel=4 | gzip | ssh user@newhost "gunzip | tar -ixf - -C /data/backup/full"
恢复前 prepare 阶段最容易被忽略的细节
--prepare 不是“点一下就完事”的操作。它本质是重放备份期间产生的 redo log,让数据文件达到一致性状态。常见翻车点:
- 必须用**同版本**的
xtrabackup执行--prepare,例如 MySQL 5.7 用的备份,不能用 xtrabackup 8.0 来 prepare - 增量备份恢复时,
--prepare必须按顺序:先全量 prepare(加--apply-log-only),再逐个合并增量(也都加--apply-log-only),最后一步全量 prepare **不加**该参数 - 如果备份后 MySQL 曾异常关闭,
--prepare可能报错log sequence number check failed,此时需加--force-non-empty-directories强制继续(但要确认无未刷盘日志)
最小安全恢复命令:xtrabackup --prepare --target-dir=/data/backup/full
流式备份解包后的目录结构、--prepare 的版本锁定、以及 --apply-log-only 的使用时机,这三处一旦出错,轻则恢复失败,重则数据损坏。实际操作前,务必在测试机上走通完整链路。











