Complete a 3 Question Survey and Earn a re:Post Badge
Help improve AWS Support Official channel in re:Post and share your experience - complete a quick three-question survey to earn a re:Post badge!
如何解决 Amazon Redshift 中的“无法删除用户”错误?
我无法在亚马逊 Redshift 中删除用户或群组。
简短描述
如果您试图在 Amazon Redshift 中删除用户,可能会看到以下错误消息之一:
- 错误:无法删除用户的“用户名”,因为某些对象依赖于它
- 错误:无法删除用户的“用户名”,因为该用户对某个对象具有权限
- 错误:无法删除用户的“用户名”,因为该用户拥有某些对象
如果您试图删除以下类型的用户,可能会出现以下错误:
- 拥有默认权限的所有者或目标用户。
- 任何对象(例如数据库、架构、表、视图、过程和库)的所有者。
- 拥有对象权限的用户。
要解决错误消息中提及的错误,请先移除用户权限。然后,转移对象所有权或移除对象的群组所有权。
**重要事项:**您必须撤销 Amazon Redshift 集群中所有数据库的用户和群组权限。
解决方法
安装脚本来创建视图
从 AWS Labs GitHub 存储库下载并安装 v_generate_user_grant_revoke_ddl.sql 和 v_find_dropuser_objs.sql 脚本。v_generate_user_grant_revoke_ddl.sql 和 v_find_dropuser_objs.sql 脚本在其定义中使用 admin 架构。如果您在 Amazon Redshift 集群上没有 admin 架构,请在现有架构中修改该定义。或者,创建 admin 架构。
如果视图定义出现任何列变化,则请先删除视图,再创建新视图和定义。如果您尝试在删除旧视图之前创建新视图,则会收到 not valid table 错误。
删除用户
完成以下步骤:
-
按用户搜索以查找所有您想要删除的已授予用户权限。然后,以其他用户的身份重新授予这些权限。最佳做法是让该用户成为超级用户:
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;
注意:要重新授予权限,您必须是对该对象拥有权限的用户。而且,您必须有权向其他用户授予权限。如果您没有授予权限,则可以以超级用户的身份重新授予这些权限。
-
找到向该用户授予的所有权限,然后撤销这些权限:
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;
上述查询会列出在删除用户之前必须撤消的该用户的权限。请先撤销这些权限,再执行下一步。
-
要检查访问控制列表 (ACL) 是否为空,请运行以下查询:
select * from pg_user where usename = '<username-to-be-dropped>'; select * from pg_default_acl where defacluser= <user-id>; select pg_get_iam_role_by_user('<user-name>');
要检索用户名和用户 ID,请在 PG_USER_INFO 表中找到 usename 和 usesysid 列条目。
**注意:**如果 PG\ _DEFAULT\ _ACL 表中存在用户条目,则无法删除该用户。 -
如果用户仍然拥有某些对象的权限,请检查该用户是否拥有 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;
-
(可选)如果该用户仍然拥有某些对象的权限,请确认该用户是否属于另一个群组。该用户可能拥有该组授予的权限。该用户拥有的权限也可能是授予给 PUBLIC 群组的。
要检查用户是否仍然拥有权限,请运行以下查询:select * from pg_user where usename = '<username-to-be-dropped>'; select * from pg_group;
在 pg\ _group 查询的输出中,检查 grolist 列中是否有列出用户的条目。如果用户属于另一个群组,则会列出他们的用户 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';
**注意:**将 objname 和 schemaname 替换为您的表和架构。默认情况下,授予 PUBLIC 群组的权限将授予给所有用户。
-
找到用户拥有的所有对象,然后将所有权转让给其他用户或管理员:
select ddl||'<newuser>;' as ddl from admin.v_find_dropuser_objs where objowner = '<username-to-be-dropped>';
上述命令的输出会列出将所有权转让给新用户所必须使用的命令。
-
在 Amazon Redshift 集群的每个数据库中重复步骤 2-7。
-
要从数据库中删除用户,请运行以下命令:
drop user <username-to-be-dropped>;
删除群组
**注意:**删除群组之前,必须撤销该群组对对象的所有权限。
完成以下步骤:
-
找到向该群组授予的所有权限,然后撤销这些权限:
select ddl from admin.v_generate_user_grant_revoke_ddl where ddltype='revoke' and grantee= 'group <group-name>';
-
在 Amazon Redshift 集群的每个数据库中重复步骤 2。确认已撤销该组在所有数据库中的权限。
-
要删除用户群组,请使用 DROP GROUP 命令。
