关于删除role的一些理论
首先,删除用户不能使用DROP ROLE … CASCADE,不能级联删除用户。也就是不能删除依赖的对象。
因为角色可以拥有数据库对象,并且可以拥有访问其他数据库对象的权限,所以删除角色通常不仅是执行DROP role的问题。该角色拥有的任何对象必须先被删除或重新分配给其他角色;并且必须回收授予该角色的一切权限。
对象的所有权可以通过alter命令修改,如下:
ALTER TABLE bobs_table OWNER TO alice;
这里就该REASSIGN OWNED BY出场了,该命令可以把要被删除角色拥有的所有对象的所有权限重新分配给另一个角色。因为REASSIGN OWNED BY不能访问其他数据库中的对象,所以要在每个包含该角色所拥有对象的数据库中运行一遍。 当转移权限后,可以运行DROP OWNED BY命令,一旦需要转移的对象被转移给新的角色,任何要被删除的角色所拥有的剩余对象都可以使用DROP owned命令删除。同样,这个命令不能访问其他数据库中的对象,因此必须在包含该角色拥有的对象的每个数据库中运行它。此外,DROP OWNED不会删除整个数据库或表空间,所以要被的删除角色,如果还拥有相关数据库或表空间的权限,就必须手动处理。
REASSIGN OWNED BY doomed_role TO successor_role;
DROP OWNED BY doomed_role;
DROP ROLE doomed_role;
尝试删除数据库中的postgres角色
数据库中的postgres角色无法删除,因为该角色是数据库内部的引导角色object ID为10,该角色只能重命名。 如下,不能删除,可以重命名
postgres=
-[ RECORD 1 ]
rolname | postgres
rolsuper | t
rolinherit | t
rolcreaterole | t
rolcreatedb | t
rolcanlogin | t
rolreplication | t
rolconnlimit | -1
rolpassword | ********
rolvaliduntil |
rolbypassrls | t
rolconfig |
oid | 10
postgres=
ERROR: cannot drop role postgres because it is required by the database system
postgres=
ALTER ROLE
下面举一个删除用户的实例:
postgres=
CREATE ROLE
postgres=
CREATE ROLE
postgres=
psql (13.6, server 12.6)
You are now connected to database "postgres" as user "role01".
postgres=> create table role01_tbl (a int);
CREATE TABLE
postgres=> \c postgres role02
psql (13.6, server 12.6)
You are now connected to database "postgres" as user "role02".
postgres=> create table role02_tbl (a int);
CREATE TABLE
postgres=> \c hank hank
psql (13.6, server 12.6)
hank=> grant select on account to role01;
GRANT
hank=> \z account
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
hank | account | table | hank=arwdDxt/hank +| password: +|
| | | auditor=arwdDxt/hank+| auditor=r/hank |
| | | role01=r/hank | |
(1 row)
hank=> \c postgres postgres
psql (13.6, server 12.6)
You are now connected to database "postgres" as user "postgres".
postgres=
ERROR: role "role01" cannot be dropped because some objects depend on it
DETAIL: owner of table role01_tbl
1 object in database hank
postgres=
ERROR: role "role02" cannot be dropped because some objects depend on it
DETAIL: owner of table role02_tbl
postgres=
CREATE ROLE
postgres=
REASSIGN OWNED
postgres=
List of relations
Schema | Name | Type | Owner | Persistence | Size | Description
public | role01_tbl | table | role03 | permanent | 0 bytes |
postgres=
DROP OWNED
postgres=
psql (13.6, server 12.6)
You are now connected to database "hank" as user "hank".
hank=> \z hank.account
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
hank | account | table | hank=arwdDxt/hank +| password: +|
| | | auditor=arwdDxt/hank+| auditor=r/hank |
| | | role01=r/hank | |
(1 row)
hank=
REASSIGN OWNED
hank=
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
hank | account | table | hank=arwdDxt/hank +| password: +|
| | | auditor=arwdDxt/hank+| auditor=r/hank |
| | | role01=r/hank | |
hank=> \c hank postgres
psql (13.6, server 12.6)
You are now connected to database "hank" as user "postgres".
hank=
DROP OWNED
hank=
Access privileges
Schema | Name | Type | Access privileges | Column privileges | Policies
hank | account | table | hank=arwdDxt/hank +| password: +|
| | | auditor=arwdDxt/hank | auditor=r/hank |
(1 row)
hank=
ERROR: role "role01" cannot be dropped because some objects depend on it
DETAIL: privileges for database hank
postgres=
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges | Size | Tablespace | Description
hank | postgres | UTF8 | en_US.utf8 | en_US.utf8 | =Tc/postgres +| 639 MB | tbs_hank |
| | | | | postgres=CTc/postgres +| | |
| | | | | hank=C*T*c*/postgres +| | |
| | | | | role01=CTc/hank +| | |
| | | | | role03=CTc/hank | | |
hank=
hank=
DROP ROLE
hank=> select * from information_schema.table_privileges where grantee='role01';
-[ RECORD 1 ]
grantor | hank
grantee | role01
table_catalog | hank
table_schema | hank
table_name | account
privilege_type | SELECT
is_grantable | NO
with_hierarchy | YES
postgres=
List of relations
Schema | Name | Type | Owner
information_schema | column_privileges | view | postgres
information_schema | data_type_privileges | view | postgres
information_schema | routine_privileges | view | postgres
information_schema | table_privileges | view | postgres
information_schema | udt_privileges | view | postgres
information_schema | usage_privileges | view | postgres
可以通过以下链接,找出数据库对象的依赖关系
https://github.com/digoal/blog/blob/master/201607/20160725_01.md
另外如果觉的删除用户风险大,也可以通过其他方式控制要删除的用户,如:
- 修改用户的连接限制为0
postgres=
postgres=
FATAL: too many connections for role "role01"
Previous connection kept
- 不允许用户登陆
postgres=
postgres=
FATAL: role "role01" is not permitted to log in
Previous connection kept
- 将用户名重命名
postgres=
参考: https://www.cybertec-postgresql.com/en/drop-role-or-drop-user-postgresql/ https://www.postgresql.org/docs/current/sql-reassign-owned.html https://www.postgresql.org/docs/current/role-removal.html https://www.postgresql.org/docs/current/sql-drop-owned.html
|