背景
在多租戶場景或者其他場景下,很多時候需要主動清理一些用戶,本文將介紹PostgreSQL 下如何快速刪除一個用戶(role)。
具體方法
一般情況下直接執行 drop role xxx; 就可以把這個用戶刪除。但是很多時候會因爲用戶有依賴而報錯。
權限依賴
postgres=# create role test with login;
CREATE ROLE
postgres=# grant all on database postgres to test;
GRANT
postgres=# drop role test;
ERROR: role "test" cannot be dropped because some objects depend on it
DETAIL: privileges for database postgres
可以看出,因爲我們把數據庫postgres 的權限賦予了test 用戶,所以直接刪除的時候會報錯。面對這種情況,我們需要先將role 的權限所有的權限全部revoke 掉,如下:
postgres=# revoke all on database postgres from test;
REVOKE
postgres=# drop role test;
DROP ROLE
注意:需要把該用戶在所有數據庫具有權限的所有數據庫對象的(表,視圖,SEQUENCE)權限全部回收,才能刪除該用戶。
對象依賴
postgres=# create role test with login;
CREATE ROLE
postgres=# \c - test
You are now connected to database "postgres" as user "test".
postgres=> create table test (id int);
CREATE TABLE
postgres=# \c - postgres
You are now connected to database "postgres" as user "postgres".
postgres=# drop role test;
ERROR: role "test" cannot be dropped because some objects depend on it
DETAIL: owner of table test
可以看出,因爲test 用戶是test 表的owner,所以刪除的時候報錯owner of table test。如果不需要保留該對象,則需要先把該依賴對象刪除。如果需要保留該對象,則應該在刪除之前先把owner 賦予別人,如下:
postgres=# alter table test OWNER TO postgres;
ALTER TABLE
postgres=# drop role test;
DROP ROLE
注意:需要把該用戶在所有數據庫具有owner 權限的所有數據庫對象(表,視圖,SEQUENCE)刪除或者執行alter xx owner to,才能刪除該用戶。
更牛逼的方法
如果不保留owner 的數據庫對象
postgres=# REASSIGN OWNED BY test TO postgres;
REASSIGN OWNED
postgres=# DROP OWNED BY test;
DROP OWNED
postgres=# drop role test;
DROP ROLE
如果保留owner 的數據庫對象
postgres=# REASSIGN OWNED BY test TO postgres;
REASSIGN OWNED
postgres=# drop role test;
DROP ROLE
注意:REASSIGN OWNED 需要執行者所屬的role (或者子集)必須包含test 和postgres 或者是superuser。另外必須所有涉及到的數據庫上都執行該以上語句才能刪除用戶。