數據組有一個需求,建立一張hive用戶表,包含用戶的基本信息,後續可能會添加字段,做爲用戶的標籤,還有一些字段須要更新,也就是說這張用戶表須要天天:insert、update、delete、添加字段。java
在這方面並無經驗,通過查詢各類資料,新建了分桶表:算法
hive支持insert、update、delete操做須要hive-site.xml添加這些配置:apache
1<property>
2 <name>hive.support.concurrency</name>
3 <value>true</value>
4</property>
5<property>
6 <name>hive.exec.dynamic.partition.mode</name>
7 <value>nonstrict</value>
8</property>
9<property>
10 <name>hive.txn.manager</name>
11 <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
12</property>
13<property>
14 <name>hive.compactor.initiator.on</name>
15 <value>true</value>
16</property>
17<property>
18 <name>hive.compactor.worker.threads</name>
19 <value>1</value>
20</property>
21<property>
22 <name>hive.enforce.bucketing</name>
23 <value>true</value>
24</property>
說明:建表語句必須帶有into buckets子句和stored as orc TBLPROPERTIES ('transactional'='true')子句,而且不能帶有sorted by子句。微信
例如:app
1create external table if not exists hm2.history_helper
2(
3guid string,
4starttime string,
5endtime string,
6num int
7)
8clustered by(guid) into 50 buckets
9stored as orc TBLPROPERTIES ('transactional'='true');
這樣,這個表就能夠就行insert,update,delete操做了。oop
原本一切都很正常,天天定時任務很穩定,知道須要對錶添加字段,因而,我執行了以下語句:ui
1alter table hm2.history_helper add columns(country string, province string, city string);
這時候,表中數據仍是能夠查詢的,只是添加的三列由於歷史沒有數據,顯示爲NULLgoogle
執行一個update語句後,顯示更新成功,而後表就掛了。url
執行select * from table limit 1;都不能執行了,直接報錯:spa
1Error: java.io.IOException: java.lang.ArrayIndexOutOfBoundsException: 11
2 at org.apache.hadoop.hive.io.HiveIOExceptionHandlerChain.handleRecordReaderCreationException(HiveIOExceptionHandlerChain.java:97)
3 at org.apache.hadoop.hive.io.HiveIOExceptionHandlerUtil.handleRecordReaderCreationException(HiveIOExceptionHandlerUtil.java:57)
4 at org.apache.hadoop.hive.ql.io.HiveInputFormat.getRecordReader(HiveInputFormat.java:252)
5 at org.apache.hadoop.hive.ql.io.CombineHiveInputFormat.getRecordReader(CombineHiveInputFormat.java:701)
6 at org.apache.hadoop.mapred.MapTask$TrackedRecordReader.<init>(MapTask.java:169)
7 at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:429)
8 at org.apache.hadoop.mapred.MapTask.run(MapTask.java:343)
9 at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:163)
10 at java.security.AccessController.doPrivileged(Native Method)
11 at javax.security.auth.Subject.doAs(Subject.java:422)
12 at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1692)
13 at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158)
這也是無奈了,google一下,一哥們兒說能夠將添加的列刪除,恢復表:
1ALTER TABLE history_helper replace COLUMNS (
2guid string,
3starttime string,
4endtime string,
5num int
6);
其實,又會報錯這樣:
1Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Replace columns is not supported for table default.fac_scan. SerDe may be incompatible
而後他給的建議是:這個時候的操做只能是刪除原表,再根據新結構重建新表。這意思表不就廢了。
這哥們兒博客地址:
https://blog.csdn.net/youzhouliu/article/details/52998328
我從hdfs目錄看到今天的修改時間:
1drwxr-xr-x - hadoop supergroup 0 2018-09-27 12:57 /hive/warehouse/hm2.db/history_helper/.hive-staging_hive_2018-10-12_12-54-16_647_2029592254486085251-1
2drwxr-xr-x - hadoop supergroup 0 2018-9-28 13:15 /hive/warehouse/hm2.db/history_helper/.hive-staging_hive_2018-10-12_13-12-21_614_5380977921537493007-1
3drwxr-xr-x - hadoop supergroup 0 2018-09-30 13:35 /hive/warehouse/hm2.db/history_helper/.hive-staging_hive_2018-10-12_13-32-49_772_5132148987957791034-1
4drwxr-xr-x - hadoop supergroup 0 2018-07-1 12:44 /hive/warehouse/hm2.db/history_helper/delta_0000864_0000864
5drwxr-xr-x - hadoop supergroup 0 2018-07-02 12:57 /hive/warehouse/hm2.db/history_helper/delta_0000866_0000866
6...
7
8drwxr-xr-x - hadoop supergroup 0 2018-10-12 13:42 /hive/warehouse/hm2.db/history_helper/delta_0000873_0000873
將今天的文件刪除,沒想到就行了,能夠執行:
1select * from hm2.history_helper limit 10;
開心!
趕忙備份一份數據到新表!
後來嘗試了,建立hbase表,經過hive外部表關聯後執行添加字段、更新操做,可是失敗了。這是個坎兒呀!
本文分享自微信公衆號 - 數據分析挖掘與算法(ikeguang2)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。