hive分区表添加字段出现新增字段null的bug
对于hive分区表,我们使用alter语句新增字段后(如alter table table_name add columns(age int)),再重写之前已经存在的分区,会出现使用查询语句查出来的新增字段显示null值。
例如:表a ,分区dt,已有分区dt=’a’,由于需求新增了一个字段,然后重新写a
分区数据,写完后使用select发现新增字段为null值(但是实际的hdfs文件中是存在新增列的数据)。
起初我以为是我脚本sql的问题,在花费了半天时间排除各种错误原因后发现竟然是hive本身的问题。hive JIRA:https://issues.apache.org/jira/browse/HIVE-6131
方法1:
修改hive元数据SDS表的CD_ID字段,原因是修改表结构后,元数据库中的SDS中该表对应的CD_ID会改变,但是该表分区下面对应的CD_ID还是原来表的CD_ID。本人没有尝试,直接修改元数据风险较大
方法2:
因为本身写入hdfs的文件是没问题的,若是表是外部表,可以先执行删除分区命令
alter table table_name drop partition(dt='a')
然后,再执行修复分区命令,msck repair table table_name,或者alter table table_name add partition(dt=’a’)。
若是非外部表,可以执行删除分区命令后,再重写分区。
方法3
结果显示null,实际上是由于分区元数据缺少新添加的字段导致的,可以通过如下语句往出错的分区元数据中添加这个列。
alter table partition_test partition(dt='a') add columns(age int);
测试过程
create EXTERNAL table tmp.partition_test(
id int
)
partitioned by(dt string)
insert overwrite table partition_test partition(dt='a') values(1);
select * from partition_test;
#1 a
alter table partition_test add columns(name string);
select * from partition_test;
#1 NULL a
insert overwrite table partition_test partition(dt='a') values(1,'1');
select * from partition_test;
#1 NULL a
alter table partition_test drop partition(dt='a');
msck repair table partition_test;
select * from partition_test;
#1 1 a
alter table partition_test add columns(age int);
insert overwrite table partition_test partition(dt='a') values(1,'1',1);
select * from partition_test;
#1 1 NULL a
alter table partition_test partition(dt='a') add columns(age int);
select * from partition_test;
#1 1 1 a
注:也就是说hive在select数据时,不仅与表元数据相关,而且会根据分区元数据去hdfs文件中取字段值,表元数据与分区元数据不同步造成select的结果并不是我们需要的。
注:实际上在添加字段是可以通过CASCADE关键字来,避免出现这种问题。如alter table table_name add columns(age int) CASCADE