问题
hive表在原有的schema上新增一列后,重新计算历史分区的数据进行覆盖更新后,会发现以下现象:
- 用hive的select操作从老分区取出来的新增列值都是null,从新分区select取出来的值都是正常的
- 用presto(trino) select筛选出来的数据不管新老分区的数值都是正确的
分析
在alter table时默认选项为RESTRICT,RESTRICT只会更改元数据。
由于不会修改在此操作之前创建的partition的表结构,只会修改在此之后创建的新的partition。
所以查询时旧的partition中的值全为NULL,而新分区的值全部可以正常限制。
解决
方案1.对历史分区的数据添加新增列
alter table [数据库].[数据表] partition(dt='xxxx-xx-xx') add columns(c1 [字段类型],c2 [字段类型],c3 [字段类型]...)"
按照分区逐个操作较为繁琐,但是亲测有效。
方案2.对历史分区的数据添加新增列
将分区逐个删除,然后进行数据的重新刷新,流程比较繁琐,简单粗暴。不太推荐此方案。
方案3.对历史分区的数据添加新增列
ALTER TABLE table_name
[PARTITION partition_spec]
ADD|REPLACE COLUMNS (col_name data_type [COMMENT col_comment], ...)
[CASCADE|RESTRICT]
该方案相对比较简单易操作,但是相应也有一些缺点:
该操作对于分区数多的表比较危险,可能导致元数据库MySQL故障