「psqlで\duコマンドを打っても、どのロールに何の権限があるのかよく分からない」
PostgreSQLのロール管理は、MySQLのユーザー管理とは設計思想が違うため、初めて触ると戸惑いやすいポイントが多いです。
この記事では、Linux上のPostgreSQLサーバーでpostgresユーザーへの切り替え・psqlへの接続・ロール作成・権限付与・権限確認・よくあるエラー対処を一通り解説します。RHEL 9系 / Rocky Linux 9 / Ubuntu 24.04 LTSで動作確認した手順です。
この記事のポイント
・psql接続は「su - postgres → psql」の2ステップが基本
・CREATE ROLE 名前 WITH LOGIN PASSWORD でアプリ用ロールを作る
・権限付与はCONNECT→USAGE→テーブル権限の3段階で行う
・PostgreSQL 15以降はpublicスキーマのデフォルトCREATE権限が変わった
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
PostgreSQLのロールとユーザーは同じもの
PostgreSQLには「ユーザー」と「ロール」の2つの概念がありますが、内部的にはどちらも同じROLEオブジェクトです。違いはログイン権限(WITH LOGIN)を持つかどうかだけです。・CREATE ROLE name:ログイン不可のロール(グループロールとして使う)
・CREATE ROLE name WITH LOGIN:ログイン可能なロール(実質的なユーザー)
・CREATE USER name:WITH LOGINつきのCREATE ROLEと同義(歴史的互換コマンド)
古いコマンドの
CREATE USERも動きますが、PostgreSQLの公式ドキュメントはCREATE ROLEに統一する方向で記述しています。現場でもCREATE ROLE ... WITH LOGINを使う習慣をつけておくと、後からロールをグループとして再利用しやすくなります。postgresユーザーへの切り替えとpsqlへの接続
PostgreSQLをインストールすると、OSユーザーpostgresとデータベースロールpostgresが自動的に作成されます。初期設定や管理操作は、このOSユーザー経由でpsqlに入るのが基本です。1. su - postgres でOSユーザーを切り替える
rootまたはsudo権限のあるユーザーで以下を実行します。# OSユーザーをpostgresに切り替える su - postgres # sudoが使える環境はこちらでも可 sudo -i -u postgres
su -の-は「ログインシェルとして切り替える」意味で、環境変数(HOMEやPATH)がpostgresユーザーのものに切り替わります。-を省略するとPATHが引き継がれず、psql: command not foundになるケースがあるため注意してください。2. psqlコマンドで接続する
# postgresOSユーザーからの場合(引数なしで接続可) psql # ユーザー名・DB名を明示して接続する psql -U postgres -d postgres # ホスト・ポートを指定してTCP接続する psql -U postgres -h 127.0.0.1 -p 5432 -d postgres
psqlは「OSユーザー名と同名のロールで、同名のデータベースに接続する」動作をします。postgresOSユーザーから実行すれば、ロールpostgresでデータベースpostgresに接続されます。3. 基本メタコマンド(\l・\du・\c・\q)
psqlのプロンプト(postgres=#)に入ったら、まず以下のメタコマンドを覚えてください。・\l:データベース一覧を表示
・\du:ロール一覧を表示
・\c dbname:接続するデータベースを切り替える
・\dn:スキーマ一覧を表示
・\dt:現在のDBのテーブル一覧を表示
・\q:psqlを終了する
ロールの作成と削除
1. CREATE ROLEでロールを作成する
以下は、アプリケーション用のロールwebappを作成する例です。-- ログイン可能なロール(パスワード付き) CREATE ROLE webapp WITH LOGIN PASSWORD 'StrongPass123!'; -- ログイン不可のグループロール CREATE ROLE readonly_group; -- 既存ロールをグループロールのメンバーに追加 GRANT readonly_group TO webapp;
2. \duでロール一覧を確認する
作成後は\duで状態を確認します。以下は実際の出力例です。postgres=# \du List of roles Role name | Attributes | Member of ----------------+------------------------------------------------------------+----------- postgres | Superuser, Create role, Create DB, Replication, Bypass RLS | {} readonly_group | Cannot login | {} webapp | | {readonly_group}
postgresロールがスーパーユーザー権限を持ち、webappのAttributes列が空欄(ログイン可・一般権限)でreadonly_groupのメンバーになっていることが確認できます。ロールのログイン可否をSQL側で確認したい場合は
pg_rolesビューを使います。SELECT rolname, rolcanlogin, rolsuper FROM pg_roles ORDER BY rolname;
3. DROP ROLEでロールを削除する
-- ロールを削除する(オブジェクトを所有している場合はエラー) DROP ROLE webapp; -- 存在チェック付き(スクリプト向け) DROP ROLE IF EXISTS webapp;
REASSIGN OWNED BY webapp TO postgres;で所有権を別ロールに移してから削除します。データベースの作成とオーナー設定
1. CREATE DATABASEでデータベースを作成する
-- 基本的な作成(オーナーはpostgres) CREATE DATABASE myappdb; -- オーナーを指定して作成する CREATE DATABASE myappdb OWNER webapp; -- 文字コードとロケールを指定して作成する(日本語環境向け) CREATE DATABASE myappdb OWNER webapp ENCODING 'UTF8' LC_COLLATE 'ja_JP.UTF-8' LC_CTYPE 'ja_JP.UTF-8' TEMPLATE template0;
LC_COLLATEとLC_CTYPEにja_JP.UTF-8を指定し、TEMPLATE template0でクリーンなベースから作成するのが定石です。template1(デフォルト)はすでにロケール設定が焼き込まれているため、異なるロケールを指定するとエラーになります。2. オーナーを後から変更する
ALTER DATABASE myappdb OWNER TO webapp;
\lコマンドでOwner列を確認して変更が反映されているかチェックします。GRANT・REVOKEで権限を付与・剥奪する
PostgreSQLの権限付与は3段階の階層構造で行います。この順番を守らないとpermission deniedエラーになります。1. 段階的なGRANTの手順(3ステップ)
-- Step 1: データベースへの接続権限 GRANT CONNECT ON DATABASE myappdb TO webapp; -- Step 2: スキーマの使用権限(\c myappdb でDBに切り替えてから実行) \c myappdb GRANT USAGE ON SCHEMA public TO webapp; -- Step 3: 既存テーブルへの権限 GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO webapp; -- 今後追加されるテーブルへのデフォルト権限 ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO webapp; -- シーケンス(SERIAL/BIGSERIALの自動採番)への権限 GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO webapp; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO webapp;
GRANT CONNECTはDB接続を許可するだけで、スキーマ内のオブジェクトを操作するには別途GRANT USAGE ON SCHEMAが必要です。2. PostgreSQL 15以降の注意点
PostgreSQL 15から、publicスキーマへのデフォルトのCREATE権限が一般ロールに付与されなくなりました。PostgreSQL 14以前の設定をそのまま持ち込むと、アプリがテーブルを作成しようとしてエラーになります。-- PostgreSQL 15以降: publicスキーマのCREATE権限を明示的に付与 GRANT CREATE ON SCHEMA public TO webapp;
3. REVOKEで権限を剥奪する
-- テーブルへの書き込み権限を剥奪 REVOKE INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public FROM webapp; -- データベース接続権限を剥奪 REVOKE CONNECT ON DATABASE myappdb FROM webapp;
よくあるエラーと対処法
「permission denied for schema public」が出たとき
このエラーはStep 2(GRANT USAGE ON SCHEMA public)を実行していないことが原因です。対象のデータベースに切り替えてからGRANT USAGEを実行してください。\c myappdb GRANT USAGE ON SCHEMA public TO webapp;
GRANT CREATE ON SCHEMA public TO webapp;を実行します。「role "xxx" does not exist」が出たとき
ロール名の大文字・小文字の扱いに注意が必要です。PostgreSQLはSQL識別子を小文字に正規化するため、CREATE ROLE WebAppと書くと実際はwebappという名前で作成されます。ダブルクォートで囲むと大文字が保持されますが、参照時にも必ずダブルクォートが必要になり運用が煩雑になります。原則としてロール名は小文字で統一するのが運用上の鉄則です。
パスワードを変更したい(\passwordコマンド)
-- 対話的にパスワードを変更(コマンド履歴に平文が残らない) \password webapp -- SQLで直接変更する場合 ALTER ROLE webapp WITH PASSWORD 'NewStrongPass456!';
\passwordコマンドはpsql内で対話的にパスワードを入力できるため、コマンド履歴にパスワードが残りません。本番環境では\passwordを使う習慣をつけておきましょう。本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| postgresユーザーに切り替える | su - postgres |
| psqlに接続する | psql -U postgres -d postgres |
| ロール一覧を表示する | \du |
| データベース一覧を表示する | \l |
| ログイン可能なロールを作成する | CREATE ROLE 名前 WITH LOGIN PASSWORD '...'; |
| データベースを作成する | CREATE DATABASE dbname OWNER ロール名; |
| DB接続権限を付与する | GRANT CONNECT ON DATABASE dbname TO ロール名; |
| スキーマ使用権限を付与する | GRANT USAGE ON SCHEMA public TO ロール名; |
| 全テーブルへの権限を付与する | GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO ロール名; |
| パスワードを変更する | \password ロール名 |
| ロールを削除する | DROP ROLE IF EXISTS ロール名; |
Linux Master Pro Seminar の詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:MySQLのデータディレクトリを別ディスクへ移設する手順|datadir変更とSELinuxラベルの再設定
- この記事の属するカテゴリ:データーベース管理へ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます