在使用Hive的過程中,復制表結構和數據是很常用的操作,本文介紹兩種復制表結構和數據的方法。
1、復制非分區表表結構和數據
Hive集群中原本有一張bigdata17_old表,通過下面的SQL語句可以將bigdata17_old的表結構和數據復制到bigdata17_new表:
CREATE TABLE bigdata17_new AS SELECT * FROM bigdata17_old;
如果是分區表,則必須使用like關鍵字復制表結構,包括分區,然后用insert語句將老表的數據插入新表中。
2、復制分區表表結構和數據
復制表SQL:
CREATE TABLE bigdata17_new like bigdata17_old;
復制數據sql:
insert overwrite table bigdata17_new partition(dt) select * from bigdata17_old;
如果遇到bigdata17_old表數據量巨大,有T以上的級別時,上述方法的效率則比較低。下面介紹一種快速復制表結構和表數據的方法。
從舊表中復制表結構,這個和上面介紹方法是一樣的:
CREATE TABLE bigdata17_new like bigdata17_old;
然后使用hadoop fs - cp命令將bigdata17_old舊表的數據拷貝到bigdata17_new新表:
hadoop fs -cp /user/warehouse/bigdata17.db/bigdata17_old/* /user/warehouse/bigdata17.db/bigdata17_new/
然后執行 MSCK REPAIR TABLE new_table;
命令讓兩張表的分區元數據保持一致。
詳細使用過程如下:
bigdata17_old表有兩個字段,id和dt,其中dt是分區字段,一共有4條記錄,兩個分區:
hive> desc bigdata17_old;
OK
id int
dt string
# Partition Information
# col_name data_type comment
dt string
Time taken: 0.147 seconds, Fetched: 7 row(s)
hive> select * from bigdata17_old;
OK
15 2018-10-13
18 2018-10-13
12 2018-10-14
13 2018-10-14
Time taken: 0.118 seconds, Fetched: 4 row(s)
hive> show partitions bigdata17_old;
OK
dt=2018-10-13
dt=2018-10-14
Time taken: 0.113 seconds, Fetched: 2 row(s)
創建表結構和bigdata17_old表一模一樣的表bigdata17_new:
create table bigdata17_new like bigdata17_old;
查看表bigdata17_new的表結構:
hive> show partitions bigdata17_new;
OK
Time taken: 0.153 seconds
hive> desc bigdata17_new;
OK
id int
dt string
# Partition Information
# col_name data_type comment
dt string
Time taken: 0.151 seconds, Fetched: 7 row(s)
由於表bigdata17_new還沒有數據,因此該表中沒有分區信息。
將bigdata17_old目錄下的數據文件拷貝到bigata17_new目錄下:
[root@hadoop-master hive_test]# hadoop fs -cp /user/hive/warehouse/bigdata17.db/bigdata17_old/* /user/hive/warehouse/bigdata17.db/bigdata17_new/;
18/10/13 19:02:54 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
[root@hadoop-master hive_test]# hadoop fs -ls /user/hive/warehouse/bigdata17.db/bigdata17_new/
18/10/13 19:03:26 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Found 2 items
drwxr-xr-x - root supergroup 0 2018-10-13 19:02 /user/hive/warehouse/bigdata17.db/bigdata17_new/dt=2018-10-13
drwxr-xr-x - root supergroup 0 2018-10-13 19:02 /user/hive/warehouse/bigdata17.db/bigdata17_new/dt=2018-10-14
查看表bigdata17_new的分區信息:
hive> show partitions bigdata17_new;
OK
Time taken: 0.125 seconds
雖然數據拷貝過來了,但是表bigdata17_new的分區信息還沒更新到metastore中,因此需要使用MSCK命令修復bigdata17_new的分區信息,執行該命令后就會把bigdata17_new的分區信息更新到hive metastore中:
hive> MSCK REPAIR TABLE bigdata17_new;
OK
Partitions not in metastore: bigdata17_new:dt=2018-10-13 bigdata17_new:dt=2018-10-14
Repair: Added partition to metastore bigdata17_new:dt=2018-10-13
Repair: Added partition to metastore bigdata17_new:dt=2018-10-14
Time taken: 0.21 seconds, Fetched: 3 row(s)
查看表bigdata17_new的表結構和查詢表數據:
hive> show partitions bigdata17_new;
OK
dt=2018-10-13
dt=2018-10-14
Time taken: 0.137 seconds, Fetched: 2 row(s)
hive> select * from bigdata17_new;
OK
15 2018-10-13
18 2018-10-13
12 2018-10-14
13 2018-10-14
Time taken: 0.099 seconds, Fetched: 4 row(s)
表bigdata17_new已經創建完畢,它的表結構、分區信息和表bigdata17_old一樣,數據也一模一樣。
如果是跨Hive集群復制表和數據,又要怎么做呢?
其實和上述步驟差不多,只是因為跨Hive集群,新表和舊表之間不能使用hadoop cp命令拷貝數據。假設有兩個集群,分區為Hive1和Hive2,兩個Hive集群都有表bigdata17_order,表結構完全一樣。怎么將集群Hive1中的bigdata17_order表的數據拷貝到集群Hive2中的bigdata17_order表中呢?下面介紹實現步驟:
1、將表Hive1集群bigdata17_order目錄下的數據下載到本地:
hadoop fs -get /user/warehouse/bigdata17.db/bigdata17_order/* /home/hadoop/hivetest/bigdata17_order/
2、通過hadoop fs -put命令將本地數據上傳到集群Hive2中的bigdata17_order目錄中:
hadoop fs -put /home/hadoop/hivetest/bigdata17_order/* /user/warehouse/bigdata17.db/bigdata17_order/
3、在集群Hive2中執行MSCK命令修復表bigdata17_order的分區信息:
MSCK REPAIR TABLE bigdata17_order;
Hive MSCK命令的用法請參考:一起學Hive——使用MSCK命令修復Hive分區
總結
1、介紹復制Hive非分區表和數據的方法
2、介紹復制Hive分區表和數據的兩種方法
3、介紹跨Hive集群拷貝分區表數據的方法。