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

数据源页面显示“测试连接成功”,任务发布后仍然报表不存在、没有查询权限或连接中断,这种情况并不矛盾。测试连接通常只完成 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 执行的主调用链