本文為您介紹在即時數倉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以下版本,請您使用自助升級或加入HologresDingTalk交流群反饋,詳情請參見如何擷取更多的線上支援?。
基於Schema層級的簡單許可權模型授權
在Hologres執行個體串連開發工具後,可以使用SQL語句通過基於Schema層級的簡單模式對使用者進行授權,使該使用者具有對應Schema的相關許可權。
開啟函數調用。
開啟SLPM前,您需要執行如下命令,開啟調用函數的開關。樣本中的extension是DB維度,在同一個DB只需執行一次。
create extension slpm;
開啟SLPM。
SLPM預設不開啟,需要Superuser在目標DB裡執行如下語句進行開啟。同時,在開啟SLPM時,需要確保當前DB沒有正在啟動並執行SQL,否則可能導致開啟失敗,並對服務產生影響。
call slpm_enable (); // 開啟當前DB的SLPM。
可選:專家許可權模型切換為SLPM。
如果您的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]'); // 建立使用者的同時把使用者加入對應的使用者組。
授權新使用者。
成功將新使用者建立至執行個體後,必須在對應的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以下版本,請您使用自助升級或加入HologresDingTalk交流群反饋,詳情請參見如何擷取更多的線上支援?。
情境描述
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的視圖無法查詢。