Apache SeaTunnel MySQL CDC 支持按时间启动吗?

在 MySQL CDC 任务中,很多用户都会遇到这样的问题:任务失败后该从哪里恢复?
17700288037466752b03a3968dd62

点击蓝字



关注我们


在 MySQL CDC 任务中,很多用户都会遇到这样的问题:任务失败后该从哪里恢复?只知道一个时间点,却拿不到对应的 binlog 位点怎么办?Apache SeaTunnel 2.3.12 通过引入按时间启动(Timestamp Startup)功能,给出了更直观的答案。

本文围绕该能力的设计背景、配置方式与实现机制展开解析,帮助读者理解如何基于时间语义更高效地进行 CDC 任务恢复与数据回溯。

功能概述


Problem:CDC 启动点配置“技术正确,但使用困难”

在 Apache SeaTunnel 2.3.12 之前,MySQL CDC 连接器主要支持从指定 binlog 位点(file + position)或 GTID 启动数据同步任务。这种方式在实现上是精确且可靠的,但在真实生产与运维场景中,往往并不符合用户的使用习惯。

在实际 CDC 运维过程中,用户更容易掌握的是 “时间”,而非底层 binlog 细节,例如:

  • 任务异常中断后,希望从
    “2024-04-01 10:00:00” 之后继续同步
  • 对某一时间窗口的数据进行回溯或补采
  • 只知道“昨天 08:00 之后的变更需要重新同步”,但无法定位对应的 binlog 文件和偏移量

如果仍要求用户手动将时间反推为 binlog 位点,不仅配置复杂,而且极易出错,也显著增加了运维成本。这种“技术友好、但用户不友好”的启动方式,已经成为 CDC 任务恢复和回溯场景中的常见痛点。

Solution:引入按时间启动

为解决上述问题,Apache SeaTunnel 在 2.3.12 版本中为 MySQL CDC 连接器引入了按时间启动功能

该功能允许用户直接指定一个 Unix 时间戳(毫秒级) 作为同步起始点。MySQL CDC 连接器会在启动阶段自动完成以下工作:

  1. 根据指定时间戳定位对应的 binlog 文件与偏移量
  2. 从该 binlog 位置开始读取变更事件
  3. 自动跳过所有早于该时间点的历史事件

通过引入“时间”这一更符合业务语义的维度,SeaTunnel 将 CDC 启动方式从面向底层 binlog 细节,提升为面向业务时间语义,显著降低了 CDC 任务在恢复、回溯和运维场景下的使用门槛。

配置参数


要启用按时间启动功能,需要配置以下两个关键参数:

参数名
类型
必填
说明
startup.mode
Enum
设置为 "timestamp" 启用时间模式 2
startup.timestamp
Long
Unix 时间戳(毫秒),指定启动时间点 3


配置示例






















