TiCDC事件的表级排序的问题

【 TiDB 使用环境`】生产
【 TiDB 版本】5.1.0
【遇到的问题】
TiCDC不保证事件表级事件排序,只保证行级(相同主键的?)事件排序。诚然,现在分布式数据库的CDC好像都只做到这样。但是,如果下游有聚合操作的话,行级排序是不够的。如上游表是

create table table_source (
id bigint primary key,
a varchar(20)
)

在下游要聚合成

create table table_destination (
final_id bigint,
a varchar(20) primary key
)

如果没有表级排序,那么聚合结果的正确性是无法保证的。
所以想请问一下是否有修改TiCDC以支持表级排序,或者在TiCDC下游进行排序的可能性。
如果TiCDC连接Flink,那么聚合等操作应该是很常见的。

这么貌似和排序没啥关系吧?

有的,比如事件流
(1,‘a’)
(2,‘b’)
(3,‘b’)
(4,‘b’)
如果没有表级排序,最终聚合结果可能是
(1,‘a’)
(2,‘b’)
或者
(1,‘a’)
(3,‘b’)
或者
(1,‘a’)
(4,‘b’)
中的任一个。
然而实际上期望的是第一个。

以 canal-json[1] 为例,TiCDC 在输出数据变更的同时还会输出 watermark[2] 事件用来通知数据的完整性。

在消费端需要 100% 顺序消费的时候,可以用 watermark 来实现数据排序和去重。

比如

(2,‘b’, ts2)
(1,‘a’, ts1)
(watermark ts2)
(2,‘b’, ts2)
(3,‘b’, ts3)
(watermark ts3)
(watermark ts3)
(4,‘b’, ts4)

ts2 代表 ts = 2。

消费端需要实现一个缓存出现在 watermark 之前的事件。在收到 watermark 之后,消费端通过 watermark ts2 来排序缓存的事件。

比如 watermark ts2 可以排序 (1,‘a’, ts1) 和 (2,‘b’, ts2);watermark ts3 可以去重 (2,‘b’, ts2)。

注意 watermark 本身可能会重复,消费端还需要记录看见的最大的 watermark ts。

[1]: TiCDC Canal-JSON Protocol | PingCAP Docs
[2]: Streaming 102: The world beyond batch – O’Reilly (oreilly.com)

谢谢回答。其实上面是一个简化模型,实际上我们需要处理update事件并且需要对另一列进行过滤。从实际上看,我们在下游看到的结果看上去是乱的。我们还是需要表级事件排序的,无论是不是在同一个事务。

谢谢,我研究一下。

另外请问ts有绝对的区分度吗?是否会有这样一种情况,如

(2,‘b’, ts2)
(3,‘b’, ts2)
(1,‘a’, ts1)
(watermark ts2)

这样的话我们无法决定最终结果是
(2,‘b’)
还是
(3,‘b’)

这里的 ts 是 TiDB 事务中的 COMMIT TS,如果两个事件 ts 一样,就说明它们是在一个事务中提交的。
事务内的行修改顺序 TiCDC 还做不到区分。

您的结论好像和上面dba_gc的结论不一样:joy:
所以同一事务内DML顺序是不能保证的吗?

TiCDC事务

  • 同一个事务不同表的DML顺序不一致
  • 同一个事务同表的DML顺序一致

我补充下细节。
TiCDC 是按表来复制的,所以如果一个事务涉及多个表,那么表间的更改是没法保证同步顺序的(比如这两个表可能在不同 TiCDC 节点上同步)。

同表同事务的 DML 之间其实是没有“顺序”的,因为在数据库看来这些 DML 的更改是同时发生的。

谢谢补充,不过您的回答稍微有点抽象。我的理解是:您否定了“ 同一个事务同表的DML顺序一致”这个说法,最终结论是同一事务内同表的事务无法排序。我想是这样子的。

看待这个问题有两个不同的视角,依以下事务为例

begin;
update table set xxx where id =  a;
update table set yyy where id =  b;
commit;
  1. 用户视角:这个事务的 DML 的执行是有顺序的,先执行了 a 再执行了 b。
  2. 数据库视角:同表 同事务 的 DML 之间其实是没有“顺序”的,因为这些 DML 的更改是 同时 发生的。

TiCDC 同步 DML 只能还原据库视角看到的顺序,即能还原事务和事务之间的顺序,但不能还原单个事务内 DML 的顺序。

1 个赞

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