异构数据同步最怕什么?不是同步慢,而是数据对不上

异构数据同步最怕什么?不是同步慢,而是数据对不上

做数据库迁移的时候,有一个问题我觉得比性能更让人头疼:

数据到底有没有真的迁对?

这个问题在项目没上线之前,很多人其实不会特别在意。

因为迁移阶段大家关注的通常都是进度:今天迁了多少张表,还有多少存储过程没改,增量同步延迟多少,什么时候能割接。

但真正到了切库那天,关注点一下就变了。

源库 1000 万条,目标库也是 1000 万条,然后呢?

能证明两边完全一样吗?

不能。

这也是我后来研究 KFS 时比较关注的一块:数据同步完成以后,它到底怎么证明数据是对的?

COUNT(*) 对得上,远远不够

以前做数据库迁移,最简单粗暴的办法就是查数量。

sql 复制代码
SELECT COUNT(*) FROM t_order;

Oracle 查一次,目标数据库再查一次。

两个结果都是:

text 复制代码
12586231

看起来没问题。

但这个结果最多只能说明:

两张表的记录数量一样。

至于是不是同样的 12586231 条数据,它证明不了。

比如源库:

text 复制代码
id=1001 amount=100
id=1002 amount=200

目标库:

text 复制代码
id=1001 amount=200
id=1002 amount=100

COUNT 一模一样,但数据已经错了。

更麻烦的是,生产数据库通常还在持续写入。

你刚查完源库的 COUNT,业务又进来 500 条数据;等你查目标库的时候,KFS 可能已经同步过去 300 条。

于是:

text 复制代码
源库:10000500
目标库:10000300

差 200 条。

这时候到底是同步异常,还是正常的同步延迟?

光看数量其实判断不了。

所以真正的数据校验,不能只解决"怎么比",还得先解决另外一个问题:

比较的到底是不是同一个时间点的数据。

这才是在线数据校验比较麻烦的地方。


为什么异构数据库的数据校验更难

如果两边都是同一种数据库,事情相对简单一些。

但实际国产化迁移经常是:

text 复制代码
Oracle      → KingbaseES
MySQL       → KingbaseES
SQL Server  → KingbaseES
PostgreSQL  → KingbaseES

这时候很多东西都可能发生变化。

数据类型映射是一个。

字符编码是一个。

NULL、空字符串、时间精度、数字精度又是一个。

再加上同步过程中还有 INSERT、UPDATE、DELETE,以及事务提交顺序的问题。

所以数据迁移并不是简单的:

text 复制代码
源端数据 → 复制 → 目标端

实际更接近:

text 复制代码
源数据库
   ↓
日志解析
   ↓
数据转换
   ↓
网络传输
   ↓
SQL转换
   ↓
目标端批量写入
   ↓
事务提交

其中任何一步出问题,都可能留下数据差异。

KFS 本身也是基于数据库增量日志进行数据捕获和实时同步的,官方资料里提到支持 DML/DDL、过滤转换、断点续传、重连重试以及在线数据比对修复。

这几个能力其实是连在一起的。

同步负责把数据送过去,断点机制负责故障之后知道"从哪里继续",校验负责回答"送过去的数据到底对不对"。

少一个都不太踏实。


KFS 的思路:同步和校验不要拆成两套系统

这点我觉得比单纯讲某个算法更有意思。

很多项目里的数据校验其实是后补的。

迁移工具负责迁移,迁完以后 DBA 再写 SQL 校验。

最后现场经常会变成这样:

text 复制代码
迁移:一套工具
同步:一套工具
COUNT:人工 SQL
抽样:人工 SQL
差异数据:Excel
修复:人工 UPDATE

数据量小时还能这么干。

几十 TB、几百张甚至几千张表以后,这种方式基本就开始失控了。

KFS 的处理方式是把同步、校验和修复放到一条链路里。

官方产品资料中明确提到:

支持全自动在线数据一致性校验与修复。

而且不只是简单比数量,还支持全量详细比对、筛选过滤比对、抽样比对和摘要比对。

这样就有点不一样了。

不是迁完以后再问:

"我们是不是还得找个工具校验一下?"

而是在迁移方案设计的时候,就把校验作为整个链路的一部分。


在线校验最关键的,其实是找到一个共同基准

这里可以结合 KFS 的断点机制来理解。

CDC 同步一直在往前跑:

text 复制代码
Oracle
   │
   │ Redo
   ↓
KFS
   │
   │ INSERT / UPDATE / DELETE
   ↓
KingbaseES

假设某一时刻:

text 复制代码
源端已经产生到:1005
目标端已经提交到:1000

这时候直接比较两边当前数据肯定会出现差异。

因为 1001~1005 本来就在同步路上。

因此要做可靠的数据一致性判断,首先要把比较范围确定下来。

KFS 的目标端入库设计本身就维护同步位点。

它的正常提交流程大致是:

text 复制代码
事件到达
   ↓
逐行回放 / Batch写入
   ↓
事务处理完成
   ↓
commit
   ↓
写入断点
   ↓
位点持久化

只有事务真正提交以后,位点才跟着推进。

这个设计很重要。

因为数据库里"写过"与"已经成功提交"是两回事。

有了这个位点之后,校验至少有机会回答:

我现在比较的是哪一个同步位置的数据?

而不是拿两个不断变化的数据集硬比。


多通道同步以后,事情会更复杂

单线程同步还比较好理解。

但 KFS 为了提高目标端写入能力,可以使用多个通道并行处理。

结构大概是:

text 复制代码
                ┌→ Channel 0 → Connection 0
事件 → Partitioner
                ├→ Channel 1 → Connection 1
                ├→ Channel 2 → Connection 2
                └→ Channel N → Connection N

