抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

CDC 任务第一次启动,通常要先把表里已有的数据读出来,再持续消费 Binlog。产品页面上这件事常被简化成两个阶段:全量完成,切到增量。真正的一致性问题恰好藏在“切”这个字里。

全量扫描可能持续几个小时,这期间业务仍在 INSERT、UPDATE、DELETE。先扫表、扫完以后再记 Binlog 位点,会漏掉扫描期间的变化;先记位点、等全量全部写完再读 Binlog,又必须保证这段日志不会被清理,而且下游能正确处理快照记录与后续变更。

Debezium 1.6.0.Final 的 MySQL connector 给出了一个可读的实现:在短暂锁定期间建立 repeatable read 事务,记录 Binlog 位点和表结构,然后释放全局读锁,在同一一致性视图里继续扫描表。这个位点才是全量与增量的边界。

Debezium MySQL 初始快照与 Binlog 衔接

数据源页面显示“测试连接成功”,任务发布后仍然报表不存在、没有查询权限或连接中断,这种情况并不矛盾。测试连接通常只完成 JDBC 建连,最多证明当前网络、账号和密码能建立一个短连接。

同步任务要求更多:Reader 要执行真实 SQL,切分键需要能参与查询;Writer 要有目标表写入权限,preSqlpostSql 还要通过语法检查。任务跑几个小时以后,连接空闲超时、游标、字符集和网络设备的行为也会出现。

DataX 在 2020 年底已经有两套不同深度的检查:DBUtil.testConnWithoutRetry() 和 Job 的 dryRun。把源码走一遍,就能知道页面上的绿色图标到底证明了什么。

DataX 数据源从建连到真实任务的检查层次

DataX 任务想容忍少量脏数据,通常会在 job.setting.errorLimit 里同时写条数和比例:小表不超过 10 条,大表不超过万分之一。这个意图很合理,但 2020 年底这版 DataX 并不会同时检查两条规则。

只要配置了 recordErrorRecordChecker 就把 percentageLimit 设成 null。两个参数都写时,真正生效的只有条数。

另一个容易混淆的配置是 core.statistics.collector.plugin.maxDirtyNumber。它限制的是控制台最多打印多少条脏数据,不是任务能够容忍多少条。把这两个 max 当成同一个阈值,会得到一条“日志看起来不多,任务却突然失败”或“日志只打印几条,任务居然成功”的链路。

这篇笔记仍然使用 DataX 提交 5485fb3,提交时间是 2020 年 12 月 17 日。

DataX 脏数据采集、日志输出与阈值检查

同步任务偶发失败时,加几次自动重试很诱人。网络抖一下能自己恢复,值班的人也少接一条告警。问题是,重试会把整个 Task 再执行一遍。Writer 如果不具备幂等能力,一次短暂故障很可能被放大成重复数据。

DataX 对这件事并非完全没有防护。它没有根据异常类型判断“可恢复”或“不可恢复”,而是把决定权交给 Writer:只有 Writer 明确声明支持 FailOver,TaskGroupContainer 才会重建 Task。

这篇笔记核对的是 2020 年 12 月 17 日的 DataX 提交 5485fb3,距离文章日期两天。先把源码行为说清楚,再讨论调度平台应该补哪一层。

DataX Task 失败后的重试状态

DataX 任务跑慢了,很多人的第一反应是把 job.setting.speed.byte 往上调。这个动作有时有效,有时一点反应都没有,偶尔还会把目标库写得更慢。

问题出在我们很容易把它理解成一个总限速开关。DataX 启动前会用速度预算计算 Channel 数量,运行中再由每个 Channel 统计吞吐并决定要不要休眠。Reader 和 Writer 之间还有一个有界队列。任何一环跟不上,都会把前后两端拖住。

下面的代码基于 DataX 提交 30842ca,提交时间是 2020 年 11 月 9 日。这样可以避开后来版本的改动,也和这篇笔记的时间对得上。

DataX 从速度预算到运行时背压的链路

DataX 一次同步任务可以压成一条主线:datax.py 组装 JVM 命令,Engine 读取任务 JSON,JobContainer 初始化并切分 Reader/Writer,调度器把 Task 分给若干 TaskGroupContainer,每个 Task 再用 Channel 连接 Reader 和 Writer。

这条链路里最容易混淆的是三个数量:Reader 切出了多少 Task、作业允许多少 Channel、每个 TaskGroup 能同时跑多少 Task。它们相关,但不是一个值。

这篇文章最初有 23 张调试截图,原 OSS 存储桶删除后无法恢复。2026 年整理旧文时,我没有继续保留空图片框,而是按 2020 年 10 月 13 日的 DataX 提交 3c03fedd 重新核对类和方法,并把真正需要看的关系重画成三张调用链图。原始发布时间不变,修订时间单独记录。

DataX 从 Engine 到 Task 执行的主调用链