mysqldump --single-transaction不能真正实现大库不停机迁移,因其仅对innodb有效、myisam仍锁表,1tb数据导出导入耗时长且易受ddl干扰;xtrabackup通过物理文件复制+lsn追踪+增量衔接,才是1tb级不停机迁移的事实标准。

mysqldump 和 XtraBackup 都能实现不停机迁移,但选错工具或参数,轻则导入慢到超时,重则数据不一致、切换失败。真正可靠的方案取决于你的数据量、引擎类型和停机容忍度。
为什么不能直接用 mysqldump --single-transaction 迁移大库?
它只对 InnoDB 表生效,MyISAM 表仍会锁表;即使全是 InnoDB,1TB 数据导出+导入耗时可能超过数小时,期间 binlog 堆积、主从延迟飙升,最终无法控制切换窗口。
-
--single-transaction依赖 MVCC 快照,但备份开始后若有人执行ALTER TABLE或DROP TABLE,快照可能失效,导致备份不一致 - 导出的 SQL 文件体积通常为原始数据的 1.2–1.5 倍(含建表语句、索引重建逻辑),网络传输和目标库 replay 成本极高
- 导入时
INSERT逐行写入,无法并发加速;而LOAD DATA INFILE又要求文件已存在目标服务器本地,跨机房难落地
XtraBackup 全量 + 增量是 1TB 级迁移的事实标准
它绕过 SQL 层,直接复制物理文件,速度比 mysqldump 快 5–10 倍,且全程不锁表。关键不是“备份快”,而是“可衔接复制”——这才是不停机的核心。
- 全备命令必须带
--no-timestamp和--parallel=4(根据 CPU 核数调),避免目录嵌套和单线程瓶颈 - 增量备份要基于上一次全备的
xtrabackup_checkpoints中的to_lsn,不是时间戳,否则--prepare会报错LSN mismatch - 准备阶段必须分两步:
xtrabackup --prepare --apply-log-only --target-dir=全备目录(仅合并日志),再--prepare --target-dir=增量目录(应用增量) - 恢复时别用
--copy-back:如果目标磁盘空间紧张,改用--move-back或手动cp --reflink=always(支持 btrfs/xfs)节省空间
切库前最后 5 分钟怎么稳住不丢数据?
不是等从库 Seconds_Behind_Master = 0 就切,那只是复制线程状态,不代表 binlog 已全部 apply。真实一致性靠位点比对。
- 在源库执行
FLUSH LOGS; SHOW MASTER STATUS;,记下File和Position - 在目标从库执行
SHOW SLAVE STATUS\G,确认Relay_Master_Log_File和Exec_Master_Log_Pos与源库完全一致 - 切库前执行
STOP SLAVE IO_THREAD;,等Seconds_Behind_Master归零后再STOP SLAVE SQL_THREAD;,此时数据静止 - 应用层做连接池 draining(如设置
maxLifetime=30s),旧连接自然消亡,新连接打向新库——这比直接 kill 连接更安全
最容易被忽略的兼容性雷区
版本差一级、配置漏一项,IMPORT TABLESPACE 或 xtrabackup --prepare 就卡住,报错却无明确提示。
-
innodb_page_size必须完全相同:5.7 默认 16KB,8.0 可配 64KB,混用直接拒绝加载 -
lower_case_table_names值必须一致:Linux 上设为1才能跨大小写兼容,否则tablespace missing -
innodb_file_per_table=ON是硬性前提,否则.ibd文件无效,XtraBackup备份出来的ibdata1无法单独还原 - MySQL 5.7 和 8.0 的 redo log 格式不兼容,
XtraBackup 2.4不支持 8.0.30+,必须用8.0版本配套工具











