本文为您介绍在Hologres中简单权限模型(Simple Permission Model,SPM)的使用方法。
使用简单权限模型进行授权
在Hologres中,使用简单权限模型对单个实例进行授权可以使用如下方式:
- 使用管理控制台进行授权 - 您可以在Hologres管理控制台使用可视化方式创建用户并授权,详情请参见使用简单权限模型为RAM用户授权(推荐)。 
- 使用SQL语句进行授权 - 在Hologres实例连接开发工具后,可以使用SQL语句通过简单模式对用户进行授权,使该用户具有实例的相关权限。具体步骤如下所示: 
- 开启函数调用。 - 开启SPM前,您需要执行如下命令,开启调用函数的开关。 - create extension spm;
- 开启简单权限模型。 - 简单权限模型默认不开启,Superuser需要在目标DB里执行如下语句,开启简单权限模型。更多关于函数的说明请参见spm_enable。 - call spm_enable(); // 开启当前DB的简单权限模型。说明- 开启简单权限模型之后,developer用户组拥有DB中所有schema的所有表、类表的权限默认。 
- 可选:专家权限模型迁移。 - 如果您的DB使用的是专家权限模型,并且DB中包含一定数量的表、视图或外表等对象。此时,您必须将原对象迁移至简单权限模型,否则会出现表权限缺失的情况,从而影响业务运行。在该DB中执行如下语句迁移专家权限模型。 - call spm_migrate(); // 将DB中已有的对象change owner到developer,使用SPM管理。- 如果您是新创建的DB,DB内无任何对象,则不需要执行此步骤。 说明- 在开启简单权限模型时,需要确保当前DB没有正在运行的SQL,否则可能导致开启失败,并对服务产生影响。 - 由于migrate可能涉及到将大量表进行Alter Owner操作,触发PostgreSQL对此操作的限制,则spm_migrate每次仅对不超过max_locks_per_transaction的对象进行Change Owner操作。您可能需要多次执行spm_migrate,直到所有对象完成迁移为止。更多关于函数的说明请参见spm_migrate。 
- 创建用户。 - 在为新用户授权之前,您需要将新用户创建至当前实例中。如果新用户已经被创建进实例,可忽略此步骤。 - 阿里云账号、RAM用户: - call spm_create_user ('云账号UID/云邮箱/RAM账号'); // 创建用户,使用云邮箱时还需要加双引号 call spm_create_user ('云账号UID/云邮箱/RAM账号', '<dbname>_[admin|developer|writer|viewer]'); // 创建用户的同时把用户加入对应的用户组- 其中 - dbname为当前Hologres实例的数据库名称。- 示例:将RAM用户 - xxx.onaliyun.com加入- testdb数据库的- developer用户组中。- call spm_create_user ('xxx.onaliyun.com', 'testdb_developer');
- 自定义用户: - create user "BASIC$<user_name>" with password '<password>';
 说明- 如果是RAM用户,执行 - spm_create_user时需要在账号UID前加p4_,即“p4_UID”。
- 如果是自定义账号,暂不支持用户名称以 - admin、- developer、- writer、- viewer、- all_users结尾。
 
