PostgreSQLのデータベース一覧とディスク使用量を調べる方法|pg_databaseとpg_database_sizeで容量を把握する

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Linuxtipsデーターベース管理 > PostgreSQLのデータベース一覧とディスク使用量を調べる方法|pg_databaseとpg_database_sizeで容量を把握する
「ディスク使用率がじわじわと上昇している。でも、どのデータベースが容量を食っているのかわからない。」
複数のデータベースを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なので監視対象から除外してよい


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

なぜデータベース容量の定期的な把握が運用の基本なのか

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)

template0template1 は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)

Size 列を見ると、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=#

テーブル単位のサイズを大きい順に確認するSQLを実行します。

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サーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から丁寧に教えます。
Linuxセミナーの詳細を見る >>

接続エラー・容量確認のトラブルシュートとよくあるエラー対処法

「ERROR: permission denied for table pg_database」が出る場合

一般ユーザーで接続したまま pg_database を参照しようとすると、権限エラーが発生することがあります。解決策は postgresスーパーユーザーで接続し直すことです。

# postgresスーパーユーザーで接続する $ sudo -u postgres psql

pg_database はシステムカタログですが、PostgreSQLのバージョンや設定によっては一般ユーザーからの参照に制限が設けられている場合があります。

「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
定期的なサイズ確認をcronで自動化し、一定のしきい値を超えたらメール通知する仕組みを整えると、ディスク不足の予兆を見逃さずに済みます。PostgreSQLをLinuxサーバーで長期安定運用するための基本スキルとして、ぜひ活用してください。

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。