本文為您介紹在實時數倉Hologres中使用SQL語句實現基于Schema級別的簡單權限模型(Schema-level Permission Model,SLPM)的使用方法。
SLPM的使用限制
由于SLPM是基于Schema級別嚴格進行權限管控的,因此在授權和使用時需要您注意如下的限制條件:
當您創建一個View或者Rule,引用了跨Schema的兩個或多個表時,由于Schema間權限不互通的原因,此View或者Rule將無法被訪問。會出現報錯:
ERROR: permission denied for table
。因此不建議您在SLPM管理的DB中創建跨Schema的View或Rule對象。如果需要創建跨Schema的視圖,請參見在SLPM模式下創建跨Schema的視圖(Beta)。開啟SLPM之后,只會開放特定的權限,開放權限請參見基于Schema級別的簡單權限模型授權。以下表格中的DDL功能將不能在SLPM使用,請您使用對應的SLPM語句執行相關操作,具體函數說明請參見基于Schema級別的簡單權限模型函數說明。
命令語句
說明
SLPM語句
alter table owner to xx
所有table owner都是對應Schema的developer用戶組,不支持修改。
無需手動執行。
grant
將用戶加入某個用戶組后,會被授予對應用戶組的權限,無需再執行grant授權語句。
slpm_grant
revoke
若要移除某個用戶的某個權限,只能通過將該用戶移除某個用戶組的方法來實現,不能單獨執行revoke語句。
slpm_revoke
alter default privileges
在原有權限模型下,授權只對當前以及過去的表有權限,未來表需要重新授權。在簡單模型下,無需考慮建表的時態,只需要加入某個用戶組就能擁有對應的權限,因此無需再給未來表授權。
無需手動執行。
create / drop / alter / rename默認用戶組
開啟SLPM后,會默認生成admin/developer/writer/viewer等用戶組,不允許用戶(包括Superuser)對默認用戶組進行創建、修改和刪除。
不涉及。
rename schema
Schema重命名不支持在某個DB直接執行
alter rename schema
命令,需要調用slpm_rename_schema
命令實現。slpm_rename_schema
rename database
DB重命名不支持直接執行
alter rename database
命令,需要調用slpm_rename_database
命令實現。slpm_rename_database
drop database
刪除DB需要在執行
drop database
之后,調用slpm_cleanup('<dbname>')
來清除默認用戶。需要執行
drop database
之后,調用slpm_cleanup('<dbname>')
來清除默認用戶。僅Hologres V1.3.36及以上版本支持跨Schema創建視圖,如果您的實例是V1.3.36以下版本,請您使用自助升級或加入Hologres釘釘交流群反饋,詳情請參見如何獲取更多的在線支持?。
基于Schema級別的簡單權限模型授權
在Hologres實例連接開發工具后,可以使用SQL語句通過基于Schema級別的簡單模式對用戶進行授權,使該用戶具有對應Schema的相關權限。
開啟函數調用。
開啟SLPM前,您需要執行如下命令,開啟調用函數的開關。示例中的extension是DB維度的,在同一個DB只需執行一次。
create extension slpm;
開啟SLPM。
SLPM默認不開啟,需要Superuser在目標DB里執行如下語句進行開啟。同時,在開啟SLPM時,需要確保當前DB沒有正在運行的SQL,否則可能導致開啟失敗,并對服務產生影響。
call slpm_enable (); // 開啟當前DB的SLPM。
說明為當前DB開啟SLPM之后,您必須把使用該DB的所有用戶加入至對應的用戶組,否則這些用戶將無實例的連接權限,可能對業務造成影響。具體操作請參見授權新用戶。
可選:專家權限模型切換為SLPM。
您可以進入Hologres管理控制臺,從DB授權頁面查看當前使用的權限模型。
如果您的DB使用的是專家權限模型,并且DB中包含一定數量的表、視圖或外表等對象。此時,如果您需要開啟SLPM進行權限管理,可以通過調用slpm_migrate函數將原用戶的權限由專家模型權限切換為SLPM。
call slpm_migrate (); // 將DB中已有的對象change owner到develoepr,使用SLPM管理。
在將專家權限模型切換為SLPM時,需要您注意如下內容:
slpm_migrate函數默認每次僅對64個(參數可調)用戶進行權限切換。如果涉及用戶對象數量過多,需要多次執行該函數,直到全部用戶權限切換完畢。更多關于該函數的說明,請參見slpm_migrate。
創建用戶至當前實例。
在為新用戶授權之前,您需要將新用戶創建至當前實例中。如果新用戶已經被創建進實例,可跳過該步驟。
如下命令中,{dbname}.[admin|{schemaname}.developer|{schemaname}.writer|{schemaname}.viewer]是將用戶加入當前DB中可供選擇的用戶組名稱,更多描述請參見用戶組說明。
call slpm_create_user ('云賬號ID/云郵箱/RAM賬號'); // 創建用戶,使用云郵箱時還需要加雙引號。 call slpm_create_user ('云賬號ID/云郵箱/RAM賬號', '{dbname}.[admin|{schemaname}.developer|{schemaname}.writer|{schemaname}.viewer]'); // 創建用戶的同時把用戶加入對應的用戶組。
說明如果使用RAM用戶UID賬號進行授權,執行
slpm_create_user
時需要在UID前添加p4_
,即p4_UID
。在Hologres中,請前往用戶頁面獲取UID賬號。更多RAM賬號表達格式請參見賬號概述。SLPM權限模型暫不支持自定義賬號名稱以
admin
、developer
、writer
、viewer
、all_users
結尾。如果您需要批量創建用戶至當前實例,請前往Hologres管理控制臺,實例詳情頁面單擊賬號管理,在用戶管理頁簽批量新增用戶。請參見新增用戶。
授權新用戶。
成功將新用戶創建至實例后,必須在對應的DB內將新用戶加入相應的用戶組,以完成授權操作。如果是在創建用戶的同時已經加入對應的用戶組則不需要再次授權。
如下命令中,{dbname}.[admin|{schemaname}.developer|{schemaname}.writer|{schemaname}.viewer]是將用戶加入當前DB中可供選擇的用戶組名稱,更多描述請參見用戶組說明。
call slpm_grant ('{dbname}.[admin|{schemaname}.developer|{schemaname}.writer|{schemaname}.viewer]', '云賬號id/云郵箱/RAM賬號'); // 將某個用戶加入某個用戶組
您可以參照如下示例,將用戶加入不同權限的用戶組。
// 加入某個DB的admin用戶組 call slpm_grant ('mydb.admin', '197006222995xxx'); // 將197006222995xxx加入數據庫mydb的admin用戶組 call slpm_grant ('mydb.admin', 'ALIYUN$xxx'); // 將xxx@aliyun.com加入數據庫mydb的admin用戶組 // 加入某個DB的developer用戶組 call slpm_grant ('mydb.public.developer', '197006222995xxx'); // 將197006222995xxx加入數據庫mydb的developer用戶組 call slpm_grant ('mydb.public.developer', 'RAM$mainaccount:subuser');// 將云賬號mainaccount的RAM用戶subuser加入數據庫mydb的developer用戶組 // 加入某個DB的viewer用戶組 call slpm_grant ('"MYDB.lisa.viewer"', '197006222995xxx'); // 將197006222995xxx加入數據庫"MYDB"的viewer用戶組 call slpm_grant ('mydb.lisa.viewer', '"xxx@aliyun.com"'); // 將賬號xxx@aliyun.com加入數據庫mydb的viewer用戶組
移除用戶組
如果您需要將某個用戶從某個DB的某個用戶組中移除,可以執行如下命令。移除之后,該用戶將不具備該用戶組具有的權限。
如下命令中,{dbname}.[admin|{schemaname}.developer|{schemaname}.writer|{schemaname}.viewer]是將用戶加入當前DB中可供選擇的用戶組名稱,更多描述請參見用戶組說明。
call slpm_revoke ('{dbname}.[admin|{schemaname}.developer|{schemaname}.writer|{schemaname}.viewer]', '云賬號id/云郵箱/RAM賬號'); // 移除某用戶的權限
您可以參照如下示例,將用戶從不同權限的用戶組移除。
// 將用戶從某DB的admin用戶組移除
call slpm_revoke ('dbname.admin', 'p4_564306222995xxx');//將564306222995xxx(RAM用戶)移除admin用戶組
call slpm_revoke ('dbname.admin', '197006222995xxx');//將197006222995xxx(云賬號)移除admin用戶組
call slpm_revoke ('dbname.admin', '"xxx@aliyun.com"');
// 將用戶從某DB的developer用戶組移除
call slpm_revoke ('mydb.lisa.developer', 'RAM$mainaccount:subuser'); // 將RAM用戶subuser移出數據庫mydb的developer用戶組
call slpm_revoke ('mydb.public.developer', 'p4_564306222995xxx');//將564306222995xxx(RAM用戶)移除developer用戶組
// 將用戶從某個DB的viewer用戶組移除
call slpm_revoke ('"MYDB.SCHEMA1.viewer"', 'p4_564306222995xxx'); // 將564306222995xxx(RAM用戶)移出數據庫"MYDB"的viewer用戶組
刪除用戶
您也可以根據需要對某個用戶進行刪除,成功刪除用戶后,該用戶將會從當前實例刪除,用戶將無實例任何權限,請謹慎執行該操作。
DROP ROLE "云賬號ID/云郵箱/RAM賬號"; // 直接將該用戶從實例中刪除。
基于Schema級別的簡單權限模型關閉
當您不需要使用基于Schema級別的簡單權限模型時,您可以根據業務需求執行如下操作,關閉此功能。
關閉SLPM。
開啟SLPM后,Superuser也可以根據業務需要執行如下示例內容關閉SLPM。關閉SLPM之后,對應用戶組將不會被刪除,對應用戶組內用戶擁有的權限請參見基于Schema級別的簡單權限模型函數說明。
call slpm_disable ();
關閉SLPM注意事項:
只有Superuser可以執行關閉操作。
將對PUBLIC開放public schema的USAGE和CREATE權限、DB的CONNECT和TEMPORARY權限、functions和procedures的EXECUTE權限以及language和data types (include domains) 的USAGE權限。
對于其他對象如table、view、materialized view、table column、sequence、foreign data wrapper、foreign server、schema(除public schema)等不會將權限開放給PUBLIC。如果您需要開放此權限,請聯系Superuser授權。
關閉SLPM之后,{db}.admin、{db}.{schemaname}.developer、{db}.{schemaname}.writer和{db}.{schemaname}.viewer將保留對當前已有對象的權限,對新建數據庫對象不生效。
刪除用戶組(通常情況下,為了方便管理不建議刪除用戶組)。
關閉SLPM后,您可以根據業務需求,通過調用slpm_cleanup函數刪除用戶組。場景如下:
場景1:刪除用戶組保留DB。
如果您需要刪除DB內的用戶組,但同時又希望當前DB可以繼續使用,Superuser可以執行如下語句。
call slpm_cleanup ( '<dbname>' );
說明調用slpm_cleanup時,請確保該DB上沒有正在運行的SQL語句,否則可能會失敗,并可能對服務產生影響。
由于slpm_cleanup需要將現有對象owner轉移給當前用戶,但slpm_cleanup默認每次僅對64個(參數可調)對象轉移owner。因此,您可能需要多次執行slpm_cleanup,直到所有對象完成遷移(建議累計執行次數小于5次),并刪除所有保留用戶組為止。更多關于該函數的說明,請參見slpm_cleanup。
場景2:先刪除DB再刪除用戶組。
如果您已經將原有DB刪除,但用戶組并未刪除,Superuser可以在其他的DB(例如postgres)執行如下語句刪除原有DB對應的所有用戶組。
call slpm_cleanup ( 'mydb' );
重新開啟SLPM
如果您因為某些原因需要重新開啟SLPM,步驟如下。
清除用戶權限
為了避免用戶權限混亂,在開啟SLPM之前,建議執行如下命令將數據庫中用戶現有的權限全部清除。
call slpm_cleanup ( '<dbname>' );
重新開啟SLPM權限模型
清除用戶權限后,執行以下命令開啟SLPM權限模型。
-- 以恢復模式開啟SLPM call slpm_enable ('t'); -- 將DB中已有的對象owner更新為developer,使用SLPM管理,必須執行 call slpm_migrate ();
用戶授權
重新開啟SLPM之后,可以在Hologres管理控制臺或者使用SQL命令為用戶重新授權,詳情請參見用戶授權。
在SLPM模式下創建跨Schema的視圖(Beta)
僅Hologres V1.3.36及以上版本支持跨Schema創建視圖,如果您的實例是V1.3.36以下版本,請您使用自助升級或加入Hologres釘釘交流群反饋,詳情請參見如何獲取更多的在線支持?。
場景描述
SLPM實現了基于Schema級別的簡單權限管理,但是在業務中有時需要跨Schema去創建視圖。例如業務場景中,按照數倉的各個層級創建Schema,分別為ODS、DWD、DWS、ADS,然后在各層創建表,但是有時需要跨Schema創建視圖,例如使用DWS層和DWD層的表創建一個ADS的視圖用于業務服務,如下表所示:
Database | Schema | Table | View |
erp_db | ods | orders | 不涉及 |
dwd | customer | 不涉及 | |
ads | 不涉及 | 視圖名稱:customer_total_order_price 視圖DDL:
|
打開跨Schema創建視圖功能
注意事項
系統默認關閉跨Schema創建視圖功能。
跨Schema創建視圖時,創建者需要有視圖所在Schema的
developer
權限,同時擁有視圖中用到所有表的viewer
或以上權限。例如場景描述中的場景,若需要使用賬號
ads_dev_user
在ads
Schema創建customer_total_order_price_view
視圖。此時需要賬號ads_dev_user
擁有ads
Schema的developer
權限以及ods
、dwd
Schema的viewer
權限。查看跨Schema創建的視圖時,僅需要賦予賬號在視圖所在Schema的
viewer
或以上權限。例如賬號
ads_view_user
查看ads.customer_total_order_price_view
視圖,僅需要賦予賬號ads_view_user
在ads
Schema的viewer
或以上的權限即可。打開跨Schema創建視圖的功能后,創建的視圖的Owner均為創建視圖的用戶。只有視圖的Owner可以修改視圖和刪除視圖。
例如場景描述中的場景,視圖
ads.customer_total_order_price_view
的Owner是賬號ads_dev_user
。若賬號ads_dev_user
需要從數據庫中刪除,您可以使用如下SQL轉移視圖的Owner,但是請務必確保被轉移的賬號具備視圖中所有表對應Schema的viewer
或以上的權限以及視圖所在Schema的developer
權限。--語法示例 call slpm_alter_view_owner('視圖名', '云賬號ID/云郵箱/RAM賬號'); --使用示例:將視圖ads.customer_total_order_price_view的owner轉移給p4_xxxxx call slpm_alter_view_owner ('ads.customer_total_order_price_view', 'p4_xxxxx');
使用命令
您如果需要使用跨Schema創建視圖的功能,使用Superuser用戶執行如下SQL打開跨Schema創建視圖的功能。
call slpm_enable_multi_schema_view();
執行完畢后,即可跨Schema創建視圖。
關閉跨Schema創建視圖功能
您如果不再使用跨Schema創建視圖的功能,可以執行如下SQL關閉。
-- 關閉跨Schema創建視圖的功能
call slpm_disable_multi_schema_view();
-- 將所有的視圖的Owner轉移到視圖所在Schema的developer的角色
call slpm_migrate();
執行完畢后,非跨Schema的視圖可以繼續查詢,恢復默認的SLPM的行為;跨Schema的視圖無法查詢。