美文网首页
ticdc逻辑组件mounter

ticdc逻辑组件mounter

作者: nchuxyz | 来源:发表于2021-10-13 23:38 被阅读0次

    众所周知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值设计如下

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

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

    解码value值

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

    <CodecVer(1byte)><large(1byte)><非空字段数(2bytes)><空字段数(2bytes)>
    <columnId 0><columnId 1>...<columnId n>
    <column 0在data段中的偏移量>...<column n在data段中的偏移量>
    <data段>
    

    从以上结构中可以很方便地取出各个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

          本文链接:https://www.haomeiwen.com/subject/gzspoltx.html