目录

零停机数据库迁移:DTS 与备份导入方案技术选型

数据库迁移这事儿,说起来像搬家,做起来更像是给一辆行驶中的汽车换发动机——你不能让车停下来,还得多加小心别把零件装错位。上云也好,跨地域也好,引擎升级也好,不管什么场景,最后都绕不开三个核心问题:

  • 能停多久? 秒级?分钟级?还是能申请到几个小时的维护窗口?
  • 切过去之后能不能回得来? 回切之后数据还能不能对齐?
  • 团队扛不扛得住? 日志订阅、增量追赶、割接演练、监控告警,这条链路比日常运维复杂得多。

这篇文章聊两条最主流的路线:DTS/CDC 在线迁移停机备份导入

在线迁移的思路其实很直接:先把存量数据搬过去,再靠变更日志把增量追上,最后在一个很短的停写窗口里切过去。

标准的三段式流程:

  1. 结构迁移:表、索引、视图等 DDL 先同步过去
  2. 全量迁移:历史数据灌入目标库(建议低峰期跑)
  3. 增量同步:持续消费源库的变更日志——MySQL 的 Binlog、SQL Server 的 CDC 等——把新的写入实时同步到目标库,一直追到割接那一刻
  • 停写窗口极短:最终切换通常只需要秒级到分钟级的停写,具体取决于系统的停写能力和验证手段
  • 大库友好:数据量越大,一次性备份导入的风险就越高,而增量追赶可以提前把压力摊平
  • 日志强依赖:源库必须稳定产生变更日志并且允许订阅,日志配置一旦有问题,丢数据或者延迟堆积几乎是必然的
  • 割接流程严格:停写、追平、校验、切换、观测——最后一公里完全靠流程纪律,任何一步马虎都可能翻车
  • Binlog 已开启,保留时长充足,格式通常是 ROW
  • 迁移账号有源库读权限和日志订阅权限,目标库有写权限
  • 目标库的字符集、排序规则、时区、关键参数与源库兼容,否则会出现各种隐性差异

这条路没什么花哨的:停写、备份、传输、导入、验证、切连接、恢复。朴素,但往往也最可靠。

写进变更单的典型顺序:

  1. 公告维护窗口,冻结所有变更(代码、DDL、配置)
  2. 应用进入维护模式或直接停写
  3. 备份导出(逻辑备份或物理备份)
  4. 把备份传到目标环境
  5. 导入恢复
  6. 验证数据完整性和关键业务链路
  7. 切换连接,恢复服务
  • 工具链成熟,理解成本低:不需要引入额外的同步组件
  • 强一致:备份点就是一致性边界,不存在追增量的问题
  • 回退简单:只要备份之后源库确实没有写入,回切只需要把连接指回去

中断时间随数据量线性增长。 粗略估算:

停机时长 ≈ 停写 + 备份 + 传输 + 导入 + 验证

数据到 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

别靠偏好选,靠约束选。

两个经验判断(不是绝对阈值,最终以你自己的吞吐量和窗口为准):

  • 停机只能秒级到分钟级 → 在线迁移
  • 窗口充裕、数据量不大 → 备份导入更省心

然后沿着四个维度做最终判断:

  1. 业务容忍度:停机对收入、用户、SLA 的影响是否可控
  2. 数据规模与写入强度:库大不一定难,真正难的是高写入 + 长时间不能停写
  3. 技术可行性:源库的日志能力、网络带宽、跨云链路、版本和引擎差异
  4. 团队执行力:割接流程能不能演练到闭着眼跑

一个更具体的决策矩阵:

约束 / 场景 更推荐 原因
生产核心链路,7×24 在线 在线迁移 停写窗口最小化
大库或恢复时间不可预测 在线迁移 压力提前摊到增量阶段
有明确维护窗口,流程可控 备份导入 简单、强一致、回退直观
测试库 / 预发布 / 报表库 备份导入 在线迁移的复杂度不值得
源库无法稳定提供日志 备份导入 在线迁移根本不可用或风险太高

在线迁移真正的难点不在同步,而在切换。出事故往往源于一个词:冲突——双写导致主键冲突、覆盖更新、逻辑状态错乱。

  1. 停写:维护模式、网关断流或者直接停应用,关键是确认真的没有写入了
  2. 追平增量:等同步延迟收敛到可接受范围,最好是 0
  3. 最终校验:光靠抽样不够的话,做校验和或者表级对账
  4. 切连接:配置批量切换,保证一次性生效
  5. 恢复写入并观测:确认新流量只写目标库,盯紧错误率、延迟和关键业务指标
  6. 保留回退路径:源库先以只读模式保留一段时间,观察期过了再退役

一致性校验(MySQL):

pt-table-checksum --nocheck-replication-filters --databases=dbname h=src_host

关于双写:如果割接前让应用同时写源库和目标库,务必有明确的冲突解决策略——幂等写、业务层去重、统一序列号、严格顺序保证,至少得有一样。否则迁移工具救不了你。

  • 先预演:至少跑通一次"全量 + 增量 + 割接 + 回退"的完整链路,再上生产
  • 全量阶段限速:别把源库压垮了,目标库也要留够写入和建索引的余量
  • 监控四个维度:同步延迟、失败重试、目标库写入错误、源库日志增长与保留期
  • 先迁最少的对象:必要的库和表先迁,降低第一次割接的不确定性
  • 导入是瓶颈:优先选支持并行恢复的工具链
  • 超大库走物理备份:Xtrabackup 这类工具比逻辑备份稳得多,不容易跑到一半挂掉
  • 传输要有保障:专线、对象存储直传、断点续传,都好过 scp 硬传
  • 能拆就拆:按业务域或时间范围分批迁移,单次失败的爆炸半径小一些
  • 权限验证:源库读 + 日志访问、目标库写,提前确认到位,别到割接的时候才发现权限不够
  • 容量预留:CPU、内存、IOPS、磁盘空间预留 30% 以上,参数和连接数上限也要提前对齐
  • 回退方案:什么时候回退、怎么回退、回退要做哪些清理,白纸黑字写清楚,并预留执行时间
  • 沟通:迁移窗口、影响范围、冻结策略、负责人和应急联系人,全部对齐

想要最小停机且数据量大,选在线迁移,但前提是割接流程得演练到位、可观测性跟得上。维护窗口充裕、数据规模可控,备份导入往往更稳更省心,关键在于并行化和充分预演。

说到底,选哪条路不是重点,重点是能不能把停写、校验、切换、回退这四件事变成一套可重复、可验证的流程。做到了,哪条路都能走通。