零停机数据库迁移:DTS 与备份导入方案技术选型
目录
数据库迁移这事儿,说起来像搬家,做起来更像是给一辆行驶中的汽车换发动机——你不能让车停下来,还得多加小心别把零件装错位。上云也好,跨地域也好,引擎升级也好,不管什么场景,最后都绕不开三个核心问题:
- 能停多久? 秒级?分钟级?还是能申请到几个小时的维护窗口?
- 切过去之后能不能回得来? 回切之后数据还能不能对齐?
- 团队扛不扛得住? 日志订阅、增量追赶、割接演练、监控告警,这条链路比日常运维复杂得多。
这篇文章聊两条最主流的路线:DTS/CDC 在线迁移和停机备份导入。
DTS/CDC 在线迁移
原理
在线迁移的思路其实很直接:先把存量数据搬过去,再靠变更日志把增量追上,最后在一个很短的停写窗口里切过去。
标准的三段式流程:
- 结构迁移:表、索引、视图等 DDL 先同步过去
- 全量迁移:历史数据灌入目标库(建议低峰期跑)
- 增量同步:持续消费源库的变更日志——MySQL 的 Binlog、SQL Server 的 CDC 等——把新的写入实时同步到目标库,一直追到割接那一刻
优势
- 停写窗口极短:最终切换通常只需要秒级到分钟级的停写,具体取决于系统的停写能力和验证手段
- 大库友好:数据量越大,一次性备份导入的风险就越高,而增量追赶可以提前把压力摊平
代价
- 日志强依赖:源库必须稳定产生变更日志并且允许订阅,日志配置一旦有问题,丢数据或者延迟堆积几乎是必然的
- 割接流程严格:停写、追平、校验、切换、观测——最后一公里完全靠流程纪律,任何一步马虎都可能翻车
上线前的前置检查(MySQL 为例)
- Binlog 已开启,保留时长充足,格式通常是
ROW - 迁移账号有源库读权限和日志订阅权限,目标库有写权限
- 目标库的字符集、排序规则、时区、关键参数与源库兼容,否则会出现各种隐性差异
停机 + 备份导入
原理
这条路没什么花哨的:停写、备份、传输、导入、验证、切连接、恢复。朴素,但往往也最可靠。
写进变更单的典型顺序:
- 公告维护窗口,冻结所有变更(代码、DDL、配置)
- 应用进入维护模式或直接停写
- 备份导出(逻辑备份或物理备份)
- 把备份传到目标环境
- 导入恢复
- 验证数据完整性和关键业务链路
- 切换连接,恢复服务
优势
- 工具链成熟,理解成本低:不需要引入额外的同步组件
- 强一致:备份点就是一致性边界,不存在追增量的问题
- 回退简单:只要备份之后源库确实没有写入,回切只需要把连接指回去
短板
中断时间随数据量线性增长。 粗略估算:
停机时长 ≈ 停写 + 备份 + 传输 + 导入 + 验证
数据到 TB 级别的时候,任何一个环节超时或者失败都很常见,整次迁移容易变成一场赌博。
常用命令参考
MySQL 逻辑备份:
mysqldump --single-transaction --routines --triggers --events dbname > db.sql
MySQL 并行导出/导入(大库、多表场景更合适):
mydumper -B dbname -o dump_dir -t 8
myloader -B dbname -d dump_dir -t 8
PostgreSQL 并行恢复(配合目录格式):
pg_dump -Fd -j 8 -f dump_dir dbname
pg_restore -j 8 -d dbname dump_dir
怎么选
别靠偏好选,靠约束选。
两个经验判断(不是绝对阈值,最终以你自己的吞吐量和窗口为准):
- 停机只能秒级到分钟级 → 在线迁移
- 窗口充裕、数据量不大 → 备份导入更省心
然后沿着四个维度做最终判断:
- 业务容忍度:停机对收入、用户、SLA 的影响是否可控
- 数据规模与写入强度:库大不一定难,真正难的是高写入 + 长时间不能停写
- 技术可行性:源库的日志能力、网络带宽、跨云链路、版本和引擎差异
- 团队执行力:割接流程能不能演练到闭着眼跑
一个更具体的决策矩阵:
| 约束 / 场景 | 更推荐 | 原因 |
|---|---|---|
| 生产核心链路,7×24 在线 | 在线迁移 | 停写窗口最小化 |
| 大库或恢复时间不可预测 | 在线迁移 | 压力提前摊到增量阶段 |
| 有明确维护窗口,流程可控 | 备份导入 | 简单、强一致、回退直观 |
| 测试库 / 预发布 / 报表库 | 备份导入 | 在线迁移的复杂度不值得 |
| 源库无法稳定提供日志 | 备份导入 | 在线迁移根本不可用或风险太高 |
割接:在线迁移最容易出事的地方
在线迁移真正的难点不在同步,而在切换。出事故往往源于一个词:冲突——双写导致主键冲突、覆盖更新、逻辑状态错乱。
割接 Checklist
- 停写:维护模式、网关断流或者直接停应用,关键是确认真的没有写入了
- 追平增量:等同步延迟收敛到可接受范围,最好是 0
- 最终校验:光靠抽样不够的话,做校验和或者表级对账
- 切连接:配置批量切换,保证一次性生效
- 恢复写入并观测:确认新流量只写目标库,盯紧错误率、延迟和关键业务指标
- 保留回退路径:源库先以只读模式保留一段时间,观察期过了再退役
一致性校验(MySQL):
pt-table-checksum --nocheck-replication-filters --databases=dbname h=src_host
关于双写:如果割接前让应用同时写源库和目标库,务必有明确的冲突解决策略——幂等写、业务层去重、统一序列号、严格顺序保证,至少得有一样。否则迁移工具救不了你。
实战经验
在线迁移的几个要点
- 先预演:至少跑通一次"全量 + 增量 + 割接 + 回退"的完整链路,再上生产
- 全量阶段限速:别把源库压垮了,目标库也要留够写入和建索引的余量
- 监控四个维度:同步延迟、失败重试、目标库写入错误、源库日志增长与保留期
- 先迁最少的对象:必要的库和表先迁,降低第一次割接的不确定性
备份导入的几个要点
- 导入是瓶颈:优先选支持并行恢复的工具链
- 超大库走物理备份:Xtrabackup 这类工具比逻辑备份稳得多,不容易跑到一半挂掉
- 传输要有保障:专线、对象存储直传、断点续传,都好过
scp硬传 - 能拆就拆:按业务域或时间范围分批迁移,单次失败的爆炸半径小一些
不管哪种方案,都得提前做好
- 权限验证:源库读 + 日志访问、目标库写,提前确认到位,别到割接的时候才发现权限不够
- 容量预留:CPU、内存、IOPS、磁盘空间预留 30% 以上,参数和连接数上限也要提前对齐
- 回退方案:什么时候回退、怎么回退、回退要做哪些清理,白纸黑字写清楚,并预留执行时间
- 沟通:迁移窗口、影响范围、冻结策略、负责人和应急联系人,全部对齐
总结
想要最小停机且数据量大,选在线迁移,但前提是割接流程得演练到位、可观测性跟得上。维护窗口充裕、数据规模可控,备份导入往往更稳更省心,关键在于并行化和充分预演。
说到底,选哪条路不是重点,重点是能不能把停写、校验、切换、回退这四件事变成一套可重复、可验证的流程。做到了,哪条路都能走通。