導入: なぜ「DROP OWNED」が重要なのか
データベース運用において、退職やプロジェクト終了に伴うユーザー(ロール)の削除は頻繁に発生します。しかし、PostgreSQLでは「ロールが所有しているオブジェクトが存在する」場合、単純に DROP ROLE を実行してもエラーとなり削除できません。一つずつオブジェクトを特定して削除するのは非効率であり、権限の残骸(ゴミ)が残るリスクもあります。この課題を解決するのが、対象ロールの所有物を一括削除できる「DROP OWNED」コマンドです。
基礎知識: DROP OWNEDの仕組み
DROP OWNED は、指定したロールが現在のデータベース内で所有するすべてのオブジェクトを削除し、同時にそのロールに付与されていた権限も取り消します。
- DROP OWNED BY ロール名; で実行します。
- これを実行することで、後続の DROP ROLE をスムーズに行うための「クリーンアップ」が完了します。
- 依存関係がある場合は、CASCADE オプションを検討する必要があります。
実装/解決策: 安全な削除手順
実務では、いきなり実行するのではなく、まずは対象のロールが何を持っているか確認することが推奨されます。以下の手順で進めるのが最も安全です。
1. ロールの所有物を確認する。
2. DROP OWNED を実行して所有物と権限を削除する。
3. ロールを削除(DROP ROLE)する。
サンプルプログラム: 実行手順とコマンド例
以下のコードは、開発環境や本番環境のメンテナンス時に役立つ一連の流れです。
— 1. 対象ロールが所有するテーブルやスキーマを確認する(システムカタログを検索)
SELECT schemaname, tablename, tableowner
FROM pg_tables
WHERE tableowner = ‘target_user’;
— 2. 所有オブジェクトと権限をまとめて削除する
— CASCADEを付けると、依存するオブジェクトも連鎖的に削除されます
DROP OWNED BY target_user CASCADE;
— 3. (必要に応じて)他のデータベースでも同様の処理を行う
— 注: DROP OWNEDはデータベースごとのコマンドなので、複数DBにまたがる場合は接続先を切り替えて実行が必要です
— 4. 最後にロールを削除する
DROP ROLE target_user;
— コメント:
— DROP OWNEDは現在のデータベース内でのみ有効です。
— 共有オブジェクト(ロールそのものなど)は削除されませんが、
— データベース内の所有権と権限は綺麗にリセットされます。
応用・注意点: 現場で役立つ補足情報
実務において最も注意すべきは、「共有オブジェクト」と「データベース固有オブジェクト」の混同です。
- データベースを跨ぐ場合: DROP OWNED は接続しているデータベース内のオブジェクトしか削除しません。もし複数のデータベースでそのユーザーが活動していた場合、すべてのデータベースに接続して個別に DROP OWNED を実行する必要があります。
- CASCADEの危険性: CASCADE を使用すると、そのロールが作成したビューや、その権限に依存している他のオブジェクトまで削除される可能性があります。本番環境では、まず削除対象の一覧を前述のクエリで確認し、意図しないオブジェクトが含まれていないか必ずチェックしてください。
- 権限の残骸: DROP OWNED はロールが「所有者」であるものだけでなく、そのロールに対して「付与された権限」も削除します。これにより、ロール削除後に「権限エラーで動かない」といったトラブルを未然に防ぐことができます。
このコマンドを適切に使うことで、データベースのライフサイクル管理が非常にスムーズになります。ぜひ運用スクリプトの一部として組み込んでみてください。

コメント