如何解决 Amazon Redshift 中的“无法删除用户”错误?
上次更新时间:2020 年 12 月 23 日
我无法删除 Amazon Redshift 中的用户或组。如何解决此问题?
简短描述
当您尝试在 Amazon Redshift 中删除用户或组时,您可能会遇到以下错误消息之一:
ERROR: user 'username' cannot be dropped because the user has a privilege on some object
ERROR: user 'username' cannot be dropped because the user owns some object
要解决此错误消息,您首先必须删除所有用户权限,然后转移对象的所有权,或删除对象的组所有权。
注意:您必须撤销 Amazon Redshift 集群中的所有数据库的用户和组权限。
解决方法
删除用户
重要提示:在删除用户前,您必须首先撤销一切用户权限。然后转移该用户拥有的任何数据库对象的所有权。
1. 从 AWSLabs GitHub 存储库下载并安装 v_generate_user_grant_revoke_ddl.sql 脚本。v_generate_user_grant_revoke_ddl.sql 脚本将在 Amazon Redshift 中创建一个视图,此视图对接下来的两个步骤将很有用处。
注意:v_generate_user_grant_revoke_ddl.sql 和 v_find_dropuser_objs.sql 脚本的视图在其定义中使用管理员 schema。如果您没有在 Amazon Redshift 集群上创建管理员 schema,您可以在其他现有的 schema 中创建这些视图。要在其他 schema 中创建这些视图,请修改定义或创建管理员 schema。
2. 查找要删除的所有授予的用户权限,然后将这些权限重新授予给另一个用户:
select regexp_replace(ddl,grantor,'aws') from admin.v_generate_user_grant_revoke_ddl where grantor='aws' and ddltype='grant' and objtype <>'default acl' order by objseq,grantseq;
注意:重新授予权限的用户必须是对该对象拥有权限的用户。此用户还必须能够将权限授予其他用户。如果没有任何其他用户具有重新授予权限的权限,您可以以超级用户身份来重新授予这些权限。
3. 查找授予用户的所有权限,然后撤销这些权限:
select ddl from admin.v_generate_user_grant_revoke_ddl where ddltype='revoke' and (grantee='testuser1' or grantor='aws') order by objseq, grantseq desc;
确保将“grantor”和“grantee”分别替换为可以授予权限和接受权限的用户名。
4. 运行以下查询,以检查是否有任何空的访问控制列表 (ACL):
select * from pg_user where usename = 'testuser1';
select * from pg_default_acl where defacluser= 108;
注意:要删除用户,PG_DEFAULT_ACL 表中不能有任何用户条目。
5. (可选)如果查询为用户返回条目,则再次运行 revoke 命令:
select ddl from admin.v_generate_user_grant_revoke_ddl where ddltype='revoke' and (grantee='testuser1' or grantor='aws') order by objseq, grantseq desc;
确认授予用户的所有权限是否已撤销:
select * from pg_user where usename = 'testuser1';
select * from pg_group;
在查询的输出中,检查 grolist 列以验证用户 (testuser1) 是否属于任何其他组。
6. (可选)如果 grolist 列表表明 testuser1 是组的一部分,请检查授予该组的权限:
select ddl from admin.v_generate_user_grant_revoke_ddl where ddltype='revoke' and (grantee='group-name') order by objseq, grantseq desc;
7. (可选)如果 PG_DEFAULT_ACL 表仍显示条目,请检查是否已向 PUBLIC 组授予任何权限:
select * from admin.v_generate_user_grant_revoke_ddl where objname='timecards' and schemaname='postgres' and grantee='PUBLIC' and ddltype='revoke';
确保将 objname 和 schemaname 替换为各自的表和 schema。
注意:默认情况下,授予 PUBLIC 组的权限将授予所有用户。
8. 查找用户拥有的所有对象,然后将所有权从被删除的用户转移至其他用户或管理员。在以下示例中,当前拥有者为 username,新拥有者为 newuser:
select ddl||'<newuser>;' as ddl from admin.v_find_dropuser_objs where objowner = 'testuser1';
9. 为 Amazon Redshift 集群中的每个数据库重复第 2-8 步。
10. 使用 DROP USER 命令从数据库中删除该用户:
drop user testuser1;
删除组
删除组之前,您必须首先撤销该组拥有的一切对象相关权限。
1. 从 AWSLabs GitHub 存储库下载并安装 v_generate_user_grant_revoke_ddl.sql 和 v_find_dropuser_objs.sql 脚本。此脚本将在 Amazon Redshift 中创建一个视图,此视图对下一步将很有用处。
注意:v_generate_user_grant_revoke_ddl.sql 和 v_find_dropuser_objs.sql 脚本的视图在其定义中使用管理员 schema。如果您没有在 Amazon Redshift 集群上创建管理员 schema,您可以在其他现有的模式中创建这些视图。要在其他 schema 中创建这些视图,请修改定义或创建管理员 schema。
2. 查找授予该组的所有权限,然后撤销这些权限,如下例所示:
select ddl from admin.v_generate_user_grant_revoke_ddl where ddltype='revoke' and username='<groupname>' order by sequence;
3. 为 Amazon Redshift 集群中的每个数据库重复第 2 步,确认已在所有数据库中撤消该组的权限。
4. 使用 DROP GROUP 命令删除用户组。