关于DM数据保证同步原事务一致性

参考:

dm数据同步过程中只能保证数据的最终一致性,而不能保证数据的事务,目前我们两个需求有问题,没有没什么好的解决方案?

需求1:  
    基于tidb做数据分析:  
    mysql数据同步到tidb,tidb通过binlog将数据发送到kafka,然后使用structuredstreaming进行流式处理。在流式处理的时候,需要进行表关联,关联主表和明细表进行数据分析。在此过程中,若不能保证事务中sql的执行顺序和数据可见性,可能导致主表之关联部分明细表,导致数据出错(以主表数据变更判断是否执行分析)。  
需求2:  
    基于tidb做数据同步:  
    线下产品将数据提交到云库,然后将云库同步到tidb,线下产品再将查询tidb到本地数据库。不能保证数据的事务性,关联查询数据时,可能会导致数据同步有误。  

基于这两个需求,是否有什么方案解决?

这两个问题都不太简单,TiDB 相关的数据同步服务为了同步性能,设计上都是做了拆分 transaction 的。背后的逻辑是 binlog 的设计概念就是一个顺序的 binlog 流,如果需要支持并发,需要针对指定的业务需求做并发任务分发;比如是否单表的更新满足事务粒度?还是多表之间也需要满足?这个数据一致性需求的粒度决定了不同的并发分发算法。

我们也希望支持你描述的场景,建议可以去 dm 建立一个 RFC ,有更多的细节我们工程师需要咨询你

1 个赞

就业务需求来说,单实例中的单表更新、多表更新需要满足事务的需求比较多,多实例之间基于XA的分布式事务也有,终极的基于应用的分布式事务就更加困难了。不过通常来说,分布式事务可以通过业务来控制,做适当的取舍;单实例的情况下的事务通过业务设计去满足就比较困难了
PS:谢谢 ,我会尽快建立RFC

目前我们有一个方案解决这些问题:
首先定义一张信息记录表:schema、table_name、data_id、tx_id、tx_state。
在应用中执行事务前插入一条记录,事务执行完毕后新开一个事务修改该记录tx_state字段。
该方法利用ti单办同步时的冲突检测与顺序性,但是对于tidb的冲突检测与顺序性有些疑问,不确定是否能保证新开的事务能否一定在前一个事务所有语句执行前执行完毕。

参见:DM同步的事务冲突检测与事务执行的顺序性

  • tx_id 和 data_id 分别是什么值? 这两个值是怎么分配的?
  • 每个 transaction 都有这两条记录吗? 还是只有需要被检测冲突的事务有这两条记录。
  • 假设针对事务 tx_a 和 tx_b 以及相关的 pre 和 commit 两条记录, 存在时序 pre_tx_a -> tx_a -> pre_tx_b -> tx_b -> commit_tx_b ->(commit_tx_a 还没有写成功) … 怎么检测冲突和顺序,具体的算法不太明白
1 个赞

这主要是针对我们业务的:
1.data_id是主数据中的唯一识别(或者事务中每条update、delete的数据的ID),来源于数据。tx_id是每个事务的唯一识别,每个事务生成一个。
2.检测记录表中数据,查看事务的状态tx_state,根据数据id,获取事务成功的数据。
之前以为冲突检测是事务级的,能保证事务的顺序。刚才了解到是表级的,细化到根据主键检测。 如果是事务级的,那么能保证修改只要事务状态为完成的,那么业务事务一定是成功的。目前不能保证事务的顺序,这个方案不成立

从业务角度跟从技术角度考虑还是不同的。
从业务角度考虑我们需要检测的是每个事务里影响业务的都是不能拆分的。我们只需要考虑到事务级别。从技术角度考虑我们需要尽可能地提高并发,尽可能的拆分事务。

假设每个update、delete记录一条数据时。
时序冲突的检测只要检测data_id(主键)有没有tx_state是未完成的。如果有,就说明有冲突。 检测到冲突怎么处理就在确定了。事务的顺序就是mysql中commit的顺序。
就tidb来说,他的事务中的job是分散的,怎么确定事务完成,去修改具有相同的tx_id的tx_state状态我不知道。。

我们在看,有结论及时回复。

可以参考下这个帖子 DM同步的事务冲突检测与事务执行的顺序性

这个帖子是我发起的,问题大致有解决方案了,可以通过单worker、单线程的方式保证事务顺序。
进而再通过上述方式控制事务一致性。

主要是想抛砖引玉,看看你们能不能通过这个解决方案提供解决同步时保证单实例同步事务一致性思路
毕竟通过单worker、单线程效率比较低
谢谢各位了:+1::+1::+1:

:+1:

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