首先是来自 Jira 的 ticket。但是当我们做完之后发现其实很早就有一个 GitHub Issue 提了这个需求。
在该 ticket 中描述了用户使用上的问题:
并且还提出了对应需要改善的目标:
注意:如果一个表使用了 new collation,那么它对应的 index 编排方式会发生改变,导致无法通过变更后的 new value 所在 key 反向解析到原数据是怎么样的,导致 TiCDC 无法还原对应的 SQL,最终导致同步失败,所以如果开启了 new collation 那么就需要开启 old value 来拉去 TiKV 数据。
在需求的讨论过程中,我们发现在 TiCDC 内部中去判断某张表是否开启 new collation 然后再对应使用开启 old value 的模式去拉数据这个机制非常的复杂。所以讨论决定无论开不开启 new collation 我们都需要使用开启 old value 的模式去拉数据。
对于第二个目标没有调整,在用户没有开启 old value 配置时,我们需要保证输出不发生变化。
最终将需求确认好后,创建了对应的 GitHub Issue。
提交 PR 来支持内部总是使用开启 old value 模式来拉 TiKV 的数据。实现该功能过程中,遇到的最核心的问题就是:用户在没有开启 old value 配置时,我们需要保持输出数据的格式不发生变化
首先我们需要明确在开启 old value 和不开启 old value 模式时原来的 TiCDC 的行为:
开启 old value | 不开启 old value | |
---|---|---|
更新数据 | 输出旧的值和新的值 | 只输出新的值,但是如果修改的是 handle key 的列,那么我们需要将更新事件拆分成一个删除事件和一个插入事件 |
删除数据 | 输出被删除的行数据中的所有列 | 只输出被删除数据的 handle key 的列 |
具体的可以参考 TiCDC Open Protocol 的说明。注意:该说明中对不开启 old value 的更新事件的说明不够仔细。
首先明确我当时做测试主要测试的两个目标:
所以我在 PR 上做了如下测试:
测试用到的 sql 如下:
测试的用例:
不开启 new collation
开启 new collation
根据以上的用例,我进行了以下的测试:
我的基本测试步骤:
./cdc cli changefeed create --sink-uri="blackhole://" --changefeed-id="test"
4.0 的 PR:https://github.com/pingcap/ticdc/pull/2322
5.0 的 PR:https://github.com/pingcap/ticdc/pull/2323
5.1 的 PR:https://github.com/pingcap/ticdc/pull/2324
注意:TiCDC 从 5.0 以后默认开启 old value。