DataBase  /  PostgreSQL  /  レポート取得ガイド

pg_stat_* ビューによる取得とセクション定義

PostgreSQL 組み込みの統計ビュー群 pg_stat_* を使って、Oracle AWR 相当の 待機イベント・接続統計・テーブル/インデックス I/O・共有バッファ・バキューム・ロック情報を 取得する方法と、主要ビューの各列のセクション定義を解説します。

1. 接続・待機イベント統計(AWR: Top 5 Timed Events 相当)

pg_stat_activity は現在接続中のセッション情報と待機イベントを提供します。 Oracle AWR の Top 5 Timed Events に相当する待機イベントの集計に使用します。

SQL — 待機イベント別セッション数の集計
-- 待機イベント別のセッション数(Oracle AWR Top 5 Timed Events 相当)
SELECT
    wait_event_type,
    wait_event,
    state,
    COUNT(*)            AS session_count
FROM pg_stat_activity
WHERE pid <> pg_backend_pid()
GROUP BY wait_event_type, wait_event, state
ORDER BY session_count DESC;

-- アクティブセッションの詳細一覧
SELECT
    pid,
    usename,
    application_name,
    client_addr,
    state,
    wait_event_type,
    wait_event,
    now() - query_start   AS query_duration,
    left(query, 80)        AS query_preview
FROM pg_stat_activity
WHERE state <> 'idle'
  AND pid <> pg_backend_pid()
ORDER BY query_start;
列名説明Oracle AWR 対応
pid バックエンドプロセスのプロセス ID。 SID / Serial#
usename 接続ユーザー名。 Username
application_name 接続アプリケーション名(application_name パラメータで設定)。 Program
client_addr クライアントの IP アドレス。Unix ソケット接続は NULL。 Machine
state active(実行中)/idle(アイドル)/idle in transaction(トランザクション内アイドル)/idle in transaction (aborted) STATUS
wait_event_type 待機イベントのカテゴリ。Lock/LWLock/IO/Client/IPC など。 Wait Class
wait_event 具体的な待機イベント名。relation/WALWrite/DataFileRead など。 Wait Event
query_start 現在のクエリ開始タイムスタンプ。 SQL_EXEC_START
xact_start 現在のトランザクション開始タイムスタンプ。
backend_xid 現在のトランザクション ID(XID)。 XID
query 現在または直近に実行されたクエリテキスト(track_activity_query_size バイトまで)。 SQL_TEXT
wait_event_type の主要カテゴリ
Lock:テーブル・行レベルのロック待ち(Oracle の enq: TX 相当) / LWLock:軽量ロック待ち(Oracle の latch 相当) / IO:ディスク I/O 待ち(Oracle の db file sequential/scattered read 相当) / Client:クライアントからのデータ待ち / IPC:プロセス間通信待ち

2. データベース統計(AWR: Instance Activity 相当)

SQL — データベース統計の取得
SELECT
    datname,
    numbackends,
    xact_commit,
    xact_rollback,
    blks_read,
    blks_hit,
    ROUND(blks_hit::numeric / NULLIF(blks_hit + blks_read, 0) * 100, 2) AS cache_hit_ratio,
    tup_returned,
    tup_fetched,
    tup_inserted,
    tup_updated,
    tup_deleted,
    conflicts,
    temp_files,
    temp_bytes,
    deadlocks,
    stats_reset
FROM pg_stat_database
WHERE datname = current_database();
列名説明Oracle AWR 対応
numbackends 現在このデータベースに接続しているバックエンド数。 Sessions / Logons
xact_commit 累積コミット数。差分÷経過時間でコミット/秒を算出。 User Commits
xact_rollback 累積ロールバック数。多い場合はアプリの例外処理を見直す。 User Rollbacks
blks_read ディスクから読み込んだブロック数(キャッシュミス)。 Physical Reads
blks_hit 共有バッファから読み込んだブロック数(キャッシュヒット)。 Logical Reads
cache_hit_ratio バッファキャッシュヒット率(%)。95% 以上が目安。 Buffer Cache Hit Ratio
tup_returned シーケンシャルスキャンで返した行数。多い場合はフルスキャンが多い。 Table Scans(論理)
tup_fetched インデックススキャンで取得した行数。 Index Fetch
temp_files ソートや結合のために作成された一時ファイル数。work_mem 不足の指標。 Sorts (disk)
temp_bytes 一時ファイルの合計サイズ(バイト)。
deadlocks 累積デッドロック検出数。 Deadlocks
stats_reset 統計が最後にリセットされた日時。差分計算の基点。

3. テーブル統計(AWR: Segment Statistics 相当)

