每一次,不夸张的说是每一次,在业务方问:「切了吗?什么时候能切?」
那一刻我心里想的都是另一件事:切过去容易,切坏了怎么退?
「MongoDB 迁移」这件事,真正让人睡不着觉的从来不是「怎么搬数据」,而是搬完之后的那几步------停机窗口怎么卡、切流怎么切、切坏了怎么回滚、数据对不对怎么验。这几步,工具教程不讲,官方文档一笔带过,但翻车全在这里。
今天这篇不聊工具选型(那个我单独写过),就专攻切流、回滚、校验这三件上线前必须想清楚的事。
一、迁移前:先把评估做扎实
动数据之前,先把这四件事算清楚,算不清楚别开工:
- 数据量:各集合的文档数、数据体积,决定全量搬运时间。
- 停机窗口:业务能容忍多久不可写?这是后面所有决策的锚点。
- 网络带宽:数据量 ÷ 带宽 = 全量搬运时间的下限。
- 目标集群规格:目标端 IO/内存/连接数能不能扛住切流后的真实读写。
- 目标库类型:是「MongoDB → MongoDB」的同构迁移,还是「MongoDB → 国产库」的异构迁移?如果是信创项目、目标端要落到金仓数据库 KingbaseES 这类国产库,评估里还得加两项------文档模型适配深度、异构增量同步工具(国产生态里金仓数据库的 KFS 就干这个)。
我见过最冤的翻车:迁移顺顺利利,切流后新库连接数被打满,业务全线超时------因为只算了数据量,没算切流后的读写规格。
二、停机窗口怎么算
不停机是理想,现实是「尽量短的停机窗口」。窗口的构成就三块:
停机窗口 ≈ 增量追平时长 + 切换动作时长 + 观察缓冲
- 增量追平时长:全量搬完后,追上「搬运期间新产生的写」需要多久。写入越猛、带宽越小,这段越长。
- 切换动作时长:停写 → 确认追平 → 切主 → 改连接串,几分钟到几十分钟。
- 观察缓冲:切完后留一段观察期,别急着下结论。
能压缩的只有「增量追平」这一段:选业务低峰、先限流部分非核心写,给增量一个追平的机会。
三、增量同步怎么追:全量 + 增量两段式
一次靠谱的 MongoDB 迁移,几乎都是「全量 + 增量」两段式:
- 全量阶段:把存量数据一次性搬过去(dump/restore、mongosync、实时迁移都在干这个)。
- 增量阶段:全量期间新产生的写,靠 oplog 位点持续追。源端记着「搬到哪个位点」,目标端从那个位点接着追。
判断追平的金标准:源端最新 oplog 位点 ≈ 目标端已应用的位点,且落后不再扩大。别只看「任务状态显示完成」,要看位点。
四、切流五步:一段能抄的流程
数据追平后,切流按这五步走,一步都别跳:
- 停写(或转只读):业务切到只读或暂停写入,制造静止点。
- 确认追平:核对源/目标文档数、最新位点一致。
- 执行切换:实时迁移做 cutover,或停掉同步任务、标记完成。
- 改连接串 :应用把连接地址切到新库(这一步最常漏,写进变更工单)。
- 观察期:盯新库的读写延迟、报错、连接数,留一段缓冲再收工。
切流的目标不是「快」,是「每一步都留着退路」。
五、回滚方案:切之前就写好
我见过最惨的割接:切到新库半小时才发现问题,旧库已经被删,回退无门。所以回滚方案必须在切流前写好:
- 旧库保留观察期:切成功后旧库至少留 7 天,期间保持同步或快照,别急着删。
- 应用层留双写开关:用配置控制「写旧库/写新库/双写」,一键回退。
- 回退动作 :改回旧连接串 → 旧库恢复可写 → 反向追平增量 → 重新切。回退本身也是一次迁移,别当儿戏。
回滚能不能成功,取决于你有没有提前保留旧库和数据位点。等真出事了才想,基本来不及。
六、迁移后数据校验:别用「感觉」验收
「迁移跑完了」和「迁移跑对了」是两码事。我的验收四件套:
- 数文档数 :源/目标分别
countDocuments({}),行数对上第一关。 - 核对索引 :
getIndexes()对比两侧索引名、字段、唯一性,索引缺失会让新库慢到怀疑人生。 - 抽样比对 :挑关键集合抽几条做字段级哈希比对,行数一样不代表内容一样。
- 应用连通性:用真实业务连新库跑读写,看报错和延迟。
过不了这四关,就别删旧库。
七、常见报错对照表
迁移过程里的高频报错,先对着查:
| 报错/现象 | 大概原因 | 先查什么 |
|---|---|---|
| 增量一直追不平 | 写入速率 > 同步速率 | 源库写入 QPS、带宽、同步延迟 |
too stale to catch up |
oplog 被覆盖、位点丢失 | oplog 窗口大小、从节点落后时间 |
| 报「版本不支持」 | 源库版本过旧 | 目标端支持矩阵 |
| 切完业务还打旧库 | 连接串没切 | 应用配置、DNS/负载均衡 |
| 新库查询极慢 | 索引缺失 | getIndexes() 对比 |
| 连接数被打满 | 目标规格不够 | 连接数上限、读写规格 |
迁移任务报 not authorized |
账号权限不足 | 源端读 oplog、目标端写权限 |
八、完整检查清单:上线前过一遍
- 迁移前评估:数据量、停机窗口、带宽、目标规格、目标库类型(同构/异构)
- 全量 + 增量两段式方案已定
- 停机窗口 = 追平时长 + 切换时长 + 缓冲,已测算
- 切流五步流程已写进变更工单(含连接串切换)
- 回滚方案已定:旧库保留、双写开关、回退动作
- 验收四件套已备:文档数/索引/抽样/连通性
- 常见报错对照表已打印,值班能对着查
- 观察期内监控已挂:延迟、报错、连接数
MongoDB 迁移真正难的,不是把数据搬过去,而是切流、回滚、校验这三件事有没有提前想清楚。 想清楚了,你也能凌晨两点不慌。
我是DBA小马哥,十年一线数据库运维。写的东西都是生产环境里趟出来的,关注我,少踩坑。