TiCDC时区问题

【TiDB 使用环境】生产环境
遇到一个非常神奇的问题,求助各路大神。。。tidb数据库集群设置的时区是北京时间,ticdc设置的时区也是北京时间,但发送到kafka的时间有问题,timestamp显示utc时间,少了8小时,datatime显示的时间戳又多了8小时

数据库时区


ticdc时区
image

Changefeed

./cdc cli changefeed create --server=http://10.*.*.*:8300 --sink-uri="kafka://10.*.*.*:9092/ticdc_cyf?protocol=debezium&kafka-version=3.9.0&partition-num=1&max-message-bytes=67108864&replication-factor=1" --changefeed-id="simple-replication-task" --config=/data/tidb/changefeed.conf

结果:
数据库时间(时间1是timestamp,时间2是datatime):
image

Kafka消息的时间:
“t1”:“2025-06-20T07:54:31Z”,“t2”:1752421130000
image

看起来还是时区读取异常

确保输出的 timestamp 字段带有明确的时区标识,例如 “ts”: “2025-07-14T13:30:00+08:00”

需要重启集群吗?

时区都配置了,像是没生效的样子

可以建一个 issue 吗?

有点困难,网络被管控了 :cry:

kafka 是没有 time-zone 这个参数的 https://docs.pingcap.com/zh/tidb/stable/ticdc-sink-to-kafka/

1 个赞

额,这个参数,我看发送到MySQL的Changefeed配置sink-uri中有,就拿过来试试。 Changefeed的time-zone是最后没办法了才想加上试试

这里预期的结果是什么呢?

预期结果是不管在数据库中时间是什么样,发送到kafka消息的时间能和数据库保持一致,不管是什么格式起码转换后能一致

可以给下 case 吗?我这里复现下

CREATE TABLE user_info (
id bigint NOT NULL AUTO_INCREMENT COMMENT ‘自增主键’,
user_code varchar(200) NOT NULL COMMENT ‘用户编码’,
user_name varchar(200) NOT NULL COMMENT ‘用户名称’,
phone varchar(200) DEFAULT NULL COMMENT ‘电话’,
email varchar(200) DEFAULT NULL COMMENT ‘邮箱’,
created_time timestamp NOT NULL COMMENT ‘创建时间’,
updated_time datetime DEFAULT NULL COMMENT ‘最后修改时间’,
PRIMARY KEY (id) /*T![clustered_index] CLUSTERED */
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin AUTO_INCREMENT=42857281846452003 COMMENT=‘用户表’;

INSERT INTO test.user_info (user_code,user_name,phone,email,created_time,updated_time) VALUES
(‘123123123112’,‘1111111’,‘2222222’,‘3333333’,‘2025-07-13 15:54:31’,‘2025-07-13 15:38:50’);

changefeed.conf

[consistent]
level = "none"

[filter]
rules = ["test.user_info"]
ignore-txn-start-ts = []

[mounter]
worker-num = 16

# Sink 配置
[sink]
protocol = "debezium"
dispatchers = [
  {matcher = ['test.user_info'], partition = "index-value" }
]
./cdc cli changefeed create --server=http://10.*.*.*:8300 --sink-uri="kafka://10.*.*.*:9092/ticdc_cyf?protocol=debezium&kafka-version=3.9.0&partition-num=1&max-message-bytes=67108864&replication-factor=1" --changefeed-id="simple-replication-task" --config=/data/tidb/changefeed.conf

修改一下更新时间或者创建时间,这两个字段设置了不同的字段类型

你的 tidb timezone 和 cdc timezone 是怎么配置的啊?我这边测试发现 created_time 和官方 debezium 实现会不一致,官方实现输出为 “created_time”: string(“2025-07-13T07:54:31Z”)“,ticdc 的实现输出为 “created_time”: string(“2025-07-13T15:54:31Z”)“ 和你的对不上,updated_time为“1752421130000”,这个和官方实现是一致的。https://github.com/pingcap/tiflow/pull/12242

1 个赞

tidb集群的时区设置:SET GLOBAL time_zone = ‘Asia/Shanghai’;
cdc时区:tiup cluster edit-config 集群名,在server_configs模块设置做如下配置,然后执行 tiup cluster reload 集群名 -R cdc
image

我在本地测试得到的结果为"created_time":"2025-07-13T15:54:31Z","updated_time":1752421130000,和你的对不上

你的updated_time也不对呀,毫秒级的时间戳,转换后多了8小时呀。不过created_time是对的,和我的不一样
image

这个输出和 debezium connect 的输出是一致的,你可以看下那个集成测试,我们通过对比输出是否一致来验证 ticdc 的编码是否正确 https://github.com/pingcap/tiflow/blob/71a2afb257a1c17f55e5f3f278c7fb52b7d1426e/tests/integration_tests/debezium/README.md

Debezium 官方的datetime转换示例,他们转换后也是多了8小时。这个先放放,timestamp类型转换就很奇怪,我的时区也配置了呀,但好像没生效的样子,cdc和tikv节点都是重启过的。有什么思路吗?
https://debezium.io/documentation//reference/1.9/connectors/mysql.html#mysql-temporal-types

1 个赞

这里确实有点问题,我在本地测试没问题,但是集成测试出现了你说的情况