このトピックでは、DROP USER 文を使用して Hologres のアカウントを削除する方法と、アカウントの削除時に発生する可能性のあるエラーのトラブルシューティング方法について説明します。
背景情報
日々のビジネス運用において、アカウントを削除する必要がある場合があります。Hologres では、データベース、スキーマ、テーブル、ビューなどのオブジェクトのオーナーであるアカウントを削除しようとすると、エラーが発生します。一般的なエラーは次のとおりです。
アカウントがオブジェクトを所有している場合、次のエラーが返されます。
ERROR: role "<uid>" cannot be dropped because some objects depend on it DETAIL: owner of table xxx owner of schema yyy他のオブジェクトがアカウントに依存している場合、次のエラーが返されます。
ERROR: role "<uid>" cannot be dropped because some objects depend on it DETAIL: 1 object in database xxxアカウントがオブジェクトに対する権限を持っている場合、次のエラーが返されます。
ERROR: role "<uid>" cannot be dropped because some objects depend on it Detail: privileges for table xxx privileges for table yyy
これらのエラーは、削除しようとしているアカウントが、インスタンス内のデータベース、スキーマ、ビュー、テーブルなどのオブジェクトに依存しているか、またはそれらのオブジェクトに対する権限を持っているために発生します。そのため、アカウントを直接削除することはできません。
アカウント削除理由の特定
アカウントを削除する前に、その理由を特定してください。一般的な理由には、次のようなものがあります。
理由 1:アカウントの権限付与が不正確で、正しい権限を付与するためにアカウントを削除したい。
理由 2:アカウントのオーナーが退職した、アカウントが使用されなくなった、またはその他のビジネス上の理由でアカウントを削除する必要がある。
推奨されるソリューションは次のとおりです。
アカウント削除の理由は理由 1 です。
このシナリオでは、アカウントを削除する必要はありません。代わりに、現在の権限を取り消してから、新しい権限を付与できます。
標準権限モデルを使用して権限を取り消し、新しい権限を付与するには、「標準権限モデル」をご参照ください。
簡易権限モデルを使用して権限を取り消し、新しい権限を付与するには、「簡易権限モデルの使用」および「スキーマレベルの簡易権限モデルの使用」をご参照ください。
アカウントが誤って一般ユーザとして作成され、スーパーユーザに変更したい場合は、次の文を実行します。
-- RAM ユーザーの場合、uid を p4_id に変更します。 alter user "<uid>" superuser;uid はアカウント ID です。詳細については、「アカウント ID」をご参照ください。
アカウントが誤ってスーパーユーザとして作成され、一般ユーザに変更したい場合は、次の文を実行します。
説明スーパーユーザを一般ユーザに変更した後、そのユーザーには権限がありません。必要な権限をユーザーに付与する必要があります。
-- RAM ユーザーの場合、uid を p4_id に変更します。 alter user "<uid>" nosuperuser;uid はアカウント ID です。詳細については、「アカウント ID」をご参照ください。
アカウントは理由 2 により削除されました。
アカウントが所有するオブジェクトを保持するには、オブジェクトの所有権を別のユーザーに転送してからアカウントを削除します。詳細については、「オブジェクトを保持したままアカウントを削除」をご参照ください。
オブジェクトを保持したままアカウントを削除
アカウントを削除しつつ、そのアカウントが所有するテーブル、ビュー、関数などのオブジェクトを保持したい場合は、オブジェクトの所有権を別のユーザーに転送してからアカウントを削除できます。次のコマンドを使用します。
オブジェクトの所有権を別のユーザーに転送します。
REASSIGN OWNED BY "<uid>" TO "<Another_uid>" ;uid はアカウント ID です。詳細については、「アカウント ID」をご参照ください。
アカウントを削除します。
DROP USER "<uid>";
アカウントの依存関係の表示
次の文を実行して、アカウントの依存オブジェクトを表示します。
select 'select * from ' || s.classid::regclass || ' where oid = ' || s.objid || '; (Execute in the ' || d.datname || ' DB)' as "Query dependent objects", case when deptype = 'a' then 'Permission dependency' when deptype = 'o' then 'Owner dependency' else deptype::text end as "Dependency type"from pg_shdepend s join pg_database d on (s.dbid = d.oid) join pg_roles r on (r.oid = s.refobjid) where datname = current_database() and refclassid = 1260 and r.rolname = '<username>';すべてのテーブル、ビュー、および外部テーブルのオーナーを表示します。
SELECT n.nspname AS "Schema", c.relname AS "Name", CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN 'materialized view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 's' THEN 'special' WHEN 't' THEN 'TOAST table' WHEN 'f' THEN 'foreign table' WHEN 'p' THEN 'partitioned table' WHEN 'I' THEN 'partitioned index' END AS "Type", pg_catalog.pg_get_userbyid(c.relowner) AS "Owner", pg_catalog.obj_description(c.oid,'pg_class') AS "Description" FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('r', 'p', 't', 'v', 'm', 'S', 's', 'f', '') AND pg_catalog.pg_table_is_visible(c.oid);特定のユーザーが所有するテーブル、ビュー、および外部テーブルを表示します。
SELECT n.nspname AS "Schema", c.relname AS "Name", CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' WHEN 'm' THEN 'materialized view' WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 's' THEN 'special' WHEN 't' THEN 'TOAST table' WHEN 'f' THEN 'foreign table' WHEN 'p' THEN 'partitioned table' WHEN 'I' THEN 'partitioned index' END AS "Type", pg_catalog.pg_get_userbyid(c.relowner) AS "Owner", pg_catalog.obj_description(c.oid, 'pg_class') AS "Description" FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relkind IN ('r', 'p', 't', 'v', 'm', 'S', 's', 'f', '') AND pg_catalog.pg_table_is_visible(c.oid) AND pg_catalog.pg_get_userbyid(c.relowner) ='<user_name>';オーナーを変更します。
-- テーブルのオーナーを変更します。 ALTER TABLE schema_name.table_name OWNER TO new_owner; -- 外部テーブルのオーナーを変更します。 ALTER FOREIGN TABLE schema_name.foreign_table_name OWNER TO new_owner; -- ビューのオーナーを変更します。 ALTER VIEW schema_name.view_name OWNER TO new_owner;スキーマのオーナーを表示します。
すべてのスキーマのオーナーを表示します。
SELECT n.nspname AS "Name", pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner", pg_catalog.array_to_string(n.nspacl, E'\n') AS "Access privileges", pg_catalog.obj_description(n.oid, 'pg_namespace') AS "Description" FROM pg_catalog.pg_namespace n ORDER BY 1;特定のユーザーが所有するスキーマを表示します。
SELECT n.nspname AS "Name", pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner", pg_catalog.array_to_string(n.nspacl, E'\n') AS "Access privileges", pg_catalog.obj_description(n.oid, 'pg_namespace') AS "Description" FROM pg_catalog.pg_namespace n WHERE pg_catalog.pg_get_userbyid(n.nspowner) ='<user_name>';オーナーを変更します。
-- スキーマのオーナーを変更します。 ALTER SCHEMA schema_name OWNER TO new_owner;
サーバーのオーナーを表示します。
すべてのサーバーのオーナーを表示します。
SELECT s.srvname AS "Name", pg_catalog.pg_get_userbyid(s.srvowner) AS "Owner", f.fdwname AS "Foreign-data wrapper", pg_catalog.array_to_string(s.srvacl, E'\n') AS "Access privileges", s.srvtype AS "Type", s.srvversion AS "Version", CASE WHEN srvoptions IS NULL THEN '' ELSE '(' || pg_catalog.array_to_string(ARRAY ( SELECT pg_catalog.quote_ident(option_name) || ' ' || pg_catalog.quote_literal(option_value) FROM pg_catalog.pg_options_to_table(srvoptions)), ', ') || ')' END AS "FDW options", d.description AS "Description" FROM pg_catalog.pg_foreign_server s JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid = s.srvfdw LEFT JOIN pg_catalog.pg_description d ON d.classoid = s.tableoid AND d.objoid = s.oid AND d.objsubid = 0;特定のユーザーが所有するサーバーを表示します。
SELECT s.srvname AS "Name", pg_catalog.pg_get_userbyid(s.srvowner) AS "Owner", f.fdwname AS "Foreign-data wrapper", pg_catalog.array_to_string(s.srvacl, E'\n') AS "Access privileges", s.srvtype AS "Type", s.srvversion AS "Version", CASE WHEN srvoptions IS NULL THEN '' ELSE '(' || pg_catalog.array_to_string(ARRAY ( SELECT pg_catalog.quote_ident(option_name) || ' ' || pg_catalog.quote_literal(option_value) FROM pg_catalog.pg_options_to_table(srvoptions)), ', ') || ')' END AS "FDW options", d.description AS "Description" FROM pg_catalog.pg_foreign_server s JOIN pg_catalog.pg_foreign_data_wrapper f ON f.oid = s.srvfdw LEFT JOIN pg_catalog.pg_description d ON d.classoid = s.tableoid AND d.objoid = s.oid AND d.objsubid = 0 WHERE pg_catalog.pg_get_userbyid(s.srvowner) = '<user_name>';オーナーを変更します。
-- サーバーのオーナーを変更します。 ALTER SERVER server_name OWNER TO new_owner;
ユーザーマッピングのオーナーを表示します。
すべてのユーザーマッピングのオーナーを表示します。
SELECT um.srvname AS "Server", um.usename AS "User name", CASE WHEN umoptions IS NULL THEN '' ELSE '(' || pg_catalog.array_to_string(ARRAY ( SELECT pg_catalog.quote_ident(option_name) || ' ' || pg_catalog.quote_literal(option_value) FROM pg_catalog.pg_options_to_table(umoptions)), ', ') || ')' END AS "FDW options" FROM pg_catalog.pg_user_mappings um;特定のユーザーが所有するユーザーマッピングを表示します。
SELECT um.srvname AS "Server", um.usename AS "User name", CASE WHEN umoptions IS NULL THEN '' ELSE '(' || pg_catalog.array_to_string(ARRAY ( SELECT pg_catalog.quote_ident(option_name) || ' ' || pg_catalog.quote_literal(option_value) FROM pg_catalog.pg_options_to_table(umoptions)), ', ') || ')' END AS "FDW options" FROM pg_catalog.pg_user_mappings um WHERE um.usename = '<user_name>';ユーザーマッピングを削除します。
-- ユーザーマッピングを削除します。 DROP USER MAPPING FOR user_name SERVER server_name;