数据库同步踩坑:全量、增量字段、CDC 到底该怎么选

最近做一个同步任务,问题不是“工具能不能跑”,而是“用哪种同步模式更不容易出事”。

源库是业务库,目标库是报表库。有人想每天全量覆盖,有人想按 update_time 做增量,也有人觉得直接上 CDC 最省心。最后我发现,真正要先问的不是“哪个更高级”,而是这些问题:

  • 目标库有没有历史数据?
  • 删除事件要不要同步?
  • update_time 是否一定可靠?
  • 源库日志和权限能不能准备好?
  • 任务失败后怎么确认目标库没少数据?

这篇按踩坑思路整理一下。工具上我用 DataMover 做验证,它能可视化配置全量、增量字段和 CDC,比较方便对比。这里的 DataMover 不是主角,主角还是同步模式选错以后会出现的漏数、重复和覆盖风险。

先看结论

场景推荐模式风险点
初始化目标库全量目标表已有数据时防误覆盖
低频刷新报表或测试库全量/定期覆盖大表执行时间和目标端索引
追加型业务表增量字段增量字段是否稳定推进
更新旧数据也要同步增量字段或 CDC更新时间字段是否可靠
删除事件必须同步CDC日志、权限、快照、位点
秒级延迟CDC源库和目标端压力

如果需要快速把这些模式跑起来对比,DataMover 是一个可视化的数据迁移同步工具,支持全量、增量字段和 CDC。Docker 环境下可以直接执行:

curl -fsSL https://down.datamover.cn/install.sh | bash

安装包入口:https://datamover.cn/download.html
文档地址:https://datamover.cn/doc/

试过的几种思路

直接全量

全量最容易理解,也最容易验证。缺点是大表成本高,目标表策略要特别清楚。

如果目标表为空,全量很好用。如果目标表已有数据,就要明确是清空、追加、写临时表,还是写新表再切换。这个策略不写清楚,后面出了问题没人说得清。

按字段增量

增量字段配置轻,不依赖数据库日志。自增 ID、update_time、入库时间都可以作为候选字段。

但它只适合字段可靠的表。比如 update_time 被业务代码统一维护,更新旧数据时一定变化,这就可以考虑。如果历史数据会回填,或者手工 SQL 不维护更新时间,就要小心漏数。

CDC

CDC 能捕获 INSERT、UPDATE、DELETE,适合实时同步。但它需要源库日志、权限、位点和快照策略。

这里的坑是:很多人只看到“实时”,没看到“前置条件”。上线前才发现 binlog 没开、账号权限不够、目标表已有数据不知道怎么处理,就很被动。

DataMover 配置过程

我用 DataMover 做这类任务时,一般按这个顺序:

  1. 新建源端数据源,测试连接。
  2. 新建目标端数据源,确认写入权限。
  3. 新建任务。全量/增量字段选普通任务,CDC 选实时任务。
  4. 选择源表和目标表。
  5. 检查字段映射,重点看类型、长度、默认值、主键。
  6. 普通任务配置同步策略:全量、增量字段、调度方式、批大小。
  7. 实时任务确认是否执行快照。
  8. 启动任务后查看输入、输出、失败数和执行日志。

DataMover 文档在这里:https://datamover.cn/doc/

DataMover 执行监控里能看到任务输入、输出和失败数据,这些信息要和后面的 SQL 校验一起看。

踩坑记录

1. 有更新时间字段,不代表可以放心增量

我见过不少表都有 update_time,但并不是每次更新都会维护。批处理脚本、历史修复脚本、人工 SQL 都可能绕过应用层逻辑。

处理方式:上线前抽样检查最近更新记录,确认 update_time 是否真的变化。

2. 目标表已有数据时,快照策略很危险

CDC 任务如果执行初始快照,就要确认目标表是否会被清空或覆盖。这个问题必须在任务启动前确认。

处理方式:目标表先备份,明确覆盖、追加、写新表还是从当前位点开始。

3. 进度 100% 不代表数据一致

任务完成只能说明流程跑完,不代表目标端数据和源端完全一致。目标端约束、字段截断、写入失败都可能导致数据少。

处理方式:看错误数据和日志,再跑 SQL 校验。

4. 批大小不是越大越好

批大小太大可能让 Worker 内存压力变高,也可能让目标端写入变慢。

处理方式:先用默认值跑通,再根据目标库写入能力和机器配置调整。

上线检查清单

检查项现场表现处理方式
增量字段不可靠增量同步漏历史回填数据改用 CDC 或补回填同步
目标表已有数据快照或清空导致数据被覆盖先备份,明确写入策略
字段类型不匹配写入失败、精度丢失先小表试跑并检查映射
字符集/时区不一致中文乱码、时间偏移统一连接参数
DDL 变更无流程源端加字段后目标端写入失败上线前约定 DDL 变更流程
只看进度目标端实际少数据增加 SQL 校验和错误数据检查

SQL 校验

-- 行数校验
SELECT COUNT(*) FROM source_table;
SELECT COUNT(*) FROM target_table;

-- 时间范围校验
SELECT MIN(update_time), MAX(update_time) FROM source_table;
SELECT MIN(update_time), MAX(update_time) FROM target_table;

-- 状态聚合校验
SELECT status, COUNT(*) FROM source_table GROUP BY status ORDER BY status;
SELECT status, COUNT(*) FROM target_table GROUP BY status ORDER BY status;

-- 抽样校验
SELECT * FROM source_table WHERE id IN (1, 100, 1000);
SELECT * FROM target_table WHERE id IN (1, 100, 1000);

金额类表:

SELECT status, COUNT(*) AS cnt, SUM(amount) AS total_amount
FROM source_table
GROUP BY status
ORDER BY status;

总结

我的选择顺序是:

  1. 要建立基线,先全量。
  2. 有可靠增量字段,可以用字段增量。
  3. 要同步删除、复杂更新或秒级延迟,再上 CDC。

DataMover 能把这些模式集中到 Web 界面里配置,适合少写脚本。官网在 https://datamover.cn ,安装入口是 https://datamover.cn/download.html 。但无论用什么工具,目标端校验都不能省。


DataMover
1 声望0 粉丝