SQL — テーブル別アクセス統計(上位10件)
SELECT
    schemaname,
    relname                                     AS table_name,
    seq_scan,
    seq_tup_read,
    idx_scan,
    idx_tup_fetch,
    n_tup_ins                                   AS inserts,
    n_tup_upd                                   AS updates,
    n_tup_del                                   AS deletes,
    n_tup_hot_upd                               AS hot_updates,
    n_live_tup,
    n_dead_tup,
    ROUND(n_dead_tup::numeric / NULLIF(n_live_tup + n_dead_tup, 0) * 100, 2) AS dead_ratio,
    last_autovacuum,
    last_autoanalyze
FROM pg_stat_user_tables
ORDER BY seq_tup_read + idx_tup_fetch DESC
LIMIT 10;
列名説明Oracle AWR 対応
seq_scan シーケンシャルスキャン(フルスキャン)の累積回数。多い場合はインデックスを検討。 Full Table Scans
seq_tup_read シーケンシャルスキャンで読み込んだ累積行数。 Physical Reads(論理)
idx_scan インデックススキャンの累積回数。 Index Scans
idx_tup_fetch インデックスを経由して取得した累積行数。
n_tup_hot_upd HOT(Heap Only Tuple)更新の累積回数。高いほど効率的な更新が行われている。
n_live_tup 有効(生存)タプル数の推定値。 Rows
n_dead_tup 死亡タプル数の推定値。多い場合は VACUUM が必要。
dead_ratio 全タプルに占める死亡タプルの割合(%)。20% 超は VACUUM 推奨。
last_autovacuum 最後に自動 VACUUM が実行された日時。
last_autoanalyze 最後に自動 ANALYZE が実行された日時。統計情報が古い場合の確認に使う。

4. インデックス統計

SQL — 未使用インデックス・使用頻度の低いインデックスの特定
-- インデックス使用統計
SELECT
    schemaname,
    relname       AS table_name,
    indexrelname  AS index_name,
    idx_scan      AS scans,
    idx_tup_read  AS tuples_read,
    idx_tup_fetch AS tuples_fetched
FROM pg_stat_user_indexes
ORDER BY idx_scan DESC
LIMIT 20;

-- 未使用インデックスの検出(主キー・一意制約除く)
SELECT
    s.schemaname,
    s.relname         AS table_name,
    s.indexrelname    AS index_name,
    pg_size_pretty(pg_relation_size(s.indexrelid)) AS index_size,
    s.idx_scan
FROM pg_stat_user_indexes s
JOIN pg_index i ON i.indexrelid = s.indexrelid
WHERE s.idx_scan = 0
  AND NOT i.indisprimary
  AND NOT i.indisunique
ORDER BY pg_relation_size(s.indexrelid) DESC;
列名説明Oracle AWR 対応
idx_scan このインデックスを使用したスキャン累積回数。0 は未使用の可能性。 Index Scans
idx_tup_read インデックスエントリを読み込んだ累積行数。
idx_tup_fetch このインデックスを使って取得したヒープ行数。

5. I/O 統計(AWR: File I/O 相当)

SQL — テーブル・インデックス I/O 統計
-- テーブル I/O 統計(キャッシュヒット率)
SELECT
    schemaname,
    relname                                                         AS table_name,
    heap_blks_read,
    heap_blks_hit,
    ROUND(heap_blks_hit::numeric / NULLIF(heap_blks_hit + heap_blks_read, 0) * 100, 2) AS heap_hit_ratio,
    idx_blks_read,
    idx_blks_hit,
    ROUND(idx_blks_hit::numeric / NULLIF(idx_blks_hit + idx_blks_read, 0) * 100, 2) AS idx_hit_ratio,
    toast_blks_read,
    toast_blks_hit
FROM pg_statio_user_tables
ORDER BY heap_blks_read + idx_blks_read DESC
LIMIT 20;
列名説明Oracle AWR 対応
heap_blks_read テーブルのヒープからディスク読み込みしたブロック数。 Physical Reads(Table)
heap_blks_hit テーブルのヒープで共有バッファからヒットしたブロック数。 Logical Reads(Table)
idx_blks_read インデックスからディスク読み込みしたブロック数。 Physical Reads(Index)
idx_blks_hit インデックスで共有バッファからヒットしたブロック数。 Logical Reads(Index)
toast_blks_read TOAST(大きな値の外部格納)からディスク読み込みしたブロック数。
💡 PostgreSQL 16 以降: pg_stat_io
PostgreSQL 16 で導入された pg_stat_io は、I/O 操作をバックエンド種別・コンテキスト別に より細かく計測できます。backend_type(client backend / autovacuum / checkpointer など) ごとの read/write/extend/fsync 回数と所要時間を確認できます。

6. バックグラウンドライタ / チェックポイント統計(AWR: Buffer Pool 相当)

SQL — チェックポイント・バッファ書き込み統計
SELECT
    checkpoints_timed,
    checkpoints_req,
    checkpoint_write_time,
    checkpoint_sync_time,
    buffers_checkpoint,
    buffers_clean,
    maxwritten_clean,
    buffers_backend,
    buffers_backend_fsync,
    buffers_alloc,
    stats_reset
