我無法在 Amazon Redshift 中刪除使用者或群組。
簡短說明
當您嘗試在 Amazon Redshift 中捨棄使用者時,可能會看到以下其中一個錯誤訊息:
- ERROR: user "username" cannot be dropped because some objects depend on it
- 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 叢集中的所有資料庫撤銷使用者和群組權限。若要檢視叢集中的資料庫清單,請執行 SHOW DATABASES 命令。若要檢視您登入的資料庫名稱,請執行 CURRENT_DATABASE 命令。
解決方法
安裝指令碼以建立檢視
以超級使用者身分,從 GitHub 網站上的 AWS 實驗室儲存庫下載並安裝 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 錯誤。
捨棄使用者
完成以下步驟:
-
開啟query editor v2 (查詢編輯器 v2)。然後,搜尋您要捨棄的使用者,以檢視授予的使用者權限。
-
若要將權限重新授予其他使用者,請執行以下命令:
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 username = 'username-to-be-dropped';
select * from pg_default_acl where defacluser= user-id;
select pg_get_iam_role_by_user('user-name');
**注意:**將 username-to-be-dropped 和 user-name 替換為您的值。若要擷取使用者名稱和使用者 ID,請在 PG_USER_INFO 資料表中尋找 username 和 usesysid 欄項目。如果 PG_DEFAULT_ACL 資料表中有使用者項目,則您無法捨棄該使用者。
-
如果使用者仍對物件具有權限,請檢查使用者是否具有 assumerole 權限:
select pg_get_iam_role_by_user('user-name');
如果使用者具有 assumerole 權限,請先從 public 撤銷 assumerole。然後,執行以下命令以撤銷 username:
revoke assumerole on all from public for all;
revoke assumerole on all from user-name for all;
-
(選用) 如果使用者仍對某些物件具有權限,請檢查使用者是否屬於其他群組。使用者可能擁有從該群組授予的權限。或者,使用者可能擁有授予 PUBLIC 群組的權限。
若要檢查使用者仍具有的權限,請執行以下查詢:
select * from pg_user where username = 'username-to-be-dropped';
select * from pg_group;
在 pg_group 查詢的輸出中,檢查是否有在 grolist 欄中列出該使用者的項目。如果使用者屬於其他群組,則 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 替換為您的資料表和結構描述。根據預設,Amazon Redshift 會將授予 PUBLIC 群組的權限授予所有使用者。
-
尋找使用者擁有的所有物件,然後將擁有權轉移給不同的使用者或管理員:
select ddl||'newuser;' as ddl from admin.v_find_dropuser_objs where objowner = 'username-to-be-dropped';
前述命令的輸出會列出您必須用來將擁有權轉移給新使用者的命令。
-
在 Amazon Redshift 叢集上的每個資料庫中重複步驟 2-7。
**注意:**若要列出資料庫,請執行 SHOW DATABASES 命令。
-
若要從資料庫移除使用者,請執行以下命令:
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 叢集上的每個資料庫中重複步驟 1,以撤銷所有資料庫中的群組權限。
-
若要移除使用者群組,請執行 DROP GROUP 命令。