过往记忆的专栏文章转载:Hive删除外部表异常(Table metadata not deleted)

原始连接:https://www.iteblog.com/archives/2166.html

 

Hive删除外部表异常(Table metadata not deleted)

 Hive  2017-06-27 08:54:01 3508  1评论 下载为PDF 为什么无法评论和登录

 

文章目录

问题

我们应该知道,Hive中存在两种类型的表:管理表(Managed table,又称Internal tables)和外部表(External tables),详情请参见《Hive表与外部表》。在公司内,特别是部门之间合作,很可能会通过 HDFS 共享一些 Hive 表数据,这时候我们一般都是参见外部表。比如我们有一个共享目录:/user/iteblog_hadoop/order_info,然后我们需要创建一个外部表用于分析,如下:

Hive External tables Table metadata not deleted
如果想及时了解Spark、Hadoop或者Hbase相关的文章,欢迎关注微信公共帐号:iteblog_hadoop

CREATE EXTERNAL TABLE `order_info`(

  `user_id` string COMMENT '用户UID',

  `order_no` string COMMENT '订单号',

  `price` dobule COMMENT '订单金额',

)

LOCATION

  'hdfs://iteblogcluster/user/iteblog_hadoop/order_info'

但是由于某些原因我们可能需要删除这个外部表。遗憾的是,我们会遇到以下的异常:

hive> drop table order_info;

FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. MetaException(message:Table metadata not deleted since hdfs://iteblogcluster/user/iteblog_hadoop/order_info is not writable by iteblog)

原因

这是因为 Hive 在删除表的时候会检查当前用户是否对数据目录(本例子为/user/iteblog_hadoop/order_info)有写权限,代码如下:

if (tbl.getSd().getLocation() != null) {

  tblPath = new Path(tbl.getSd().getLocation());

  if (!wh.isWritable(tblPath.getParent())) {

    String target = indexName == null ? "Table" : "Index table";

    throw new MetaException(target + " metadata not deleted since " +

        tblPath.getParent() + " is not writable by " +

        hiveConf.getUser());

  }

}

一般外部共享给咱们的数据只有读权限,并没有写权限,所以上面的实现逻辑有问题。

解决办法

解决办法大致有两种:

  • 修改 Hive 的源码
  • 修改外部表的数据目录

修改 Hive 的源码

,如果当前表是外部表,则不检查当前用户是否对数据目录有写权限。实现如下:

diff --git a/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java b/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java

index 4520cd52539e26afebf9553ce411c9d4ee03cda0..1ae9b9771617637d8b8b9b16f7c5184d77e28d5a 100644

--- a/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java

+++ b/metastore/src/java/org/apache/hadoop/hive/metastore/HiveMetaStore.java

@@ -1360,13 +1360,20 @@ private void drop_table_core(final RawStore ms, final String dbname, final Strin

             throw new MetaException(e.getMessage());

           }

         }

+

         isExternal = isExternal(tbl);

         if (tbl.getSd().getLocation() != null) {

           tblPath = new Path(tbl.getSd().getLocation());

-          if (!wh.isWritable(tblPath.getParent())) {

-            throw new MetaException("Table metadata not deleted since " +

-                tblPath.getParent() + " is not writable by " +

-                hiveConf.getUser());

+

+          //Check that the user is owner of the table

+            if (!tbl.getOwner().equals(hiveConf.getUser())) {

+              throw new MetaException("Table metadata not deleted since user " + hiveConf.getUser()

+                  + " is not the owner of table " + tbl.getTableName());

+          }

+            // if table is internal, check that table location is writable by the user

+            if (!wh.isWritable(tblPath.getParent())&&!isExternal) {

+              throw new MetaException("Table metadata not deleted since " + tblPath.getParent()

+                  + " is not writable by " + hiveConf.getUser());

           }

         }

上面的代码是摘自HIVE-9020,详情请大家自己进去看。

修改外部表的数据目录

这种办法就是利用 Hive 提供的功能,修改当前外部表(order_info)的数据目录到一个可以写的数据目录下,然后再删除外部表,如下:

hive> alter table order_info set location 'hdfs://iteblogcluster/user/iteblog/tmp/';

hive> drop table order_info;

OK

Time taken: 0.254 seconds

然后我们再删除 order_info 表,这时候就没问题了。

如果外部表带有分区,删除每个分区的时候可能也会报上面的错误,这时候也需要我们修改每个分区的数据目录到一个可写的目录下就可以删除当前分区。

ALTER TABLE order_info PARTITION (dt='2017-06-27') SET LOCATION "new location";

本博客文章除特别声明,全部都是原创!
转载本文请加上:转载自过往记忆(https://www.iteblog.com/)
本文链接: 【Hive删除外部表异常(Table metadata not deleted)】(https://www.iteblog.com/archives/2166.html)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值