複数のデータベースを1台のLinuxサーバーで運用していると、こうした状況に直面することがあります。PostgreSQLはディスクが満杯になると書き込みを受け付けなくなるため、容量の把握は後回しにできない運用タスクです。
この記事では、pg_database システムカタログと pg_database_size() 関数を使ってデータベース一覧とディスク使用量を確認する具体的な手順を解説します。psqlのメタコマンドによる素早い確認から、SQLで全データベースを一覧比較する方法、テーブル・インデックス単位の内訳確認まで、セルフホスト運用に必要な手順をまとめました。動作確認環境はRocky Linux 9.4 / PostgreSQL 16.4です。
この記事のポイント
・pg_database_size()関数でDBごとのサイズをバイト単位で取得できる
・psqlの\l+でSQL不要でデータベース一覧+サイズをまとめて確認できる
・pg_size_pretty()と組み合わせると「1547 MB」形式で読みやすくなる
・template0/template1はシステム用DBなので監視対象から除外してよい
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜデータベース容量の定期的な把握が運用の基本なのか
PostgreSQLは、ディスクの空き領域がゼロになると新規の書き込みを受け付けなくなります。アプリケーションのログには「ERROR: could not write to file」や「could not extend file」のようなエラーが出始め、最悪の場合はサービスが停止します。容量不足が深刻なのは、肥大化が緩やかに進行する点です。毎日少しずつ増加するデータは気づきにくく、ある朝突然「ディスク使用率95%」の警告が届くというパターンがよく起きます。予防するには、定期的に各データベースのサイズを確認しておくことが欠かせません。
また、ストレージ増設やデータ整理の計画を立てるときにも「どのデータベースがどれくらいの容量を使っているか」の実数が必要です。このページでその確認方法を一通りおさえておきましょう。
psqlのメタコマンドでデータベース一覧を確認する方法
まずはpsqlに接続して、メタコマンドでざっくり確認する手順から解説します。SQLを書かずに一覧を確認できるため、現場でとりあえず状況を把握したいときに便利です。1. postgresユーザーでpsqlに接続する
PostgreSQLの管理操作はpostgresユーザーで行います。# OSのpostgresユーザーに切り替える $ sudo -i -u postgres # psqlを起動する $ psql psql (16.4) Type "help" for help. postgres=#
postgres=# になればログイン成功です。2. \l でデータベース一覧を表示する
\l(バックスラッシュ + l)を入力すると、現在のPostgreSQLインスタンスに存在するデータベースの一覧が表示されます。postgres=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges ------------+----------+----------+-------------+-------------+----------------------- appdb | appuser | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | postgres | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | template0 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres (4 rows)
template0 と template1 はPostgreSQLが内部で使うシステムデータベースです。通常、業務用のデータが入っているのは postgres や独自に作成したデータベースになります。3. \l+ でサイズ付き一覧を確認する
\l+ を使うと、サイズの列が追加されたより詳細な一覧を確認できます。postgres=# \l+ List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges | Size | Tablespace ------------+----------+----------+-------------+-------------+-------------------+---------+------------ appdb | appuser | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | | 1547 MB | pg_default postgres | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | | 8293 kB | pg_default template0 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres +| 7993 kB | pg_default template1 | postgres | UTF8 | ja_JP.UTF-8 | ja_JP.UTF-8 | =c/postgres +| 7993 kB | pg_default (4 rows)
appdb が 1547 MB を使っていることがわかります。これだけでも「どのDBが大きいか」はすぐに判断できます。pg_databaseカタログとpg_database_size()で容量を把握する
メタコマンドは手動確認に向いていますが、シェルスクリプトや監視ツールと連携させるにはSQLで結果を取得する方が扱いやすくなります。1. pg_databaseカタログでデータベース一覧をSQLで取得する
pg_database はPostgreSQLのシステムカタログで、インスタンス上のデータベース情報を格納しています。postgres=# SELECT datname FROM pg_database ORDER BY datname; datname ----------- appdb postgres template0 template1 (4 rows)
datistemplate = false の条件を加えると、template0/template1 を除いた業務用データベースだけに絞れます。postgres=# SELECT datname FROM pg_database WHERE datistemplate = false ORDER BY datname; datname ----------- appdb postgres (2 rows)
2. pg_database_size()でディスク使用量をバイト単位で取得する
pg_database_size() 関数はデータベース名またはOIDを引数に取り、そのデータベースのディスク使用量をバイト単位の整数で返します。postgres=# SELECT pg_database_size('appdb'); pg_database_size ------------------ 1621360640 (1 row)
3. pg_size_pretty()と組み合わせて全データベースを一覧比較する
pg_size_pretty() 関数はバイト値を受け取り、「1547 MB」「7993 kB」のように人間が読みやすい単位に変換します。これを pg_database_size() と組み合わせて、全データベースのサイズを一覧表示するSQLが以下です。postgres=# SELECT datname AS "データベース名", pg_size_pretty(pg_database_size(datname)) AS "サイズ", pg_database_size(datname) AS "バイト数(ソート用)" FROM pg_database WHERE datistemplate = false ORDER BY pg_database_size(datname) DESC; データベース名 | サイズ | バイト数(ソート用) ----------------+----------+--------------------- appdb | 1547 MB | 1621360640 postgres | 8293 kB | 8492032 (2 rows)
ORDER BY pg_database_size(datname) DESC で容量の大きい順に並べているため、どのデータベースがもっとも多くのディスクを消費しているかが一目でわかります。データベース内の容量内訳を確認する(テーブル・インデックス別)
「appdb が 1.5GB 使っている」とわかっても、内部でどのテーブルが大きいかを特定しないと整理のしようがありません。接続先のデータベースを切り替えて、テーブル単位の内訳を確認しましょう。まず対象のデータベースに接続します。
postgres=# \c appdb You are now connected to database "appdb" as user "postgres". appdb=#
appdb=# SELECT schemaname AS "スキーマ", tablename AS "テーブル名", pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS "合計サイズ", pg_size_pretty(pg_relation_size(schemaname||'.'||tablename)) AS "テーブル本体", pg_size_pretty(pg_indexes_size(schemaname||'.'||tablename)) AS "インデックス" FROM pg_tables WHERE schemaname NOT IN ('pg_catalog', 'information_schema') ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC LIMIT 10; スキーマ | テーブル名 | 合計サイズ | テーブル本体 | インデックス ----------+--------------------+------------+--------------+-------------- public | order_histories | 892 MB | 712 MB | 180 MB public | access_logs | 421 MB | 389 MB | 32 MB public | users | 67 MB | 52 MB | 15 MB public | products | 12 MB | 9112 kB | 3072 kB public | categories | 384 kB | 256 kB | 128 kB (5 rows)
・pg_total_relation_size():テーブル本体+インデックス+TOASTテーブルの合計
・pg_relation_size():テーブル本体のみ(インデックスは含まない)
・pg_indexes_size():そのテーブルに紐づくインデックスの合計
【重要】
pg_total_relation_size() はTOASTテーブル(可変長データの外部格納領域)も含むため、テーブル本体だけを把握したいときは pg_relation_size() を使ってください。order_histories が合計892 MBで、そのうちインデックスが180 MBあることがわかります。古いログデータや不要なインデックスを整理するだけで大幅に容量を節約できるケースは多く、このSQLが調査の第一歩になります。
Linuxセミナーの詳細を見る >>
接続エラー・容量確認のトラブルシュートとよくあるエラー対処法
「ERROR: permission denied for table pg_database」が出る場合
一般ユーザーで接続したままpg_database を参照しようとすると、権限エラーが発生することがあります。解決策は postgresスーパーユーザーで接続し直すことです。# postgresスーパーユーザーで接続する $ sudo -u postgres psql
「ERROR: function pg_database_size(unknown) does not exist」が出る場合
pg_database_size() はPostgreSQL 8.1以降で利用できる関数です。このエラーが出た場合は、引数の型を確認してください。# 文字列(テキスト型)で渡す → OK SELECT pg_database_size('appdb'); # current_database()関数でカレントDBのサイズを取得 → OK SELECT pg_database_size(current_database());
\l+ でサイズ列が空白になる場合
ごくまれに\l+ のサイズ列が空白になることがあります。これは接続しているユーザーにそのデータベースへの接続権限がない場合に起きます。postgresスーパーユーザーで実行すると解消します。本記事のまとめ
PostgreSQLのデータベース一覧とディスク使用量を確認する方法を解説しました。用途に合わせて使い分けるのがポイントです。| やりたいこと | コマンド・SQL |
|---|---|
| データベース一覧を手軽に確認する | \l(psqlメタコマンド) |
| サイズ付きでデータベース一覧を確認する | \l+(psqlメタコマンド) |
| SQLでデータベース一覧を取得する | SELECT datname FROM pg_database |
| 特定DBのサイズをバイトで取得する | SELECT pg_database_size('DB名') |
| 全DBのサイズを読みやすい単位で一覧比較する | SELECT datname, pg_size_pretty(pg_database_size(datname)) FROM pg_database |
| テーブル単位のサイズ内訳を確認する | SELECT tablename, pg_size_pretty(pg_total_relation_size(...)) FROM pg_tables |
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:MariaDBへリモート接続できるようにする手順|bind-addressの見直しとポート開放・接続元の制限
- この記事の属するカテゴリ:データーベース管理へ戻る

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