【云圖說】第235期 DDS讀寫兩步走 帶您領略只讀節點的風采
1242
2025-04-01
1. 假設當前有兩個用戶tom和jerry,如果想要用戶jerry能夠對當前tom創建的所有表以及將來創建的表都有查詢權限,如何處理:
-- 1. 將用戶tom下的同名schema權限賦給jerry grant usage on schema tom to jerry; -- 2. 將用戶tom已經創建的表的select權限賦給jerry grant select on all tables in schema tom to jerry; -- 3. 將用戶tom未來在同名schema下創建的表的select權限賦給jerry -- 注意,其中for user tom是必須的,表示把用戶tom將來在schema tom下創建的表的只讀權限賦權給jerry -- 如果不加for user tom,缺省值為當前角色/用戶 alter default privileges for user tom in schema tom grant select on tables to jerry;
2. 如何查看某張表當前的權限情況
pg_class中relacl字段表示當前的訪問權限,可以從該字段查詢當前哪些用戶對該表有訪問權限,該字段回顯結果為:
rolename=xxxx/yyyy? ? --表示rolename對該表有xxxx權限,且權限來自yyyy
=xxxx/yyyy? ? ? ? ? ? ? ? ? -- 表示public對該表有xxxx權限,且權限來自yyyy
pg_class該字段介紹可參考DWS幫助文檔:
https://support.huaweicloud.com/devg-dws/dws_04_0449.html#ZH-CN_TOPIC_0161912628__zh-cn_topic_0085032747_zh-cn_topic_0059778035_td89f8f6cc98f4a11a08b3c45d852a6cc
例如:
postgres=> select relname,relowner,relacl from pg_class where relname = 'tom_t1'; relname | relowner | relacl ---------+----------+-------- tom_t1 | 25184 | (1 row)
如果relacl字段為空,說明只有管理員賬戶和該表的創建者對該用戶有查詢權限;
postgres=> select relname,relowner,relacl from pg_class where relname = 'tom_t1'; relname | relowner | relacl ---------+----------+-------------------------------- tom_t1 | 25184 | {tom=arwdDxt/tom,jerry=ar/tom} (1 row)
本例中,relacl字段的含義是,用戶tom對該表有全部權限,且權限來自tom;用戶jerry對該表有select和insert權限,且該權限來自tom。
權限相關的判斷可以通過訪問權限查詢函數進行判斷(has_table_privilege等),例如:
postgres=# select * from has_table_privilege('jerry','test','select'); has_table_privilege --------------------- t (1 row) postgres=# select * from has_table_privilege('tom','test','select'); has_table_privilege --------------------- f (1 row)
其中,a表示insert權限,r表示select權限。其他權限參考以下表格:
3. 某張表執行過 grant select on table t1 to public 導致所有用戶對該表有讀權限,如何針對某個用戶回收權限
場景構造:假設當前有兩個普通用戶use1和use2,當前數據庫下有兩張表t1和t2, 執行:
grant select on table t1 to public;
用戶use1和use2對該表有訪問權限,并且新建用戶use3后,新用戶use3對該表也有訪問權限,且執行revoke select on table t1 from use3無效:
test=# test=# revoke select on table t1 from use3; REVOKE test=# \c - use3 Password for user use3: Non-SSL connection (SSL connection is recommended when requiring high-security) You are now connected to database "test" as user "use3". test=> test=> select * from t1; a --- (0 rows) test=> test=> select relname, relacl from pg_class where relname = 't1'; relname | relacl ---------+----------------------------------------------- t1 | {liukunpeng=arwdDxt/liukunpeng,=r/liukunpeng} (1 row)
這是因為之前執行過 grant select on table t1 to public 這條sql,該sql中關鍵字public表示該權限要賦予給所有角色,包括以后創建的角色,所以新用戶use3對該表也有訪問權限。public可以看做是一個隱含定義好的組,它總是包含所有角色。任何角色或用戶都將擁有通過GRANT直接賦予的權限和所屬組的權限,再加上public的權限。因此,執行完revoke select on table t1 from use3之后,雖然use3用戶沒有了該表的訪問權限(通過該表的relacl字段也可以看到,參考第二個案例的鏈接權限說明),但是他仍然有public的權限,所以仍能訪問該表。
解決方法:需要revoke回public的權限,然后對use3用戶的權限單獨管控。但是由于revoke回public的權限后可能導致原來能訪問該表的用戶(use1和use2)無法訪問該表,影響現網業務,因此需要先對這些用戶執行grant賦予相應權限,然后revoke回public的權限。
test=# --查看所有用戶 test=# select * from pg_user where usesysid >= 16384; usename | usesysid | usecreatedb | usesuper | usecatupd | userepl | passwd | valbegin | valuntil | respool | parent | spacelimit | useconfig | nodegroup | tempspacelimit | spillspacelimit ---------+----------+-------------+----------+-----------+---------+----------+----------+----------+--------------+--------+------------+-----------+-----------+----------------+----------------- jack | 16408 | f | f | f | f | ******** | | | default_pool | 0 | | | | | tom | 16412 | f | f | f | f | ******** | | | default_pool | 0 | | | | | use1 | 16437 | f | f | f | f | ******** | | | default_pool | 0 | | | | | use2 | 16441 | f | f | f | f | ******** | | | default_pool | 0 | | | | | use3 | 16448 | f | f | f | f | ******** | | | default_pool | 0 | | | | | (5 rows) test=# --對原用戶執行grant test=# grant select on table t1 to jack,tom,use1,use2; GRANT test=# --回收public的權限 test=# revoke select on table t1 from public; test=# \c - use3 Password for user use3: Non-SSL connection (SSL connection is recommended when requiring high-security) You are now connected to database "test" as user "use3". test=> select * from t1; ERROR: permission denied for relation t1
可以看到,執行上述操作后,新用戶use3的權限已收到管控,原用戶use1和use2仍能訪問該表,問題解決。
4. 賦予用戶schema的all權限后建表仍然報錯:ERROR: ?current user does not have privilege to role tom
場景如下,有兩個用戶tom和jerry,jerry想要再tom的同名schema下創建表,于是把該schema的all權限賦給tom,但是創建表時仍然報錯:
postgres=# grant all on schema tom to jerry; GRANT postgres=# \c - jerry Password for user jerry: Non-SSL connection (SSL connection is recommended when requiring high-security) You are now connected to database "postgres" as user "jerry". postgres=> postgres=> create table tom.t(a int); ERROR: current user does not have privilege to role tom
根據報錯內容,jerry需要角色tom的權限,通過以下方式授予:
postgres=# grant tom to jerry; GRANT ROLE postgres=# \c - jerry Password for user jerry: Non-SSL connection (SSL connection is recommended when requiring high-security) You are now connected to database "postgres" as user "jerry". postgres=> postgres=> create table tom.t(a int); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using 'a' as the distribution column by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE postgres=>
把角色tom的權限賦予jerry后,建表執行成功。
EI企業智能 Gauss AP 數據倉庫服務 GaussDB(DWS)
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。