hive内部分区表(ORC格式)新增字段后出现的问题

hive内部分区表(ORC格式)在新增字段后出现的问题:

1、在新增字段后的新分区内查询数据 正常,在新增字段后的旧分区内查询数据 异常

2、分区删不掉,一直卡着不动

3、在执行插入分区的动作后,数据文件中已经有新字段值了,但是在查询的时候新字段的值还是显示为null

4、利用sparkSQL查询历史分区部分字段,出现无法查询现象

      异常:java.lang.ClassCastException: org.apache.hadoop.io.Text cannot be cast to org.apache.hadoop.io.LongWritable

1-3 问题原因:

当我们修改hive表结构以后,mysql中元数据库中的SDS中该hive表对应的CD_ID会改变,但是该hive表旧的分区下面对应的CD_ID还是原来表的CD_ID.

如果使用动态分区插入的数据,每个分区的CD_ID都不相同

1-3 解决方案:

测试表:int_optimize_bidrequest,分区字段:date、hour  (假设在2017-06-12进行的新增表字段操作)

查看表的CD_ID:select CD_ID from SDS where LOCATION='hdfs://tercel/user/hive/warehouse/dsp.db/int_optimize_bidrequest',(假设新的CD_ID值为105749)
该hive表的新增字段后的 新分区的CD_ID:SELECT CD_ID FROM SDS WHERE LOCATION LIKE '%hdfs://tercel/user/hive/warehouse/dsp.db/int_optimize_bidrequest/date=2017-06-14/hour=01%'(CD_ID值为105749,等于主表的CD_ID)
该hive表的新增字段后的 旧分区的CD_ID:SELECT CD_ID FROM SDS WHERE LOCATION LIKE '%hdfs://tercel/user/hive/warehouse/dsp.db/int_optimize_bidrequest/date=2017-06-10/hour=01%''(CD_ID值为71806)
我们需要更新一下现有分区的CD_ID的值为表CD_ID的值:
UPDATE SDS SET CD_ID=105749 WHERE LOCATION LIKE '%hdfs://tercel/user/hive/warehouse/dsp.db/int_optimize_bidrequest/date%'

然后我们再去查询一下表int_optimize_bidrequest,字段的值就可以正常的显示出来了。

注意问题:

如果出现hive表不能修改,可直接更改hive元表

1、 SELECT * FROM COLUMNS_V2 WHERE CD_ID=105749  ORDER BY INTEGER_IDX

2、INSERT INTO COLUMNS_V2 (CD_ID,COLUMN_NAME,TYPE_NAME,INTEGER_IDX) VALUES(105749,'adx','string',0)

3、禁止设置矢量查询

#矢量查询(Vectorized query) 每次处理数据时会将1024行数据组成一个batch进行处理,而不是一行一行进行处理,这样能够显著提高执行速度。

 

set hive.vectorized.execution.enabled = false;

4、如果在hive中执行 desc dsp.int_optimize_bidrequest依旧卡着不动,很有可能是表处于被锁的状态

执行 show locks dsp.int_optimize_bidrequest 查看表的状态,如果为 Exclusive(排他锁),继续执行 unlock tabledsp.int_optimize_bidrequest命令解锁

3 问题原因:

       由于HIVE有数据类型自动转换的功能,在建表的时候都创建为了String类型,但修改或增加字段后会出现字段类型匹配不上的现象。因为在ORC存储数据时为了节约存储空间,都会有明确的数据类型。在用HIVE查询会自动兼容,但是用第三方工具查询时(如SparkSQL)会出现类型转换失败的问题。

3 解决方案

 

修改问题表字段类型

Alter table stg.xh_temp_netinfo_d  change column st  st  BIGINT

你可能感兴趣的:(hive)