这样性能确实上去了。

问题也跟着来了:

每个通道处理到的位置可能不一样。

比如:

text 复制代码
Channel 0 → seqno 100
Channel 1 → seqno 99
Channel 2 → seqno 97

系统突然挂了。

恢复的时候从哪里继续?

从 100 开始肯定不行,因为 Channel 2 还有数据没处理。

KFS 的方案是维护每个通道自己的处理位点,并记录待处理状态。恢复时先找到安全的重发起点,再判断哪些数据已经提交、哪些需要重新回放。

文档里给了一个很直观的例子:

text 复制代码
Channel 0 = 100
Channel 1 = 99
Channel 2 = 97

重发起点 = min = 97
lastMaxPoint = 100

97~100 之间不是无脑全部重新执行。

已经提交的数据跳过,没有提交的数据重新回放,100 之后再恢复正常同步。

这其实已经不只是"断点续传"四个字了。

真正困难的是:

既要敢于重放,又不能把已经成功的数据重复写一遍。

这和数据一致性本身就是一件事。


校验发现不一致,接下来才是真正麻烦的地方

以前人工做迁移时,我觉得最痛苦的其实不是发现差异。

而是:

发现差异以后怎么办?

假设一张订单表有 3000 万条数据。

校验以后发现 37 条不一致。

你接下来至少要搞清楚:

text 复制代码
哪37条?
源端是什么?
目标端是什么?
哪边才是正确数据?
INSERT少了?
UPDATE漏了?
DELETE没同步?
怎么补?
补完以后怎么证明真的好了?

如果这些全部人工处理,一两条还好。

几十张表同时出现问题,很快就会变成 Excel + SQL + 人肉对账。

所以我比较认可 KFS 的一个设计点:

校验和修复放在一起。

产品资料里明确写了:

全自动在线数据一致性校验与修复,保障数据一致性可视化,无需人为介入。

也就是说,校验的最终目的不是生成一张"有 37 条数据不一致"的报告。

而应该形成:

text 复制代码
发现差异
   ↓
定位差异记录
   ↓
修复
   ↓
再次校验
   ↓
确认一致

这个闭环对于真正做迁移的人来说,比"支持 MD5 校验"几个字有价值多了。


在实际项目里,这种能力到底有什么用?

KFS 产品资料里有几个真实案例,比自己假设一个"某银行"更有说服力。

比如某直辖市交通一卡通系统。

原系统的数据规模超过 12TB ,每天新增超过 500GB,而且要求 7×24 小时业务连续运行。

最终使用 KFS 做增量数据同步以及反向同步。

官方给出的项目结果是:

text 复制代码
12.3TB 存量数据迁移:< 3天
每日约 500GB 增量:秒级同步
数据一致性:不停机自动比对与修复

还有一个我觉得更能体现同步复杂度的案例:中国人民解放军总医院医疗云数据资源汇聚。

这个项目不是简单的 Oracle → KingbaseES。

源端同时存在 Oracle、SQL Server、MySQL、KingbaseES,而且操作系统还有 Windows、Linux、AIX、Solaris。

整体涉及:

text 复制代码
8个院区
400+业务系统
60TB+存量数据
300GB+每日增量

项目里除了实时采集,还涉及过滤、转换、映射以及数据一致性定时校验。

这才是异构同步工具真正面对的环境。

实验室里两张表同步成功并不难。

难的是几十 TB 数据、几百套业务系统、多个数据库类型同时存在的时候,系统还能告诉你:

哪些数据同步了,处理到哪里了,两边现在是不是一致,出了问题能不能恢复。


最后聊聊我现在怎么看数据迁移

以前我做数据库迁移的时候,会把注意力更多放在"迁"。

比如:

text 复制代码
迁移速度多少?
一天能跑几个TB?
同步延迟多少?
TPS多少?

这些当然重要。

但项目做多了以后,会发现真正决定你敢不敢切生产的,往往不是这些数字。

而是另外三个问题:

text 复制代码
数据有没有少?

数据有没有错?

出了问题能不能回去?

尤其是 Oracle 往国产数据库迁移以后,两边不是同一种数据库,很多以前默认成立的东西都需要重新验证。

所以现在再让我设计一套迁移方案,我不会把数据校验放在最后。

而是从一开始就把:

迁移、增量同步、位点管理、数据校验、差异修复、故障恢复

当成一套完整方案。

因为迁得快,只代表项目跑得快。

数据对得上,才代表这次迁移真的完成了。

相关推荐
程序员cxuan2 小时前
Claude 官方的学习教程,太强了。
人工智能·后端·程序员
老孙讲技术2 小时前
把工地遮挡和掉线接进项目部:setMessageCallback 订 alarm 与 deviceStatus
后端·物联网·音视频开发
老孙讲技术2 小时前
关店后有人进门,监控值班群却没响:用 setMessageCallback 订 human,再用 aiHuman 打开人形
后端·物联网·音视频开发
LEE2 小时前
原来 Claude Code 最厉害的工具,一行代码都不写
前端·后端
老孙讲技术2 小时前
把园区几百路摄像头收进值班台账:bindDevice 入账与 listDeviceDetailsByPage 翻页
后端·物联网·音视频开发
用户7813667114452 小时前
emplace_back vs push_back 详解
后端
老孙讲技术2 小时前
把没网没电的户外点位接进出画值班台:unBindDeviceInfo 核 SIMCard 与 bindDeviceLive
后端·物联网·音视频开发
万物智能2 小时前
硬件调试三板斧—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
后端·架构
小夏coding3 小时前
从"一把梭"到"精妙拆解" —— 滑动窗口计时框架的设计演进
java·后端