Gejala
Saat menghapus akun dari instans ApsaraDB RDS for PostgreSQL, muncul error.
-
Saat menghapus akun melalui Konsol ApsaraDB RDS, muncul pesan error.
Pesan error menunjukkan bahwa objek database bergantung pada akun tersebut dan akun hanya dapat dihapus setelah dependensi tersebut dihilangkan.
-
Kode error:
AccountActionForbidden.
-
Menjalankan pernyataan SQL untuk menghapus akun menghasilkan error berikut:
ERROR: role "<username>" cannot be dropped because some objects depend on it
Penyebab
Penghapusan akun akan gagal jika akun tersebut menjadi dasar ketergantungan objek database pada instans RDS.
Akun istimewa awal tidak dapat dihapus.
Solusi
Pemrosesan batch. Metode ini bersifat coarse-grained, ringkas, dan efisien. Jika menjalankan pernyataan SQL untuk menghapus akun menghasilkan error, Anda dapat mentransfer objek milik akun tersebut ke akun lain secara batch sesuai petunjuk, lalu mencabut semua izin dari akun yang ingin dihapus.
Pemrosesan fine-grained. Setiap izin dan objek transparan serta dapat dikontrol. Anda dapat mengkueri objek yang bergantung pada akun yang ingin dihapus dan menghapus objek tersebut satu per satu.
Pemrosesan batch
-
Konfirmasi objek dan izin milik akun yang ingin dihapus berdasarkan pesan error. Dalam contoh ini, contoh masalah digunakan.
DROP USER user_to_be_dropped; ERROR: role "user_to_be_dropped" cannot be dropped because some objects depend on it DETAIL: privileges for database testdb01 owner of database testdb02 privileges for membership of role testdbuser in role user_to_be_dropped_2 4 objects in database testdb01 2 objects in database testdb02Pesan error tersebut mengonfirmasi bahwa akun target
user_to_be_droppedmemiliki objek dependen di databasetestdb01dantestdb02. Secara spesifik:Di database testdb01, akun memiliki hak akses pada empat objek.
Akun merupakan Pemilik database testdb02.
-
Gunakan akun istimewa untuk login ke database yang disebutkan dalam pesan error, transfer objek milik akun yang ingin dihapus ke akun lain, lalu hapus izin atas objek tersebut dari akun yang ingin dihapus. Dalam contoh ini, akun testdbuser digunakan sebagai akun istimewa dan objek dialihkan ke akun tersebut.
-
Terhubung ke database
testdb01dan hapus objek yang dimiliki oleh akunuser_to_be_dropped.DROP OWNED BY user_to_be_dropped; -
Terhubung ke database
testdb02, alihkan kepemilikan ke akun lain, lalu hapus objek yang dimiliki oleh akunuser_to_be_dropped.-- Transfer kepemilikan database. REASSIGN OWNED BY user_to_be_dropped TO testdbuser; -- Hapus objek milik akun. DROP OWNED BY user_to_be_dropped;
-
Pemrosesan fine-grained
Langkah 1: Kueri objek dependen
Tabel sistem pg_shdepend mencatat dependensi objek database terhadap objek bersama, seperti role. Anda dapat mengkueri tabel ini untuk menemukan objek mana saja yang bergantung pada akun target. Misalnya, untuk menemukan objek yang bergantung pada akun user_to_be_dropped, lakukan langkah berikut:
-
Gunakan akun istimewa untuk terhubung ke instans database dan kueri objek yang terkait dengan akun
user_to_be_dropped.WITH role as (SELECT oid FROM pg_roles WHERE rolname = 'user_to_be_dropped') SELECT db.datname AS database, pg_class.relname AS classname, shp.objid AS oid, CASE WHEN shp.deptype = 'o' THEN 'Object Owner' WHEN shp.deptype = 'a' THEN 'In Access Control List' WHEN shp.deptype = 'r' THEN 'Policy Object' ELSE 'CANNOT HAPPEN' END FROM pg_shdepend shp LEFT JOIN pg_database db ON shp.dbid = db.oid JOIN pg_class ON shp.classid = pg_class.oid WHERE shp.refclassid = 1260 AND shp.refobjid IN (SELECT oid FROM role);Hasil berikut dikembalikan:
database | classname | oid | case ----------+-----------------+-------+------------------------ testdb01 | pg_namespace | 2200 | In Access Control List | pg_database | 16399 | In Access Control List testdb01 | pg_namespace | 16402 | Object Owner testdb01 | pg_class | 16403 | Object Owner testdb01 | pg_class | 16406 | Object Owner | pg_database | 16409 | Object Owner testdb02 | pg_namespace | 16410 | Object Owner testdb02 | pg_class | 16411 | Object Owner | pg_auth_members | 16416 | In Access Control ListTabel berikut menjelaskan bidang-bidang dalam hasil tersebut.
Bidang
Deskripsi
databaseDatabase tempat objek dependen berada. Jika bidang ini kosong, objek dependen merupakan objek global.
classnameNama tabel sistem.
oidIdentifier objek (OID) dari objek dependen.
caseJenis dependensi. Jenis dependensi umum berikut disediakan:
Owner: Akun yang ingin Anda hapus adalah pemilik objek tersebut.
ACL: Akun yang ingin Anda hapus ada dalam daftar kontrol akses (ACL).
-
Untuk setiap
oidyang dikembalikan pada langkah sebelumnya, gunakan akun istimewa untuk terhubung ke database yang sesuai dan kueri tabel sistem terkait untuk menemukan nama objeknya. Contohnya:-
Dependensi objek global
Nilai kosong pada bidang
databasemenunjukkan dependensi terhadap objek global.-
Untuk
oid=16399, daftar kontrol akses daritestdb01berisi entri untukuser_to_be_dropped.SELECT datname, datdba::regrole, datacl FROM pg_database WHERE oid = 16399; datname | datdba | datacl ----------+------------+------------------------------------------------------------------------------ testdb01 | testdbuser | {=Tc/testdbuser,testdbuser=CTc/testdbuser,user_to_be_dropped=CTc/testdbuser} (1 row) -
Untuk
oid=16409, pemiliktestdb02adalahuser_to_be_dropped.SELECT datname, datdba::regrole, datacl FROM pg_database WHERE oid = 16409; datname | datdba | datacl ----------+--------------------+-------- testdb02 | user_to_be_dropped | (1 row) -
Untuk
oid=16416, keanggotaan role dalampg_auth_membersmencatat izin yang diberikan oleh akunuser_to_be_dropped.SELECT oid, roleid::regrole, member::regrole, grantor::regrole FROM pg_auth_members WHERE oid = 16416; oid | roleid | member | grantor -------+----------------------+------------+-------------------- 16416 | user_to_be_dropped_2 | testdbuser | user_to_be_dropped (1 row)
-
-
Dependensi objek dalam satu database
Bidang
databaseyang tidak kosong menentukan database yang berisi objek dependen.-
Untuk
oid=2200, daftar kontrol akses daripublic schemaditestdb01berisi entri untukuser_to_be_dropped.SELECT nspname, nspowner::regrole, nspacl FROM pg_namespace WHERE oid = 2200; nspname | nspowner | nspacl ---------+------------+--------------------------------------------------------------------------- public | testdbuser | {testdbuser=UC/testdbuser,=U/testdbuser,user_to_be_dropped=UC/testdbuser} (1 row) -
Untuk
oid=16403, pemilik tabeltest_nsp.test_tblditestdb01adalahuser_to_be_dropped.SELECT relname, relnamespace::regnamespace, relowner::regrole, relacl FROM pg_class WHERE oid = 16403; relname | relnamespace | relowner | relacl ----------+--------------+--------------------+-------- test_tbl | test_nsp | user_to_be_dropped | (1 row)
-
-
Langkah 2: Tangani objek dependen
Anda dapat menggunakan metode berikut berdasarkan kebutuhan bisnis Anda:
Jika jenis dependensi adalah ACL, Anda dapat mencabut izin yang sesuai.
Jika jenis dependensi adalah Owner, Anda dapat mentransfer kepemilikan ke akun lain atau menghapus dependensi terhadap akun tersebut.
Contoh:
-
Dependensi tipe ACL
-
Untuk
oid=2200, cabut izin ataspublic schemaditestdb01.SELECT nspname, nspowner::regrole, nspacl FROM pg_namespace WHERE oid = 2200; nspname | nspowner | nspacl ---------+------------+--------------------------------------------------------------------------- public | testdbuser | {testdbuser=UC/testdbuser,=U/testdbuser,user_to_be_dropped=UC/testdbuser} (1 row) REVOKE ALL ON SCHEMA public FROM user_to_be_dropped; -
Untuk
oid=16399, cabut izin atas databasetestdb01.SELECT datname, datdba::regrole, datacl FROM pg_database WHERE oid = 16399; datname | datdba | datacl ----------+------------+------------------------------------------------------------------------------ testdb01 | testdbuser | {=Tc/testdbuser,testdbuser=CTc/testdbuser,user_to_be_dropped=CTc/testdbuser} (1 row) REVOKE ALL ON DATABASE testdb01 from user_to_be_dropped; -
oid=16416. Untuk ApsaraDB RDS for PostgreSQL 16 dan versi lebih baru, jika keanggotaan role terlibat, Anda harus beralih ke akunuser_to_be_droppeddan mencabut izin dari akun istimewa (misalnya, testdbuser) milikuser_to_be_dropped_2.\c testdb01 user_to_be_dropped; You are now connected to database "testdb01" as user "user_to_be_dropped". REVOKE user_to_be_dropped_2 FROM testdbuser cascade;
-
-
Dependensi tipe Owner
Login ke database tempat objek dependen berada menggunakan akun istimewa.
-
Transfer kepemilikan objek ke akun lain.
Untuk
oid=16403, transfer kepemilikan tabeltest_nsp.test_tblditestdb01ke akun lain (testdbuserdalam contoh ini).SELECT relname, relnamespace::regnamespace, relowner::regrole, relacl FROM pg_class WHERE oid = 16403; relname | relnamespace | relowner | relacl ----------+--------------+--------------------+-------- test_tbl | test_nsp | user_to_be_dropped | (1 row) ALTER TABLE test_nsp.test_tbl OWNER TO testdbuser; -
Hapus objek dependen
Hapus database testdb02.
DROP DATABASE testdb02;-
Hapus objek dengan
oid=16402.SELECT nspname, nspowner::regrole, nspacl FROM pg_namespace WHERE oid = 16402; nspname | nspowner | nspacl ----------+--------------------+-------- test_nsp | user_to_be_dropped | (1 row) DROP SCHEMA test_nsp cascade; -
Hapus objek dengan
oid=16406.SELECT relname, relnamespace::regnamespace, relowner::regrole, relacl FROM pg_class WHERE oid = 16406; relname | relnamespace | relowner | relacl ----------+--------------+--------------------+-------- test_tbl | public | user_to_be_dropped | (1 row) DROP TABLE public.test_tbl;
-
Hasil berikut dikembalikan:
database | classname | oid | case
----------+-----------+-----+------
(0 rows)
Langkah 3: Hapus akun
Hapus akun yang diperlukan melalui Konsol ApsaraDB RDS atau dengan menjalankan pernyataan SQL. Contoh pernyataan SQL:
DROP USER user_to_be_dropped;
Hapus akun
Hapus akun yang diperlukan melalui Konsol ApsaraDB RDS atau dengan menjalankan pernyataan SQL. Contoh pernyataan SQL:
DROP USER user_to_be_dropped;