天天看點

Hive分區表新增字段值為NULL背景原因方案

背景

對于HIVE分區表通過add column添加字段,向已存在分區中插入資料,結果新增字段的值全部為null。 已存在分區會産生該問題,新分區不會産生該問題。

原因

實際上資料是插入成功的。HDFS上的資料更新了,但是我們查詢的時候仍然查詢的是舊的中繼資料資訊(即Mysql中的資訊)

官方解釋如下:

Change Column Name/Type/Position/Comment

ALTER TABLE table_name [PARTITION partition_spec] CHANGE [COLUMN] col_old_name col_new_name column_type
           

[COMMENT col_comment] [FIRST|AFTER column_name] [CASCADE|RESTRICT];

This command will allow users to change a column’s name, data type, comment, or position, or an arbitrary combination of them. The PARTITION clause is available in Hive 0.14.0 and later; see Upgrading Pre-Hive 0.13.0 Decimal Columns for usage. A patch for Hive 0.13 is also available (see HIVE-7971).

The CASCADE|RESTRICT clause is available in Hive 1.1.0. ALTER TABLE CHANGE COLUMN with CASCADE command changes the columns of a table’s metadata, and cascades the same change to all the partition metadata. RESTRICT is the default, limiting column change only to table metadata.

ALTER TABLE CHANGE COLUMN CASCADE clause will override the table partition’s column metadata regardless of the table or partition’s protection mode. Use with discretion.

The column change command will only modify Hive’s metadata, and will not modify data. Users should make sure the actual data layout of the table/partition conforms with the metadata definition.

也就是說不僅僅是新增字段,修改字段也會出現類型問題。

方案

方案一

DDL語句最後添加CASCADE,會強制重新整理中繼資料資訊。

方案二

具體分區需要add column操作

例如,執行下面語句後,查分區資料新增字段值為null

alter table TABLENAME add columns(c1 string);  
           

需再執行

alter table TABLENAME partition(PAR='X') add columns(c1 string);
           

方案三

備份以前表,建立表,然後把備份資料導入回建立表。

方案四(未親自測試)

删除舊分區,然後重新添加新分區或修複表結構。

修複表結構語句如下:

msck repair table table_name;
           

方案五(未親自測試)

手動更新中繼資料,在中繼資料庫裡執行如下語句

--查找表對應的CD_ID
select CD_ID from SDS where LOCATION='hdfs://ods.db/tablename';   
           
--查找表總共有哪些分區
SELECT * FROM SDS WHERE LOCATION LIKE 'hdfs://bidc/ods.db/tablname/pt=%';   
           
--更新全部分區,如果要指定更新的分區,把%改為确切的分區值即可
UPDATE SDS SET CD_ID=(查詢1中的CD_ID的值)   WHERE LOCATION LIKE 'hdfs://bidc/ods.db/tablename/pt=%';  
           

繼續閱讀