TiCDC数据同步Kafka,表级的DDL不会经过库名+表名Hash算Partition,只会分发到Partition0分区

【 TiDB 使用环境】灰度测试环境
【 TiDB 版本】v5.4.0
【复现路径】 Kafka topic创建32个Partition,Partition分发器partition = “table” 来指定,执行多表的DDL, 如alter table add column 操作,DDL的CDC消息只会落到partition0分区,DML的CDC消息可以正常根据库名+表名Hash发送到对应的Partition。
【遇到的问题:问题现象及影响】Partition分发器partition = “table” ,对于同一张表进行DDL和DML操作,因为表结构会变化,如果DDL的CDC消息和DML的CDC打到不同的Partition.消费消息无法无序,当表结构发生变更,造成DML消息消费报错。
【资源配置】

【附件:截图/日志/监控】

描述的场景和问题,和之前文档中的描述是不一致的,估计也没啥好办法, :rofl:

建议采用 6.1.X 来做这个测试试试

参考如下:


不论约束,还是分区策略,按照你提供的信息来看…都没有达成广播的要求…

临时解决方案:
把消费失败的丢到一个单独的队列,不断拉出来重试
正常来讲DDL执行完毕后就能正常操作DML了
要考虑的细节:
根据DDL执行时间和业务场景需求考虑重试时间,避免无效重试
别出现死循环,重试多次还失败可能要报警手动确认问题处理

我们也有类似场景,建议直接用cdc提供的golang示例来改,它其实已经处理了DDL只分发到partition 0的情况,成熟度很高。
代码示例可以看下面:
https://github.com/pingcap/tiflow/blob/master/cmd/kafka-consumer/main.go

已经找到问题所在,和Sink指定MQ的协议有关系,如果用canal-json协议DDL只会打到Partition0,如果用open-protocol协议DDL会广播到每一个Partition。具体不清楚为什么这样设计,但是这种方式对下游保证顺序性消费很不友好。

这是open-protocol协议,DDL Event是可以广播到所有partition。但cannal-json协议就只会打到partition0,具体为什么消息协议不同就会不同还是不明白。

考虑过这种方案,可能会造成数据有问题。并非所有的DML都会报错进入重试队列

此话题已在最后回复的 60 天后被自动关闭。不再允许新回复。