ticdc逻辑组件mounter

众所周知tidb是将SQL转换为KV键值对存储的,那么对于ticdc而言,它需要将原始的KV键值对(byte数组)反向解码成SQL Event(有sql含义的对象,如DML/DDL)
其中实现DML解码的组件叫mounter(虽然mounter中实现了DDL解码,但不是在mounter协程执行的,实际是由ddl puller执行)。mounter启动时会同时启动若干个(defaultMounterWorkerNum = 32)解码协程,对接收到的KV键值对 并行解码,再通过pipeline传给sink组件。
本文主要介绍mounter解码协程工作的几个核心点。

解码key值

tidb当前版本(4.x~5.x),从TiKV变更数据流接收到的DML的key值设计如下


var (
    tablePrefix  = []byte{'t'}
    recordPrefix = []byte("_r")
    ...
)

在这里只需要从key值里面获取tableIdrecordId
可以通过tableId查询到完整的表结构信息
recordId稍后再说

解码value值

tidb当前版本(4.x~5.x),从TiKV变更数据流接收到的value值设计如下

<非空字段数(2bytes)><空字段数(2bytes)>
...
...

从以上结构中可以很方便地取出各个column的值,并且根据columnId将这些值与表的每个字段一一关联起来,还原出一行数据

关于types.Datum

上一节中解码的字段值会被封装进types.Datum这个对象。特别值得一提的是,这里的Datum取代了go语言的interface{},设计成专门用于数据传输的场景,具有更高的性能和易用性,由此可见tidb设计的精巧。但是很不幸,当前版本的ticdc数据传输pipeline中并未完全采用Datum,仍然是将其转化为interface{}发送到sink组件使用。

特殊情况

有一类表,它只有1个int类型的主键,这种表在写入KV存储时,key做了优化,直接把主键用作recordId(上文所提)
这种表在收到delete事件、并且enableOldValue参数未设置时,value会是空的
所以这种场景下会使用recordId作为主键值输出
tidb5.x版本不存在此情况

你可能感兴趣的:(ticdc逻辑组件mounter)