连载中 14/20

数据迁移(上):双写方案的全貌

2026-07-25 · 4008 阅读 · 0 评论 · 0 赞

为什么只剩双写一条路

把几亿行数据从老库搬到新的分片架构,先算时间账:全量拷贝按每小时千万行的安全速率,几天起步;期间线上业务还在持续写入——搬完的那一刻,数据已经过时了几天。停机迁移能终结这个死循环,但业务批不出这个窗口。于是唯一现实的方案浮出水面:老库照常服役,新库并行同步,两边数据追平后灰度切流。这套方案拆成四个阶段:存量同步 → 增量双写 → 全量校验 → 灰度切流,本篇讲前两个,校验与切流留给下一篇。

阶段一:存量同步

存量搬迁的技术选型不重要(dumponly、DataX、自研分批脚本都行),纪律才重要,三条:限速——搬迁查询压在源库安全水位以下(用空闲时段加限速批次,别把主库 IO 打满拖垮线上业务);断点续传——按主键或时间片分批,每批记水位,挂了从水位继续;与新库写入兼容——迁移程序写入新分片时绕过业务逻辑直接落库,但 ID、分片基因必须与线上规则严格一致,否则全量校验一地鸡毛。

阶段二:增量双写

存量在搬,增量在写——双写就是把这段「追赶期」的数据变更同时送达两个库。实现方式两条路,侵入度与可控性各有取舍:业务代码双写——在写路径里同时写老库与新分片,逻辑直白、排查直观,但每个写接口都要改、要防两库写一半(各自的本地事务,失败要靠补偿对账兜),代码侵入大;订阅 binlog 同步——老库仍是唯一写入口,binlog 被订阅程序捕获后转换成新分片的写入,业务代码零改造。binlog 链路天然有序、可靠,代价是多一套同步组件要维护:

业务 ──写入──> 老库(唯一权威) ──binlog──> 订阅同步服务
                                          ├─ 解析变更(表/行/操作)
                                          ├─ 按分片规则路由到新分片
                                          └─ 写入新库(失败进重试队列)

工程里更常见的组合是binlog 同步打底,双写只在关键路径做保险。无论哪种,两条纪律要立住:以老库为权威——双写期间老库的数据永远是基准,新库只许追不许改业务语义;失败只告警不阻塞——新库写失败绝不能影响线上业务,靠重试队列加对账修复,这是双写期间业务零感知的代价交换。

追赶与追平

存量同步与增量双写有个鸡生蛋的先后问题:存量搬了三天,期间的变更怎么办?标准答案是先启增量双写,再跑存量同步——双写把「此刻起」的变更送达新库,存量任务负责「此刻之前」的历史,两条线在时间上无缝衔接;重叠的少数边界数据,靠新库的幂等写入(主键冲突即跳过或覆盖)自然去重。当存量搬迁完成、双写延迟稳定趋近于零,就到了下一阶段:全量校验——数据「看起来追平」和「真的追平」之间,隔着一套严谨的核对体系,下一篇展开。

503

10 年全栈工程师 · 503咖啡馆主理人

#数据迁移#双写#binlog同步#存量搬迁#增量同步

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 5 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