lzs109
(Lzs109)
1
【 TiDB 使用环境】生产环境
【 TiDB 版本】6.5.0
【问题描述】
如何通过ticdc到kafka之后,保持1个事务内操作语句顺序不变?
在业务系统中,1个事务中有3个数据库操作,执行顺序如下
第1个操作,操作1:插入A表的备份表(t_a_back)中插入1条数据
第2个操作,操作2:删除A表(t_a)的这条原始数据
第3个操作,操作3:插入B表1条备份备份记录数据,绑定t_a_back表的主键
通过ticdc到kafka之后,顺序可能变成了
第1个操作,操作3:插入B表1条备份备份记录数据,绑定t_a_back表的主键
第2个操作,操作1:插入A表的备份表(t_a_back)中插入1条数据
第3个操作,操作2:删除A表(t_a)的这条原始数据
如何通过ticdc到kafka之后,保持1个事务内操作语句顺序不变?
【通过ticdc到kafka之后,需要1个事务内操作语句顺序不变的原因】
系统架构
服务中心:采用tidb数据库,是业务数据的发起端,具备全量的数据。
服务子节点:采用mysql数据库,是业务数据的接收端,仅具备与自身节点相关的数据。
数据同步架构
服务中心产生变化的数据,通过ticdc捕获后,传输到kafka中,服务子节点订阅服务中心kafka的消息队列,将数据的变化在本地mysql数据库中进行恢复。
数据恢复的约束
服务子节点仅处理与本节点有关的数据,需要从数据的逻辑关系进行判断那些数据是本身的。
在
问题描述的场景中,具体操作如下:
第1个操作,操作1:插入A表的备份表(t_a_back)中插入1条数据。
内部验证逻辑:接收到插入操作后,根据mysql库中t_a表的主键(a_1)验证本地数据是否存在,若存在,则执行操作1插入.
第2个操作,操作2:删除A表(t_a)的这条原始数据
内部验证逻辑:接收到删除操作后,根据mysql库中t_a表的主键(a_1)验证本地数据是否存在,若存在,则执行操作2删除.
第3个操作,操作3:插入B表1条备份备份记录数据,
绑定t_a_back表的主键
内部验证逻辑:接收到删除操作后,根据mysql库中备份表(t_a_back)的主键(a_1)验证本地数据是否存在,若存在,则执行操作3.
综上所述,如果一个事务内的操作乱序后,数据逻辑判断将会出现混乱,不能有效的进行数据恢复,无法保障数据的准确。
可以通过dispatchers 来把某张表分发到指定topic和指定分区,这样数据就是线性顺序的了。
小龙虾爱大龙虾
(Minghao Ren)
3
lzs109
(Lzs109)
4
现在是单topic和单分区,消息队列应该没问题,有问题的应该是1个事务内的数据库操作顺序传到kafka时就更换了。比如说在一个事务内提交时的顺序是1、2、3,在tidb处理完成后,经ticdc到kafka变成了3、2、1。感谢
lzs109
(Lzs109)
5
一个事务内的Resolved TS、commit ts是相同的,所以无法按照这个来进行排序,感谢~~
templey
(templey)
6
你是不是想问tidb里面一个事务里面sql执行顺序的问题
小龙虾爱大龙虾
(Minghao Ren)
8
既然已经通过 commit_ts 确认这 3 个操作是一个事务了,且上游永远先试按 t_a_back、t_a、b 这三张表顺序来操作,那下游直接根据 mysql库中t_a表的主键(a_1)验证本地数据是否存在,然后按 t_a_back、t_a、b 表顺序去消费不就行了
或者你下游 Mysql 按什么规则去分片的,直接按分片规则,每个消费对应的分片就行了啊
lzs109
(Lzs109)
10
是一个事务里sql执行后,经ticdc到kafka顺序不变的问题
lzs109
(Lzs109)
11
需要根据数据逻辑验证下游是否存在相关数据,然后进行相应的操作。“下游直接根据 mysql库中t_a表的主键(a_1)验证本地数据是否存在,然后按 t_a_back、t_a、b 表顺序去消费”,这种模式不具备普适性
小龙虾爱大龙虾
(Minghao Ren)
12
你这个场景是上游是总的数据,下游是分库分表的数据。
需要根据数据逻辑验证下游是否存在相关数据,然后进行相应的操作。
这个操作本身本质是判断是否是该分片的数据,你把你分片的逻辑也写到消费逻辑里就好了啊
system
(system)
关闭
15
此话题已在最后回复的 7 天后被自动关闭。不再允许新回复。