• 【数仓日常踩坑】如何获取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的数据
  • 相关阅读:
    链表题目 : 链表的中间结点 与 链表中倒数第k个结点(leetcode 和 牛客)
    解决GOSUMDB sum.golang.org 连接超时
    03-Redis 凭什么这么快
    PIR 传感器入侵检测算法和分析研究(Matlab代码实现)
    js图片上传(隐藏input file)
    信息收集小技巧
    如何搭建一个 websocket
    摄像机标定和 3D 重构
    C++模板 - index_sequence
    什么是GPT-4
  • 原文地址:https://blog.csdn.net/qq_45287265/article/details/126155534