跳至内容

如何解决 Amazon Redshift 中的“无法删除用户”错误?

2 分钟阅读
0

我无法在 Amazon Redshift 中删除用户或组。

简短描述

如果您试图在 Amazon Redshift 中删除用户,可能会看到以下错误消息之一:

  • 错误:无法删除用户的“用户名”,因为某些对象依赖于它
  • 错误:无法删除用户的“用户名”,因为该用户对某个对象具有权限
  • 错误:无法删除用户的“用户名”,因为该用户拥有某些对象

如果您试图删除以下类型的用户,可能会出现以下错误:

  • 拥有默认权限的所有者或目标用户。
  • 任何对象(例如数据库、架构、表、视图、过程和库)的所有者。
  • 拥有对象权限的用户。

要解决错误消息中提及的错误,请先移除用户权限。然后,转移对象所有权或移除对象的群组所有权。

**重要事项:**您必须撤销 Amazon Redshift 集群中所有数据库的用户和组权限。要查看集群中数据库的列表,请运行 SHOW DATABASES 命令。要查看您登录的数据库的名称,请运行 CURRENT_DATABASE 命令。

解决方法

安装脚本来创建视图

以超级用户身份从 GitHub 网站上的 AWS Labs 存储库下载并安装 v_generate_user_grant_revoke_ddl.sqlv_find_dropuser_objs.sql 脚本。v_generate_user_grant_revoke_ddl.sqlv_find_dropuser_objs.sql 脚本在其定义中使用 admin 架构。如果您在 Amazon Redshift 集群上没有 admin 架构,请在现有架构中修改该定义。或者,创建 admin 架构

如果您在视图定义中更改任何列,请先删除您的现有视图,然后再创建新视图和定义。如果您在删除旧视图之前创建新视图,则会收到 not valid table 错误。

删除用户

完成以下步骤:

  1. 打开查询编辑器 v2。然后,搜索要删除的用户,以查看已授予的用户权限。

  2. 要将这些权限重新授予其他用户,请运行以下命令:

    select regexp_replace(ddl,grantor,'superuser') from v_generate_user_grant_revoke_ddl where grantor='username' and ddltype='grant' and objtype <>'default acl' order by objseq,grantseq;

    注意:要重新授予权限,您必须是对该对象拥有权限的用户。而且,您必须有权向其他用户授予权限。如果您没有授予权限,则可以以超级用户的身份重新授予这些权限。

  3. 将权限重新授予其他用户后,运行以下命令以从该用户撤销这些权限:

    select ddl from v_generate_user_grant_revoke_ddl where ddltype='revoke' and (grantee='username' or grantor='username') order by objseq, grantseq desc;

    **注意:**请将 grantor 替换为授予这些权限的用户的名称。请将 grantee 替换为接受这些权限的用户的名称。
    如果您的查询没有返回任何记录或者 DROP USER 命令失败,请运行以下命令:

    select ddl from admin.v_generate_user_grant_revoke_ddl where ddltype='revoke' and ddl ilike '%user-to-be-dropped%' order by objseq, grantseq desc;

    上述查询会列出您必须从该用户撤销的任何其他权限。撤销这些权限。

  4. 要检查访问控制列表 (ACL) 是否为空,请运行以下查询:

    select * from pg_user where username = 'username-to-be-dropped';   
    select * from pg_default_acl where defacluser= user-id;
    select pg_get_iam_role_by_user('user-name');

    **注意:**请将 username-to-be-droppeduser-name 替换为您的值。要检索用户名和用户 ID,请在 PG_USER_INFO 表中找到 usenameusesysid 列条目。如果 PG_DEFAULT_ACL 表中存在用户条目,则无法删除该用户。

  5. 如果用户仍然拥有对象的权限,请检查该用户是否拥有 assumerole 权限:

    select pg_get_iam_role_by_user('user-name');

    如果用户拥有 assumerole 权限,请先从 PUBLIC 撤销 assumerole 权限。然后,运行以下命令来撤消用户名

    revoke assumerole on all from public for all;  
    revoke assumerole on all from user-name for all;
  6. (可选)如果该用户仍然拥有某些对象的权限,请确认该用户是否属于另一个群组。该用户可能拥有该组授予的权限。或者,该用户可能拥有授予 PUBLIC 组的权限。
    要检查该用户仍拥有的权限,请运行以下查询:

    select * from pg_user where username = 'username-to-be-dropped';  
    select * from pg_group;

    pg_group 查询的输出中,检查 grolist 列中是否有列出用户的条目。如果用户属于另一个组,则 pg_group 列会显示用户 ID。要检查组的权限,请运行以下命令:

    select ddl from admin.v_generate_user_grant_revoke_ddl where ddltype='revoke' and grantee= 'group group-name' ;
    select * from admin.v_generate_user_grant_revoke_ddl where objname='timecards' and schemaname='postgres' and grantee='PUBLIC' and ddltype='revoke';

    **注意:**请将 objnameschemaname 替换为您的表和架构。默认情况下,Amazon Redshift 会将授予 PUBLIC 组的权限授予所有用户。

  7. 找到用户拥有的所有对象,然后将所有权转让给其他用户或管理员:

    select ddl||'newuser;' as ddl from admin.v_find_dropuser_objs where objowner = 'username-to-be-dropped';

    上述命令的输出会列出将所有权转让给新用户必须使用的命令。

  8. 在 Amazon Redshift 集群的每个数据库中重复步骤 2-7。
    **注意:**要列出您的数据库,请运行 SHOW DATABASES 命令。

  9. 要从数据库中删除用户,请运行以下命令:

    drop user username-to-be-dropped;

删除群组

**注意:**删除群组之前,必须撤销该群组对对象的所有权限。

完成以下步骤:

  1. 找到授予该组的所有权限,然后撤销这些权限:

    select ddl from admin.v_generate_user_grant_revoke_ddl where ddltype='revoke' and grantee= 'group group-name';
  2. 在 Amazon Redshift 集群的每个数据库中重复步骤 1,以撤销该组在所有数据库中的权限。

  3. 要删除用户组,请运行 DROP GROUP 命令。

AWS 官方已更新 1 年前