【DWS】用户同名schema权限问题,提示“ERROR: must be owner of function xx”
## 问题描述
DWS集群中同时有多个用户使用,每个用户都有自己的同名schema。
用user_dm用户在user_dm的schema下创建了表,然后在user_ods这个schema下面创建了函数。
使用一段时间之后,在用user_dm用户修改函数的时候提示必须是该函数的owner才能够修改。
## 原因分析
DWS创建用户的时候,会自动创建同名schema,用户自己创建的表和函数,如果没有指定schema名称,则会默认创建在自己的同名schema下。
如果创建在其他schema下,则就会出现该函数的owner是其他schema的同名用户,而非自己用户名的情况。但是这种情况下,自己和该schema同名用户都是可以修改该函数的。
如果后期修改的该函数的owner为创建该函数的用户,即该函数的owner和schema所在用户名不一致,就会出现两个用户自己都没有权限修改的情况。就是DWS集群出现这个问题的现象。
这是DWS为了保持和Oracle的兼容性而实现的特性,oracle也会为每个用户自己创建同名schema,用户自己的表都在自己的schema下。
该同名schema下是有权限限制的,其他用户在该schma下创建的函数,owner也是该schema的同名用户,而不是创建者的用户。
如果修改了该函数的owner,就会导致这个权限限制和实际函数owner不一致,导致两个用户都无法修改函数。
## 解决办法
修改这个函数的owner为该schema名称,然后该schema同名用户和原始创建该函数的用户,两个用户就都可以修改该函数了,已经在现网进行验证通过。
## 创建数据库
```sql
create database ransom;
```
## 用户登录命令
gsql -d ransom -U user_dm -W Passwd@2019 -p 8000 -r
gsql -d ransom -U user_ods -W Passwd@2019 -p 8000 -r
gsql -d ransom -U dbadmin -W Passwd@2019 -p 8000 -r
## 创建用户
```sql
CREATE USER user_dm IDENTIFIED BY 'Passwd@2019';
CREATE USER user_ods IDENTIFIED BY 'Passwd@2019';
alter user user_dm sysadmin;
-- 创建用户之后,会自动创建同名schema
ransom=> \dn
List of schemas
Name | Owner
-------------+--------
user_dm | user_dm
user_ods | user_ods
cstore | Ruby
dbms_job | Ruby
dbms_lob | Ruby
dbms_output | Ruby
dbms_random | Ruby
dbms_sql | Ruby
public | Ruby
sys | Ruby
utl_file | Ruby
utl_raw | Ruby
(12 rows)
```
## user_dm用户登录,创建表tsTest_dm
```sql
--创建表
create table user_dm.tsTest_dm(a date, b time, c timestamp without time zone, d timestamp with time zone);
ransom=> \dt
List of relations
Schema | Name | Type | Owner | Storage
--------+-----------+-------+-------+----------------------------------
user_dm | tstest_dm | table | user_dm | {orientation=row,compression=no}
(1 row)
--创建函数
CREATE OR REPLACE FUNCTION user_ods.f_dm(i integer) RETURNS integer AS $$
BEGIN
insert into user_dm.tsTest_dm(a,b,c,d) values (current_date, current_time,current_timestamp, now());
RETURN i + 1;
END;
$$ LANGUAGE plpgsql;
ransom=> \df user_ods.f_dm
List of functions
Schema | Name | Result data type | Argument data types | Type | fencedmode | propackage
--------+------+------------------+---------------------+--------+------------+------------
user_ods | f_dm | integer | i integer | normal | f | f
(1 row)
--注意,这里虽然用user_dm用户创建的函数,但是owner也是user_ods
ransom=> select * from dba_objects where object_name = 'f_dm';
owner | object_name | object_id | object_type | namespace
--------+-------------+-----------+-------------+-----------
user_ods | f_dm | 2773207 | PROCEDURE | 2773202
(1 row)
-- 这个时候,user_dm和user_ods用户都可以修改该存储过程
```
## user_dm用户登录,修改f_dm的owner为user_dm
```sql
alter function user_ods.f_dm(integer) owner to user_dm;
ransom=> select * from dba_objects where object_name = 'f_dm';
owner | object_name | object_id | object_type | namespace
-------+-------------+-----------+-------------+-----------
user_dm | f_dm | 2773207 | PROCEDURE | 2773202
(1 row)
```
## user_dm用户登录,修改函数f_dm
```sql
ransom=> CREATE OR REPLACE FUNCTION user_ods.f_dm(i integer) RETURNS integer AS $$
postgres$> BEGIN
postgres$> insert into tsTest_dm(a,b,c,d) values (current_date, current_time,current_timestamp, now());
postgres$> RETURN i + 1;
postgres$> END;
postgres$> $$ LANGUAGE plpgsql;
ERROR: must be owner of function f_dm
```
## user_ods用户登录,修改函数f_dm
```sql
ransom=> CREATE OR REPLACE FUNCTION user_ods.f_dm(i integer) RETURNS integer AS $$
postgres$> BEGIN
postgres$> insert into tsTest_dm(a,b,c,d) values (current_date, current_time,current_timestamp, now());
postgres$> RETURN i + 1;
postgres$> END;
postgres$> $$ LANGUAGE plpgsql;
ERROR: must be owner of function f_dm
--也会报错,现在不论是dm还是ods用户,都无法修改该函数。
```
## 使用user_dm用户登录,修改f_dm函数的owner为user_ods
```sql
alter function user_ods.f_dm(integer) owner to user_ods;
ransom=> select * from dba_objects where object_name = 'f_dm';
owner | object_name | object_id | object_type | namespace
--------+-------------+-----------+-------------+-----------
user_ods | f_dm | 2773207 | PROCEDURE | 2773202
(1 row)
--修改存储过程,可以修改
ransom=> CREATE OR REPLACE FUNCTION user_ods.f_dm(i integer) RETURNS integer AS $$
postgres$> BEGIN
postgres$> insert into tsTest_dm(a,b,c,d) values (current_date, current_time,current_timestamp, now());
postgres$> RETURN i + 1;
postgres$> END;
postgres$> $$ LANGUAGE plpgsql;
CREATE FUNCTION
```
## user_ods用户登录,修改函数f_dm, 修改成功。
```sql
[Ruby@host-172-16-26-12 ~]# gsql -d postgres -U user_ods -W Passwd@2019 -p 8000 -r
gsql ((Gauss200 V100R008C10 build cf7c712a) compiled at 2019-06-04 14:27:49 commit 5133 last mr 8583 )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
ransom=>
ransom=> CREATE OR REPLACE FUNCTION user_ods.f_dm(i integer) RETURNS integer AS $$
postgres$> BEGIN
postgres$> insert into tsTest_dm(a,b,c,d) values (current_date, current_time,current_timestamp, now());
postgres$> RETURN i + 1;
postgres$> END;
postgres$> $$ LANGUAGE plpgsql;
CREATE FUNCTION
ransom=>
```
- 点赞
- 收藏
- 关注作者
评论(0)