DataBase / PostgreSQL / レポート取得ガイド
pg_stat_* ビューによる取得とセクション定義
PostgreSQL 組み込みの統計ビュー群 pg_stat_* を使って、Oracle AWR 相当の 待機イベント・接続統計・テーブル/インデックス I/O・共有バッファ・バキューム・ロック情報を 取得する方法と、主要ビューの各列のセクション定義を解説します。
1. 接続・待機イベント統計(AWR: Top 5 Timed Events 相当)
セクション定義: pg_stat_activity
pg_stat_activity は現在接続中のセッション情報と待機イベントを提供します。
Oracle AWR の Top 5 Timed Events に相当する待機イベントの集計に使用します。
-- 待機イベント別のセッション数(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 相当)
セクション定義: pg_stat_database
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 相当)
セクション定義: pg_stat_user_tables
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. インデックス統計
セクション定義: pg_stat_user_indexes
-- インデックス使用統計
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 相当)
セクション定義: pg_statio_user_tables / pg_statio_user_indexes
-- テーブル 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 で導入された
PostgreSQL 16 で導入された
pg_stat_io は、I/O 操作をバックエンド種別・コンテキスト別に
より細かく計測できます。backend_type(client backend / autovacuum / checkpointer など)
ごとの read/write/extend/fsync 回数と所要時間を確認できます。
6. バックグラウンドライタ / チェックポイント統計(AWR: Buffer Pool 相当)
セクション定義: pg_stat_bgwriter
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 相当)
セクション定義: pg_locks / pg_stat_activity
-- ロック待ちとブロッキングセッションの特定
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. バキューム統計
セクション定義: pg_stat_progress_vacuum / pg_stat_user_tables
-- 実行中の 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. 統計のリセット
-- データベース全体の統計をリセット(計測開始点のリセット)
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() はデータベース全体の累積統計を初期化します。
本番環境での実行は計測目的が明確な場合のみにしてください。
差分取得には、定期的にスナップショットを別テーブルに保存する方法が推奨されます。