为什么无法在 RDS for PostgreSQL 数据库实例中删除用户或角色?

2 分钟阅读
0

当我尝试在 Amazon Relational Database Service (Amazon RDS) for PostgreSQL 实例中删除用户或角色时,出现错误“角色无法删除,因为某些对象依赖于此角色”。

简短描述

当 RDS for PostgreSQL 中的用户或角色创建对象(如表或架构)时,该用户或角色即为所创建对象的所有者。如果您试图删除在任何数据库中拥有一个或多个对象或对这些对象具有权限的用户或角色,则会收到错误,指示存在依赖于该用户或角色的对象以及授予的权限(如有)。

要删除具有依赖对象的用户或角色,必须执行以下操作:

  1. 将这些对象的所有权重新分配给其他用户。
  2. 撤消授予用户或角色的任何权限。

**注意:**如果不再需要这些对象,请考虑先删除这些对象,然后删除角色。可以使用 DROP OWNED 命令删除数据库中角色拥有的所有对象。您还可以撤消授予该角色对该数据库中的对象或共享对象的任何权限。DROP OWNED 命令成功运行后,可以删除角色。

解决方法

在以下示例中,使用了三种不同的数据库角色:

  • test_user:这是必须删除的用户或角色。
  • admin_user:这是用于删除所需用户或角色的角色。该用户是 RDS 中权限最高的用户,附带 rds_superuser 角色。
  • another_user:这是分配到 test_user 拥有的对象所有权的用户或角色。

运行以下命令以查看您登录的角色:

pg_example=> SELECT current_user;

输出与以下内容类似:

current_user
--------------
 admin_user
(1 row)

当您尝试删除具有依赖对象的用户或角色时,会出现类似于以下错误:

pg_example=> DROP ROLE test_user;
ERROR:  role "test_user" cannot be dropped because some objects depend on it
DETAIL:  privileges for database pg_example
owner of table test_table
owner of schema test_schema
owner of sequence test_schema.test_seq
privileges for table test_t2

在此示例中,要删除的角色是 test_user。请注意,当前登录的角色是 admin_user,是数据库的主用户。

从错误消息中,您可以获得以下信息:

  • 角色 test_user 拥有对数据库 pg_example 和表 test_t2 授予的权限。
  • 角色 test_user 拥有表 test_table、架构 test_schematest_schema 中的序列对象 test_seq

**注意:**如果在连接到其他数据库时删除用户或角色,则会得到类似于以下内容的输出:

pg_another_db=> DROP ROLE test_user;
ERROR:  role "test_user" cannot be dropped because some objects depend on it
DETAIL:  privileges for database pg_example
4 objects in database pg_example

要查看用户或角色拥有的对象,请确保连接到拥有的对象所在的数据库。

要删除用户或角色,必须将所拥有对象的所有权重新分配给另一个用户或角色,并撤消关联的权限。您可以使用 PostgreSQL REASSIGN OWNED 命令将这些对象的所有权重新分配给其他用户。运行此命令可能会出现类似以下内容的错误:

pg_example=> select current_user;
 current_user
--------------
 test_user
pg_example=> REASSIGN OWNED BY test_user TO another_user;
ERROR:  permission denied to reassign objects

要解决此问题,必须将用户或角色授予正在重新分配所有权的用户。您不能使用 test_user 来执行此操作,因为 test_user 不是 another_user 的所有者。因此,您可能会看到类似于以下内容的错误:

pg_example=> select current_user;
 current_user
--------------
 test_user
pg_example=> grant another_user to test_user;
ERROR:  must have admin option on role "another_user"

您可以执行以下任一操作,将用户或角色授予正在重新分配所有权的用户:

  • 登录主用户并运行 GRANT 命令:
pg_example=> select current_user;
 current_user
--------------
 admin_user
pg_example=> GRANT another_user TO test_user;
GRANT ROLE
  • 登录将重新分配所有权的用户并运行 GRANT 命令:
pg_example=> select current_user;
 current_user
--------------
 another_user
pg_example=> GRANT another_user TO test_user;
GRANT ROLE

选择上述选项之一后,在登录 test_user 之后,将 test_user 拥有的对象的所有权重新分配给 another_user

pg_example=> select current_user;
 current_user
--------------
 test_user
pg_example=> reassign owned by test_user to another_user;
REASSIGN OWNED

如果登录主用户并尝试删除仍具有现有权限的 test_user,则可能会出现类似以下内容的错误:

pg_example=> select current_user;
 current_user
--------------
 admin_user
pg_example=> DROP ROLE test_user;
ERROR:  role "test_user" cannot be dropped because some objects depend on it
DETAIL:  privileges for database pg_example
privileges for table test_t2

在这种情况下,即使 REASSIGN 命令成功,也会出现错误。这是因为,必须撤消 test_user 的权限。运行 REVOKE 命令从 test_user 具有权限的任何对象中撤消所有使用权限。在本例中,为 test_user 撤消对数据库 pg_example 和表 test_t2 的权限。

pg_example=> REVOKE ALL ON TABLE test_t2 FROM test_user;
REVOKE
pg_example=> REVOKE ALL ON DATABASE pg_example FROM test_user;
REVOKE

然后,删除用户 test_user

pg_example=> DROP ROLE test_user;
DROP ROLE

撤销特权后,可以成功删除角色。


相关信息

DROP ROLE 的 PostgreSQL 文档

AWS 官方
AWS 官方已更新 2 年前