更新时间:2022-12-14 GMT+08:00

用add jar方式创建function,执行drop function时出现问题

问题

  • 问题一:

    用户没有drop function的权限,能够drop成功。具体场景如下:

    1. 在FusionInsight Manager页面上添加user1用户,给予用户admin权限,执行下列操作:
      set role admin;add jar /home/smartcare-udf-0.0.1-SNAPSHOT.jar;create database db4;use db4;create function f11 as 'com.xxx.smartcare.dac.hive.udf.UDFArrayGreaterEqual';create function f12 as 'com.xxx.smartcare.dac.hive.udf.UDFArrayGreaterEqual';
    2. 修改user1用户,取消admin权限,执行下列操作:
      drop functiondb4.f11;

    结果显示drop成功,如图1所示。

    图1 用户没有权限却drop成功结果
  • 问题二:

    用户drop function成功,show function的时候,function仍然存在。具体场景如下:

    1. 在FusionInsight Manager页面上添加user1用户,给予用户admin权限,进入spark-beeline执行下列操作:
      set role admin;create database db2;use db2;add jar /home/smartcare-udf-0.0.1-SNAPSHOT.jar;create function f11 as 'com.xxx.smartcare.dac.hive.udf.UDFArrayGreaterEqual';create function f12 as 'com.xxx.smartcare.dac.hive.udf.UDFArrayGreaterEqual';
    2. 退出后再进入spark-beeline执行下列操作:
      set role admin;use db2;drop function db2.f11;
    3. 退出后再进入spark-beeline执行下列操作:
      use db2;show functions;

      结果显示,被drop的function仍然存在,如图2所示。

      图2 执行show functions操作后的结果

回答

  • 问题根因:

    上述两个问题是由于多主实例模式或者多租户模式下,使用spark-beeline通过add jar的方式创建function,此function在各个JDBCServer实例之间是不可见的。执行drop function时,如果该session连接的JDBCServer实例不是创建function的JDBCServer实例,则在该session中找不到该function,而且hive默认将“hive.exec.drop.ignorenonexistent”设置为“true”,即当function不存在时,删除function操作不会报错,这样就表现出了用户没有drop function的权限,执行drop时却没有报错,让用户误以为drop成功;但重新起session时又连到创建function的JDBCServer上,因此执行show function,function仍然存在。该行为是hive的社区行为。

  • 修改方案:

    在执行drop function命令之前先执行add jar命令,则该function在有权限的情况下才能drop成功,且drop成功之后不会出现show function仍然存在的现象。