【数仓日常踩坑】如何获取binlog数据里每个id的最新数据

背景:数仓接入binlog类型的业务数据,由于业务数据同一个id可能会有不同的操作,如:insert update delete,所以数仓接入过来的binlog数据,同一个id会存在多条数据的情况,为了保证跟业务数据库的数据状态相同,我们需要拿到id的最新数据

  • 旧版的binlog数据处理方式:

    • 每条binlog里会有一个字段position用来记录这条数据在文件里的位置,同一个id,通过对position降序排序,取到rank=1的数据即为最新的数据(一般情况下最新的数据,其position值最大)
  • 遇到的问题

    • 数仓接入的一个订单相关数据,有用户反馈数仓相关表存在订单状态异常的问题,业务数据库里某条订单状态为【已完成】,但数仓里这个订单的状态是【已下单】
  • 排查问题

    • 顺着当前表往上游查询每张表里的订单状态,都显示【已下单】
    • 怀疑binlog丢失或者计算逻辑有误
      • 在ods层查看是否存在日志丢失问题,发现binlog日志没有丢失、
      • 检查计算逻辑,用现有逻辑去查询当前order_id,对于同一条order_id、存在多条数据,最新的数据不是position最大的那条数据;假设order_status分别为1、2、3,最新的状态应该为3,但是用现有逻辑查询出来的结果为order_status=2时的那条数据最大。所以在这一步我们拿到的数据不是最新的,导致跟业务数据不一致
    • 跟中间件的同学进行了沟通,得到反馈是因为集群做迁移导致的文件顺序错位,所以会存在最新数据的position不是最大的情况,并且我们不应该拿position做排序取最新数据,这个不准确
  • 解决方案

    • 给出的解决方案是binlog数据传过来时每条数据中携带一个全局唯一事务id【gtid】,刚开始我以为是通过redis的Incr操作实现的原子计数器,后来请教了一下中间件同学,【gtid】答复是mysql自带的功能,会对每个事务附上一个唯一id,这个id会随着事务的操作递增,能保证最新的数据其【gtid】最大
    • 数仓同学在接入binlog数据时,可以拿每个【gitd】做排序,取rank=1的数据
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值