Flink Connector 26.3.0 读取 DATETIME 变成 1970 年,切换 25.0.0 后正常

Viewed 8

大家好,我们使用 Flink SQL 读取 Doris 数据时遇到日期字段解析异常,想请教是否属于已知兼容问题,以及是否有推荐的修复方案。

一、运行环境

  • Doris 服务端:SelectDB 2.1.8-3
  • Flink:基于 1.20 的公司发行版
  • Connector:org.apache.doris:flink-doris-connector-1.20
  • 异常版本:26.3.0
  • 切换后正常的版本:25.0.0
  • 读取方式:Thrift
  • Arrow Flight SQL:未启用,FE 的 arrow_flight_sql_port 为 -1
  • 日期对比时区:UTC+08:00
  • 类型映射:Doris DATETIME → Flink TIMESTAMP(0)

目前是在上述 SelectDB 环境中观察到此问题,尚未在原生 Apache Doris 2.1.8 上独立复现。

二、问题现象

同一条数据的 ctime、mtime 字段,对比结果如下:

查询方式 日期结果
Doris 直接查询 2026-07-30 19:44:28
Flink Connector 26.3.0 读取 1970-01-01 08:29:45.411868
切换到 Flink Connector 25.0.0 后 2026-07-30 19:44:28

BIGINT、字符串等普通字段读取正常。

错误日期也出现在 TaskManager 原始输出日志中,因此不是平台页面展示问题。在 Flink 中将 TIMESTAMP 显式 CAST AS STRING 后,输出仍然错误。

目前已通过切换 Connector 至 25.0.0,确认该条数据的日期恢复正常。

三、测试 SQL(已脱敏)

源表为已有的 Doris OLAP 表,字段类型为 BIGINT、VARCHAR、DATETIME。下面是实际测试 SQL 的脱敏形式,表名、记录 ID 和连接信息已替换;该示例尚未在原生 Apache Doris 上独立复现。

源记录的 ctime、mtime 均为 2026-07-30 19:44:28。

CREATE TABLE doris_datetime_probe (
    id BIGINT,
    name STRING,
    ctime TIMESTAMP(0),
    mtime TIMESTAMP(0)
) WITH (
    'connector' = 'doris',
    'fenodes' = '<FE_HOST>:<HTTP_PORT>',
    'table.identifier' = 'test.datetime_probe',
    'username' = '<USER>',
    'password' = '<PASSWORD>'
);

CREATE TABLE datetime_probe_print (
    id BIGINT,
    name STRING,
    ctime STRING,
    mtime STRING
) WITH (
    'connector' = 'print'
);

INSERT INTO datetime_probe_print
SELECT
    id,
    name,
    CAST(ctime AS STRING),
    CAST(mtime AS STRING)
FROM doris_datetime_probe
WHERE id = 1;

四、源码对比线索

对比官方发布源码中的:

org.apache.doris.flink.serialization.RowBatch

发现两个版本的时间转换方式不同。

Connector 25.0.0

getDateTime() 取出原始 long 值,调用 longToLocalDateTime(long),根据数值大小判断时间单位:

if (time < 10_000_000_000L) {
    // 秒
    instant = Instant.ofEpochSecond(time);
} else if (time < 10_000_000_000_000L) {
    // 毫秒
    instant = Instant.ofEpochMilli(time);
} else {
    // 微秒
    instant = Instant.ofEpochSecond(
        time / 1_000_000,
        (time % 1_000_000) * 1_000);
}

源码中还有这段说明:

// todo: Currently, the scale of doris's arrow datetimev2 is hardcoded to 6,
// and there is also a time zone problem in arrow, so use timestamp to convert first

Connector 26.3.0

getDateTime() 改为使用 Arrow 时间类型的元数据。

对于带时区元数据的时间戳,调用:

return longToLocalDateTime(
    vector.get(rowIndex),
    timestampType.getUnit(),
    DEFAULT_ZONE_ID);

其中 MICROSECOND 分支为:

instant = Instant.ofEpochSecond(
    Math.floorDiv(time, 1_000_000L),
    Math.floorMod(time, 1_000_000L) * 1_000L);

对于没有时区元数据的时间戳,则使用 vector.getObject()。

五、怀疑原因

在 UTC+08:00 下:

  • 2026-07-30 19:44:28 对应的 Unix 秒时间戳为 1785411868。
  • 如果把同一个数值 1785411868 按微秒解析,结果正好是 1970-01-01 08:29:45.411868。

这与实际错误输出完全一致。

因此怀疑存在“原始数值实际为秒,但 Arrow 元数据标注为微秒”的情况。25.0.0 的数值判断逻辑可能容忍了这种情况,而 26.3.0 按元数据解析后暴露了问题。

需要说明:目前尚未捕获原始 Arrow 数值、unit、timezone,以及运行时 RowBatch 的实际加载位置,因此上述原因仍然是假设,不能据此直接判定服务端或 Connector 哪一端存在 bug。也尚未确定 25.0.0 到 26.3.0 之间,具体从哪个版本开始出现这一变化。

六、希望社区协助确认

  1. 这是已知的时间编码/解码兼容问题吗?
  2. 具体影响哪些 Doris/SelectDB 版本、Connector 版本和读取方式?
  3. 是否有修复版本、兼容配置或推荐的版本组合?
  4. 官方兼容表中的 Doris 版本支持范围较宽,能否补充相关限制说明?
  5. 如果需要进一步定位,建议补充哪些服务端或 Connector 诊断信息?

七、相关链接

GitHub issue:
https://github.com/apache/doris/issues/68392

Connector 25.0.0 官方源码包:
https://repo.maven.apache.org/maven2/org/apache/doris/flink-doris-connector-1.20/25.0.0/flink-doris-connector-1.20-25.0.0-sources.jar

Connector 26.3.0 官方公共模块源码包:
https://repo.maven.apache.org/maven2/org/apache/doris/flink-doris-connector-base/26.3.0/flink-doris-connector-base-26.3.0-sources.jar

感谢大家协助排查!

0 Answers