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

2 分钟阅读
0

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

概述

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

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

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

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

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

**重要事项:**您必须撤销 Amazon Redshift 集群中所有数据库的用户和群组权限。

解决方法

删除用户

**重要事项:**在删除用户之前,请撤消所有用户权限。然后,转移用户拥有的所有数据库对象的所有权。

  1. 从 AWS Labs GitHub 存储库下载并安装 v_generate_user_grant_revoke_ddl.sqlv_find_dropuser_objs.sql 脚本。这些脚本在 Amazon Redshift 中创建视图,用于接下来的两个步骤。

**注意:**v_generate_user_grant_revoke_ddl.sqlv_find_dropuser_objs.sql 脚本在其定义中使用 admin 架构。如果您没有在 Amazon Redshift 集群上创建 admin 架构,请在其他任意现有架构中创建这些视图。要在其他架构中创建这些视图,请修改定义或创建 admin 架构。如果视图定义出现任何列变化,请先删除视图,再创建新视图和定义。如果视图已经存在,并且您试图先创建新视图再删除旧视图,则会收到“表无效”的错误。

  1. 查找所有必须删除的用户授予的用户权限。然后,以其他用户的身份重新授予这些权限。最佳做法是让该用户成为超级用户
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;

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

  1. 找到向该用户授予的所有权限,然后撤销这些权限:
select ddl from v_generate_user_grant_revoke_ddl where ddltype='revoke' and (grantee='<username>' or grantor='<username>') order by objseq, grantseq desc;

**注意:**将 grantorgrantee 分别替换为可以授予和接收权限的用户名。

如果您的查询没有返回任何记录或者 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;

该查询列出了在删除用户之前必须撤销的该用户的权限。请先撤销这些权限,再执行下一步。

  1. 运行以下查询以检查是否存在任何空白的访问控制列表 (ACL):
select \* from pg\_user where usename = '<username-to-be-dropped>'; select \* from pg\_default\_acl where defacluser= <user-id>;

要检索用户名和用户 ID,请在 PG_USER 表中找到 usenameusesysid 列条目。
**注意:**如果 PG_DEFAULT_ACL 表中存在任何用户条目,则无法删除用户。

  1. 如果用户仍然拥有某些对象的权限,请检查该用户是否被授予 assumerole 权限。要确认这一点,请运行以下查询:
select pg\_get\_iam\_role\_by\_user('<user-name>');

如果您看到要删除的用户具有 assumerole 权限,请使用以下命令将其撤销:

revoke assumerole on all from <user-name> for all;
  1. (可选)如果要删除的用户仍然拥有某些对象的权限,请确认该用户是否属于另一个群组。该用户可能拥有该组授予的权限。该用户拥有的权限也可能是授予给 PUBLIC 群组或所有用户的。

要确认用户是否仍然拥有权限,请运行以下查询:

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

在第二个查询的输出中,检查 grolist 列。验证是否有条目列出了要删除的用户。如果要删除的用户属于另一个群组,则会列出用户 ID。

如果您的 grolist 列显示该用户属于某个群组,请检查向该群组授予的权限:

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 替换为各自的表和架构。

**注意:**默认情况下,授予 PUBLIC 群组的权限将授予给所有用户。

  1. 找到该用户拥有的所有对象,然后将您要删除的用户的所有权转移给其他用户或管理员:
select ddl||'<newuser>;' as ddl from admin.v_find_dropuser_objs where objowner = '<username-to-be-dropped>';

此输出结果列出了可用于将所有权转移给新用户的命令。确保运行列出的命令。

  1. 在 Amazon Redshift 集群的每个数据库中重复步骤 2-7。

  2. 使用 DROP USER 命令从数据库中删除用户:

drop user <username-to-be-dropped>;

删除群组

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

  1. 从 AWS Labs GitHub 存储库下载并安装 v_generate_user_grant_revoke_ddl.sqlv_find_dropuser_objs.sql 脚本。这些脚本在 Amazon Redshift 中创建视图,用于下一个步骤。

**注意:**v_generate_user_grant_revoke_ddl.sqlv_find_dropuser_objs.sql 脚本在其定义中使用 admin 架构。如果您没有在 Amazon Redshift 集群上创建 admin 架构,那么可以在其他任意现有架构中创建这些视图。要在其他架构中创建这些视图,请修改定义或创建 admin 架构

  1. 找到向该群组授予的所有权限,然后将其撤销,如以下示例所示:
select ddl from admin.v_generate_user_grant_revoke_ddl where ddltype='revoke' and grantee= 'group <group-name>';
  1. 在 Amazon Redshift 集群的每个数据库中重复步骤 2。确认已撤销该组在所有数据库中的权限。

  2. 使用 DROP GROUP 命令删除用户群组。

相关信息

“删除用户”使用注意事项

“删除群组”示例

AWS 官方
AWS 官方已更新 7 个月前