env {  parallelism = 1  job.mode = "STREAMING"  checkpoint.interval = 10000}source {  MySQL-CDC {    url = "jdbc:mysql://localhost:3306/testdb"    username = "root"    password = "root@123"    table-names = ["testdb.table1"]    # 启用按时间启动    startup.mode = "timestamp"    startup.timestamp = 1672531200000  # 2023-01-01 00:00:00 UTC  }}sink {  Console {  }}


技术实现


1770028805100c2e290974cd72671

启动模式枚举

MySqlSourceOptions 类中定义了所有支持的启动模式,包括新增的 TIMESTAMP 模式:












public static final SingleChoiceOption<StartupMode> STARTUP_MODE =    (SingleChoiceOption)        Options.key(SourceOptions.STARTUP_MODE_KEY)            .singleChoice(                StartupMode.class,                Arrays.asList(                    StartupMode.INITIAL,                    StartupMode.EARLIEST,                    StartupMode.LATEST,                    StartupMode.SPECIFIC,                    StartupMode.TIMESTAMP))

时间戳过滤实现

核心实现在 MySqlBinlogFetchTask 类中,当检测到启动模式为 TIMESTAMP 时,会使用 TimestampFilterMySqlStreamingChangeEventSource 来处理 binlog 事件:

















StartupMode startupMode = startupConfig.getStartupMode();if (startupMode.equals(StartupMode.TIMESTAMP)) {    log.info(        "Starting MySQL binlog reader,with timestamp filter {}",        startupConfig.getTimestamp());    mySqlStreamingChangeEventSource =        new TimestampFilterMySqlStreamingChangeEventSource(            sourceFetchContext.getDbzConnectorConfig(),            sourceFetchContext.getConnection(),            sourceFetchContext.getDispatcher(),            sourceFetchContext.getErrorHandler(),            Clock.SYSTEM,            sourceFetchContext.getTaskContext(),            sourceFetchContext.getStreamingChangeEventSourceMetrics(),            startupConfig.getTimestamp());}

偏移量计算

MySqlSourceFetchTaskContext 中实现了根据时间戳查找对应 binlog 偏移量的逻辑:















private Offset getInitOffset(SourceSplitBase mySqlSplit) {    StartupMode startupMode = getSourceConfig().getStartupConfig().getStartupMode();    if (startupMode.equals(StartupMode.TIMESTAMP)) {        long timestamp = getSourceConfig().getStartupConfig().getTimestamp();        try (JdbcConnection jdbcConnection =                getDataSourceDialect().openJdbcConnection(getSourceConfig())) {            return findBinlogOffsetBytimestamp(jdbcConnection, binaryLogClient, timestamp);        } catch (Exception e) {            throw new SeaTunnelException(e);        }    } else {        return mySqlSplit.asIncrementalSplit().getStartupOffset();    }}


启动模式对比与适用场景


为了更好地理解按时间启动功能在整体 CDC 启动体系中的定位,下面对 MySQL CDC 当前支持的几种启动模式进行对比说明:

启动模式
启动依据
优点
适用场景
INITIAL
全量 + 当前 binlog
一次性完成历史与增量同步
首次接入数据源
EARLIEST
最早可用 binlog
不依赖具体位点
binlog 保存周期较长的场景
LATEST
当前最新 binlog
启动快
仅关注未来增量数据
SPECIFIC
指定 binlog file + position
精确可控
已明确掌握 binlog 位点的场景
TIMESTAMP
指定时间戳(毫秒)
配置直观、符合业务语义
任务恢复、数据回溯、按时间窗口同步

可以看到,TIMESTAMP 模式并不是替代 SPECIFIC 或 GTID 的“更底层”方案,而是为了解决“用户只知道时间、不知道 binlog”的典型问题,是一种以可用性和运维友好性为核心的补充能力

测试验证


该功能在集成测试中得到了充分验证,测试用例 MysqlCDCSpecificStartingOffsetIT 验证了按时间戳启动的正确性 7

使用注意事项


  1. 版本要求:需要 SeaTunnel 2.3.12 或更高版本

  2. 时间戳格式:必须使用 Unix 时间戳,单位为毫秒

  3. binlog 可用性:确保指定时间点对应的 binlog 文件仍然可用

  4. 时区考虑时间戳基于 UTC 时区,需要注意时区转换

  5. 该功能在工厂类MySqlIncrementalSourceFactory中通过条件配置规则进行参数验证
  6. 除了 MySQL CDC,其他 CDC 连接器如 SQL Server CDC 也支持类似的时间戳启动功能

总结


SeaTunnel MySQL CDC 的按时间启动功能为数据同步提供了更精确的控制能力,特别适用于需要从特定时间点恢复数据同步的场景。该功能通过时间戳到 binlog 偏移量的转换,实现了高效的时间点定位和数据过滤。

Apache SeaTunnel

Apache SeaTunnel是一个云原生的多模态、高性能海量数据集成工具。北京时间 2023 年 6 月1 日,全球最大的开源软件基金会ApacheSoftware Foundation正式宣布Apache SeaTunnel毕业成为Apache顶级项目。目前,SeaTunnel在GitHub上Star数量已达8k+,社区达到6000+人规模。SeaTunnel支持在云数据库、本地数据源、SaaS、大模型等170多种数据源之间进行数据实时和批量同步,支持CDC、DDL变更、整库同步等功能,更是可以和大模型打通,让大模型链接企业内部的数据。




同步Demo

MySQL→Doris | MySQLCDC | MySQL→Hive | HTTP → Doris | HTTP → MySQL | MySQL→StarRocks|MySQL→Elasticsearch |Kafka→ClickHouse

新手入门

SeaTunnel 让数据集成变得 So easy!/ 3 分钟入门指南
0 到 1 快速入门 /初探/深入理解
分布式集群部署 | CDC数据同步管道 | Oracle-CDC
图片

最佳实践

中控技术天翼云多点OPPO | 清风马蜂窝孩子王哔哩哔哩唯品会众安保险兆原数通 | 亚信科技|映客|翼康济世|信也科技|华润置地|Shopee|京东科技|58同城|互联网银行|JPMorgan
图片

测试报告

SeaTunnel VS GLUE | VS Airbyte | VS DataX|SeaTunnel 与 DataX 、Sqoop、Flume、Flink CDC 对比

图片

源码解析

Zeta引擎源码解析(一) |(二) |(三)| API 源码解析 |2.1.1源码解析|封装 Flink 连接数据库解析





仓库地址:
https://github.com/apache/seatunnel
网址:
https://seatunnel.apache.org/
Apache SeaTunnel 下载地址:
https://seatunnel.apache.org/download
衷心欢迎更多人加入!
我们相信,在Community Over Code(社区大于代码)、「Open and Cooperation」(开放协作)、「Meritocracy」(精英管理)、以及「多样性与共识决策」The Apache Way 的指引下,我们将迎来更加多元化和包容的社区生态,共建开源精神带来的技术进步!
我们诚邀各位有志于让本土开源立足全球的伙伴加入 SeaTunnel 贡献者大家庭,一起共建开源!
提交问题和建议:
https://github.com/apache/seatunnel/issues
贡献代码:
https://github.com/apache/seatunnel/pulls
订阅社区开发邮件列表 :
dev-subscribe@seatunnel.apache.org
开发邮件列表:
dev@seatunnel.apache.org
加入 Slack:
https://join.slack.com/t/apacheseatunnel/shared_invite/zt-1kcxzyrxz-lKcF3BAyzHEmpcc4OSaCjQ
关注 X.com:
https://x.com/ASFSeaTunnel


1770028807404380e33dab0cdb518
17700288079135f5d4ce5255f6015
1770028808453a1d1e5050dd435c2