对Hive分区表进行新增字段后,会出现一个奇怪的情况,就是往 已经存在的 分区中装载数据后,某些字段的值显示为null,但实际情况是数据文件中对应的字段值其实是有值的。
下面我们重现该问题:
创建一个分区表
往表中装载数据
给表新增分区
再往表中装载数据并查询
数据装载成功后,通过查询可以看出,新创建的分区中数据显示正常,但是已经存在的time=20171010分区中新增数据后,新增的字段显示为null。难道数据没有插入成功?
查看分区表在HDFS上对应的数据
可以看出hive表在hdfs上对应的数据文件中相应的字段是有值的,那么为什么通过hive查询出来会是空呢?
那么造成上述问题的原因是什么?原因是修改Hive分区表结构以后,元数据库中的SDS中该表对应的CD_ID会改变,但是该表分区下面对应的CD_ID还是原来表的CD_ID。SDS表主要保存文件存储的基本信息,如INPUT_FORMAT、OUTPUT_FORMAT、是否压缩等。我们先进入mysql中,访问hive的metastore。比如我们这边测试表叫做student,分区字段为time,查看表的CD_ID:
查看student表所有分区的CD_ID:
可以发现time=20171010分区的CD_ID与time=20171011分区的CD_ID不同,而time=20171011分区的CD_ID的值与SDS表中的CD_ID值是相同的,因此,我们需要手动的更新一下现有分区的CD_ID的值与SDS中student表的CD_ID的值相同:
再去查询一下student表,发现字段已经显示值了。
当然,删除分区重建也是可以的,具体选择哪种方法根据实际情况决定,毕竟删除分区是会删除数据的,如果不允许删除原来的数据,建议还是修改元数据。