- 授权新用户。 - 成功将新用户创建至实例后,必须在对应的DB内将新用户加入相应的用户组,以完成授权操作。授权后,RAM用户就能使用开发工具连接当前DB并在权限范围内进行开发。如果是在创建用户的同时已经加入对应的用户组则不需要再次授权。更多关于函数的说明请参见spm_grant。 - 如下命令中,{dbname}_[admin|developer|writer|viewer]是将用户加入当前DB中可供选择的用户组名称,更多描述请参见用户组说明。 - call spm_grant('{dbname}_[admin|developer|writer|viewer]', '云账号id/云邮箱/RAM账号'); // 将某个用户加入某个用户组。- 您可以参照如下示例,将用户加入不同权限的用户组。 - // 加入某个DB的admin用户组。 call spm_grant('mydb_admin', 'p4_564306222995xxx'); // 将564306222995xxx(RAM用户)加入数据库mydb的admin用户组。 call spm_grant('mydb_admin', '197006222995xxx'); // 将197006222995xxx(云账号)加入数据库mydb的admin用户组。 call spm_grant('mydb_admin', 'ALIYUN$xxx'); // 将xxx@aliyun.com加入数据库mydb的admin用户组。 // 加入某个DB的developer用户组。 call spm_grant('mydb_developer', 'p4_564306222995xxx'); // 将564306222995xxx(RAM用户)加入数据库mydb的developer用户组。 call spm_grant('mydb_developer', '197006222995xxx'); // 将197006222995xxx(云账号)加入数据库mydb的developer用户组。 call spm_grant('mydb_developer', 'RAM$mainaccount:subuser');// 将云账号mainaccount的RAM用户subuser加入数据库mydb的developer用户组。 // 加入某个DB的viewer用户组。 call spm_grant('"MYDB_viewer"', 'p4_564306222995xxx'); // 将564306222995xxx(RAM用户)加入数据库"MYDB"的viewer用户组。 call spm_grant('"MYDB_viewer"', '197006222995xxx'); // 将197006222995xxx(云账号)加入数据库"MYDB"的viewer用户组。 call spm_grant('mydb_viewer', '"xxx@aliyun.com"'); // 将账号xxx@aliyun.com加入数据库mydb的viewer用户组。
移除用户组
在Hologres中,如果您需要将某个用户从某个DB的某个用户组中移除,使用简单权限模型可以使用如下方式:
- 使用管理控制台移除用户组 - 您可以在Hologres管理控制台使用可视化方式将用户从某个用户组移除,详情请参见DB管理。 
- 使用SQL语句移除用户组 - 如果您需要将某个用户从某个DB的某个用户组中移除,可以执行如下命令。更多关于函数的说明请参见spm_revoke。 - call spm_revoke('<dbname>_[admin|developer|writer|viewer]', '云账号id/云邮箱/RAM账号'); // 移除某用户的权限。 // 示例: // 将用户从某DB的admin用户组移除。 call spm_revoke('dbname_admin', 'p4_564306222995xxx');// 将564306222995xxx(RAM用户)移除admin用户组。 call spm_revoke('dbname_admin', '197006222995xxx');// 将197006222995xxx(云账号)移除admin用户组。 call spm_revoke('dbname_admin', 'xxx@aliyun.com');// 将账号xxx@aliyun.com移除admin用户组。 // 将用户从某DB的developer用户组移除。 call spm_revoke('mydb_developer', 'RAM$mainaccount:subuser'); // 将RAM用户subuser移出数据库mydb的developer用户组。 call spm_revoke('mydb_developer', 'p4_564306222995xxx');//将564306222995xxx(RAM用户)移除developer用户组。 // 将用户从某个DB的viewer用户组移除。 call spm_revoke('"MYDB_viewer"', 'p4_564306222995xxx'); // 将564306222995xxx(RAM用户)移出数据库"MYDB"的viewer用户组。
删除用户
如果您需要从实例中删除某个用户,可以执行如下语句。
成功删除用户后,该用户将会从当前实例删除,用户将无实例任何权限,请谨慎执行该操作。
DROP ROLE "云账号ID/云邮箱/RAM账号"; // 直接将该用户从实例中删除。(可选)切换专家模型至简单权限模型
如果您的DB使用的是专家权限模型,并且DB中包含一定数量的表、视图或外表等对象,您可以开启简单权限模型更好的管理权限。您可以通过调用spm_migrate函数将已有对象迁移至简单权限模型,在该DB中执行如下语句。
call spm_migrate();  // 将DB已有的对象,change owner到developer,通过SPM管理。在开启简单权限模型时,需要确保当前DB没有正在运行的SQL,否则可能导致开启失败,并对服务产生影响。
切换时可能涉及到将大量表进行Alter Owner的操作,但spm_migrate语句每次仅对不超过max_locks_per_transaction的对象进行Change Owner,您可能需要多次执行spm_migrate,直到所有对象切换完成为止。
关闭简单权限模型
- 关闭简单权限模型。 - Superuser可以根据业务需求,在该DB中执行如下语句关闭简单权限模型。更多关于函数的说明请参见spm_disable。 - call spm_disable();- 关闭简单权限模型之后,对应用户组将不会被删除,用户组内的用户拥有的权限请参见简单权限模型函数说明。 
- 清除用户组。 - 关闭简单权限模型后,您可以根据业务需求,通过调用spm_cleanup函数清除用户组。场景如下: 说明- 通常情况下,为了方便管理不建议删除用户组。 - 场景1:删除用户组保留DB。 - 如果您需要删除DB内的用户组,但同时又希望当前DB可以继续使用,Superuser可以执行如下语句。更多关于函数的说明请参见spm_cleanup。 - call spm_cleanup('{dbname}');说明- 调用spm_cleanup时,请确保该DB上没有正在运行的SQL语句,否则可能会失败,并可能对服务产生影响。 - 由于可能涉及对大量业务表进行Alter Owner操作,spm_cleanup每次仅对不超过 - max_locks_per_transaction的对象进行Alter Owner。因此,您可能需要多次执行spm_cleanup,直到所有对象完成迁移,并删除四个用户组为止。
- 场景2:先删除DB再删除用户组。 - 如果您已经将原有DB删除,但用户组并未删除,Superuser可以在其他的DB(例如postgres)执行如下语句删除对应用户组。 - call spm_cleanup('mydb');
 
关闭简单权限模型的注意事项:
- 只能由Superuser执行关闭操作。 
- Public拥有Public Schema的USAGE及CREATE权限。 
- Public拥有DB的CONNECT及TEMPORARY权限。 
- Public拥有functions及procedures的EXECUTE权限。 
- Public拥有 - language, data types (include domains)的USAGE权限。
- Public不拥有其他对象如table、view、materialized view、table column、sequence、foreign data wrapper、foreign server及schema(除public schema)等的权限。 
- 关闭简单权限模型之后,用户组的权限如下: - admin:保留对当前已有对象的权限,但对新建数据库对象不生效。 
- developer用户组:保留对当前已有对象的权限,但对新建数据库对象不生效。 
- writer用户组:保留对当前已有对象的权限,但对新建数据库对象不生效。 
- viewer用户组:保留对当前已有对象的权限,但对新建数据库对象不生效。 
 
再次开启简单权限模型
如果您的DB已经开启过简单权限模型,后来关闭并使用了专家权限模型。当您因为业务需求,需要再次开启简单权限模型时,您可以通过执行如下语句再次开启
call spm_enable('t');  // 开启当前DB的简单权限模型。
call spm_migrate();  // 将DB中已有的对象,change owner到developer,使用SPM管理。在开启简单权限模型时,需要确保当前DB没有正在运行的SQL,否则可能导致开启失败,并对服务产生影响。
切换时可能涉及到将大量表进行Alter Owner的操作,但spm_migrate语句每次仅对不超过max_locks_per_transaction的对象进行Change Owner,您可能需要多次执行spm_migrate,直到所有对象切换完成为止。