FROM pg_stat_bgwriter;
列名説明Oracle AWR 対応
checkpoints_timed スケジュールされたチェックポイント(checkpoint_timeout によるもの)の累積回数。
checkpoints_req 要求によるチェックポイント(max_wal_size 超過など)の累積回数。多い場合は max_wal_size を増やす。
checkpoint_write_time チェックポイント中のファイル書き込みに費やした累積時間(ms)。
checkpoint_sync_time チェックポイント中のファイル同期(fsync)に費やした累積時間(ms)。大きい場合はディスク I/O がボトルネック。
buffers_checkpoint チェックポイントで書き込んだバッファ数。 Physical Writes(checkpoint)
buffers_clean バックグラウンドライタが書き込んだバッファ数。 Physical Writes(dbwr)
maxwritten_clean バックグラウンドライタが bgwriter_lru_maxpages に達してスキャンを中断した回数。多い場合は bgwriter_lru_maxpages を増やすか負荷を分散する。
buffers_backend バックエンドプロセス自身が直接書き込んだバッファ数。多い場合は shared_buffers や bgwriter の設定を見直す。
buffers_alloc 新規に割り当てたバッファ数。ディスクから読み込んだブロック数とほぼ対応。 Physical Reads
チェックポイント診断の目安
checkpoints_req / (checkpoints_req + checkpoints_timed) の比率が高い(目安:50% 超)場合、 WAL が max_wal_size に頻繁に達しています。 max_wal_size の増加や checkpoint_completion_target の調整を検討してください。

7. ロック統計(AWR: Lock Statistics 相当)

SQL — ロック待ちセッションの特定
-- ロック待ちとブロッキングセッションの特定
SELECT
    blocked.pid                              AS blocked_pid,
    blocked.usename                          AS blocked_user,
    blocked.query                            AS blocked_query,
    blocking.pid                             AS blocking_pid,
    blocking.usename                         AS blocking_user,
    blocking.query                           AS blocking_query,
    now() - blocked.query_start              AS wait_duration
FROM pg_stat_activity AS blocked
JOIN pg_stat_activity AS blocking
    ON blocking.pid = ANY(pg_blocking_pids(blocked.pid))
WHERE cardinality(pg_blocking_pids(blocked.pid)) > 0
ORDER BY wait_duration DESC;

-- ロック種別の集計
SELECT
    locktype,
    relation::regclass   AS table_name,
    mode,
    granted,
    COUNT(*)             AS count
FROM pg_locks
WHERE relation IS NOT NULL
GROUP BY locktype, relation, mode, granted
ORDER BY count DESC;
列名(pg_locks)説明Oracle AWR 対応
locktype relation(テーブル)/tuple(行)/transactionid/advisory など。 enq: TX / TM / row lock
mode ロックモード。AccessShareLock(SELECT)から AccessExclusiveLock(DDL)まで8段階。 Lock Mode
granted ロックが付与されているか(true)、待機中か(false)。
pid ロックを保持または待機しているバックエンドの PID。 SID

8. バキューム統計

SQL — バキューム進捗とテーブル肥大化の確認
-- 実行中の VACUUM の進捗確認
SELECT
    p.pid,
    p.relid::regclass       AS table_name,
    p.phase,
    p.heap_blks_total,
    p.heap_blks_scanned,
    ROUND(p.heap_blks_scanned::numeric / NULLIF(p.heap_blks_total, 0) * 100, 1) AS progress_pct,
    p.num_dead_item_ids
FROM pg_stat_progress_vacuum p;

-- バキュームが必要なテーブルの優先度確認
SELECT
    schemaname,
    relname,
    n_dead_tup,
    n_live_tup,
    ROUND(n_dead_tup::numeric / NULLIF(n_live_tup + n_dead_tup, 0) * 100, 2) AS dead_ratio,
    last_vacuum,
    last_autovacuum
FROM pg_stat_user_tables
WHERE n_dead_tup > 1000
ORDER BY dead_ratio DESC
LIMIT 20;

9. 統計のリセット

SQL — 統計リセット
-- データベース全体の統計をリセット(計測開始点のリセット)
SELECT pg_stat_reset();

-- バックグラウンドライタ統計のみリセット
SELECT pg_stat_reset_shared('bgwriter');

-- pg_stat_statements のリセット(PART 03 参照)
SELECT pg_stat_statements_reset();

-- リセット日時の確認
SELECT stats_reset FROM pg_stat_database WHERE datname = current_database();
SELECT stats_reset FROM pg_stat_bgwriter;
⚠️ リセットは慎重に
pg_stat_reset() はデータベース全体の累積統計を初期化します。 本番環境での実行は計測目的が明確な場合のみにしてください。 差分取得には、定期的にスナップショットを別テーブルに保存する方法が推奨されます。