监控GreenPlum表存在的问题
只监控时间戳有什么问题:相同时间戳的记录太多,按时间戳升序排序加 limit 会丢失时间戳等于最后一个时间戳的部分记录。
只监控id有什么问题:若只使用唯一id监控数据,数据发生变更id是监控不到的,这是万万不可以的。
在查询时发现一个问题,一般增量代码通过监控时间戳和设置批大小实现数据的分批写入,但GreenPlum的某个表相同时间戳的数据太多(触发器导致),设置批大小往往会将与最后一个时间戳相等的数据截断,导致丢失一部分数据。这在数据做增量更新的时候是不可接受的,既然只监控时间戳会存在问题,那是否需要加个全表唯一的id字段辅助截断。
解决思路:
1、先根据时间戳升序排序和 limit batchSize 截取一部分数据query1;
2、将最大的时间戳保留到变量right_lmt中,将已经查询到的id记录到列表id_has_run中;
3、根据时间戳等于right_lmt并且id not in tuple(id_has_run)来找出剩余部分的记录rest_query;
4、将rest_query 扩充到query1中,因此,实际的批大小比变量batchSize大。
5、增加GreenPlum表id索引。
疑问:既然第一步已经按照时间戳升序排序,为啥第2步不直接用 时间戳等于 right_lmt 并且 id 大于最后一个id来筛选记录呢?
答:这是因为GreenPlum采用的是分布式存储,根据时间戳升序排序并不能保证id是升序排序的,实际上id是乱序的,特别是当已有数据做了更改。
------------------------------------------------------------------分割线[2023-02-01]---------------------------------------------------------------------------
若增量规模比较大,可以分批处理,思路如下:
1、获取上一次的时间戳 last_lmt;
2、设置一个批量大小,比如batch_size=1000;
3、根据监控字段对增量数据进行排序并找出当前批量的最大时间戳batch_lmt;
4、找出last_lmt到batch_lmt之间的所有数据,很可能记录数多于batch_size,因此batch_size只是用于找出当前批次最大的时间戳,并无其他用途。
SELECT
MAX(last_modified_time) AS batch_lmt
FROM
(
SELECT
last_modified_time
FROM schema_name.table_name
WHERE last_modified_time > ${LAST_LMT}
ORDER BY last_modified_time
LIMIT ${BATCH_SIZE}
) AS t_time
注意:Greenplum是分布式存储的,所以要先根据时间戳排序,然后才能取到你想要的值