全部产品
Search
文档中心

实时数仓Hologres:简单权限模型的使用

更新时间:Aug 21, 2024

本文为您介绍在Hologres中简单权限模型(Simple Permission Model,SPM)的使用方法。

使用简单权限模型进行授权

在Hologres中,使用简单权限模型对单个实例进行授权可以使用如下方式:

  • 使用SQL语句进行授权

    在Hologres实例连接开发工具后,可以使用SQL语句通过简单模式对用户进行授权,使该用户具有实例的相关权限。具体步骤如下所示:

  1. 开启函数调用。

    开启SPM前,您需要执行如下命令,开启调用函数的开关。

    create extension spm;
  2. 开启简单权限模型。

    简单权限模型默认不开启,Superuser需要在目标DB里执行如下语句,开启简单权限模型。更多关于函数的说明请参见spm_enable

    call spm_enable();  // 开启当前DB的简单权限模型。
    说明

    开启简单权限模型之后,developer用户组拥有DB中所有schema的所有表、类表的权限默认。

  3. 可选:专家权限模型迁移。

    如果您的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

  4. 创建用户。

    在为新用户授权之前,您需要将新用户创建至当前实例中。如果新用户已经被创建进实例,可忽略此步骤。

    • 阿里云账号、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”。

    • 如果是自定义账号,暂不支持用户名称以admindeveloperwriterviewerall_users结尾。

  5. 授权新用户。

    成功将新用户创建至实例后,必须在对应的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的某个用户组中移除,使用简单权限模型可以使用如下方式:

  • 使用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,直到所有对象切换完成为止。

关闭简单权限模型

  1. 关闭简单权限模型。

    Superuser可以根据业务需求,在该DB中执行如下语句关闭简单权限模型。更多关于函数的说明请参见spm_disable

    call spm_disable();

    关闭简单权限模型之后,对应用户组将不会被删除,用户组内的用户拥有的权限请参见简单权限模型函数说明

  2. 清除用户组。

    关闭简单权限模型后,您可以根据业务需求,通过调用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,直到所有对象切换完成为止。