変更要約: 初版(主題G2・G2.1〜G2.4)
2.1アクセス統計情報
サーバーの「今」を映す統計ビュー群を学びます。接続中セッションを可視化するpg_stat_activity(wait_event_type/wait_event)、ロック競合を追うpg_locks、DB単位の集計を持つpg_stat_database、テーブルアクセス傾向のpg_stat_all_tables、物理I/Oのpg_statio_all_tables、WALアーカイブのpg_stat_archiver、チェックポイント/バッファ書き出しのpg_stat_bgwriterを押さえます。
「サーバーが遅い」という報告を受けたとき、まず見るべきは推測ではなく統計ビューです。PostgreSQLはpg_stat_*という名前空間に、接続状況・ロック競合・テーブルアクセス傾向・物理I/Oまで、稼働中サーバーの内部状態を継続的に集計して公開しています。どのビューが何を映すかを正確に対応づけられることが、性能監視の出発点です。
2.1.1pg_stat_activity と pg_locks
- pg_stat_activity=現在接続している全セッションを1行1プロセスで表示するビュー。
pid・usename・state(active/idle/idle in transaction等)・query(実行中または直近のSQL)に加え、wait_event_type(Lock/LWLock/IO/Client等の待機分類)とwait_event(具体的な待機事象名)でセッションが何を待っているかまで特定できる。 - pg_locks=サーバー内で保持・要求中のロック情報を行単位で列挙するビュー。
locktype・relation・pid・mode(AccessShareLock〜AccessExclusiveLock)・granted(true=取得済み/false=待機中)を持つ。pg_stat_activityとpidで結合すると「どのクエリがどのロックを待たされているか」を突き止められ、デッドロック調査やロック競合の一次切り分けに使う定番の組み合わせ。
2.1.2pg_stat_database・テーブル/I/O統計・archiver・bgwriter
- pg_stat_database=データベース単位の集計ビュー。
xact_commit/xact_rollback(コミット/ロールバック数)・blks_read/blks_hit(物理読み取り/バッファヒット)・deadlocks・temp_files/temp_bytes(一時ファイル使用量)を持ち、キャッシュヒット率(blks_hit / (blks_hit + blks_read))の算出元として頻出。 - pg_stat_all_tables=テーブル単位のアクセス傾向。
seq_scan/seq_tup_read(シーケンシャルスキャン回数と読取行数)・idx_scan/idx_tup_fetch(インデックス使用状況)・n_tup_ins/n_tup_upd/n_tup_del・n_dead_tup(デッドタプル数=VACUUM要否の判断材料)・last_vacuum/last_autovacuum/last_analyze/last_autoanalyze(各メンテナンスの最終実行時刻)を持つ。 - pg_statio_all_tables=物理I/Oに特化した統計。
heap_blks_read/heap_blks_hit(テーブル本体のディスク読取/キャッシュヒット)・idx_blks_read/idx_blks_hit(インデックス側)を持ち、テーブル単位でキャッシュ効率を見たいときはpg_stat_all_tablesではなくこちらを参照する。 - pg_stat_archiver=WALアーカイブの成否を追跡(
archived_count・last_archived_wal・failed_count・last_failed_wal)。archive_commandの失敗検知に使う。pg_stat_bgwriter=チェックポイント/バックグラウンドライタの書き出し統計(checkpoints_timed/checkpoints_req=定期/要求チェックポイント数・buffers_checkpoint/buffers_clean/buffers_backend=書き出し元の内訳)で、チェックポイントが頻発しすぎていないか(checkpoints_reqが多い=max_wal_size不足の兆候)を判断する材料になる。
「pg_stat_activityのwait_event_type/wait_eventでセッションの待機理由を特定する」「pg_locksとpid結合でブロッキングクエリを特定する」「n_dead_tupはVACUUM要否の判断材料」「pg_statio_all_tablesは物理I/O専用(pg_stat_all_tablesはアクセス回数)」「checkpoints_reqの多さはmax_wal_size不足の兆候」が最頻出です。ビュー名の接尾辞(_activity/_database/_all_tables/_bgwriter)と集計粒度の対応も繰り返し出ます。
実務の障害調査フローを追ってみましょう。「特定のクエリが返ってこない」という報告を受けたら、まずSELECT pid, state, wait_event_type, wait_event, query FROM pg_stat_activity WHERE state != 'idle';で現在アクティブな全セッションの待機状態を俯瞰します。wait_event_typeがLockであれば、そのセッションは何らかのロック待ちだと分かるので、次にpg_locksをpg_stat_activityとpidで結合し、granted = falseの行を探します。ここで得られるpidが、実際にロックを保持したまま長時間トランザクションを終えていない加害セッションです。加害セッションのstateがidle in transactionであることも多く、これは「BEGINしたままCOMMIT/ROLLBACKを忘れている」典型パターンです。原因が特定できれば、緊急対応として後述のpg_cancel_backend()(Gold G1範囲)でそのバックエンドのクエリをキャンセルする、という流れになります。ロック待ちでなくwait_event_typeがIOであれば、ディスクI/O自体がボトルネックの可能性が高く、pg_statio_all_tablesで対象テーブルのheap_blks_readが異常に多くないかを確認します。一方、「特定のテーブルへの書き込みが遅い」という報告であればpg_stat_all_tablesでn_dead_tupを確認し、デッドタプルが積み上がっているのにlast_autovacuumが古い(=autovacuumが追いついていない)ことが分かれば、そのテーブルに対してVACUUMのチューニング(G1/G3範囲)が必要だと判断できます。統計ビューはそれ単体では原因を教えてくれず、複数ビューを組み合わせて仮説を絞り込む道具である、という姿勢が重要です。
| ビュー | 粒度 | 主な用途 |
|---|---|---|
| pg_stat_activity | セッション(プロセス) | 待機理由の特定(wait_event_type/wait_event) |
| pg_locks | ロック行 | ブロッキングセッションの特定(pidで結合) |
| pg_stat_database | データベース | キャッシュヒット率・デッドロック件数 |
| pg_stat_all_tables | テーブル | アクセス傾向・n_dead_tup(VACUUM判断) |
| pg_statio_all_tables | テーブル | 物理I/O(heap/idx blks_read/hit) |
ひっかけ: 「pg_stat_all_tablesを見ればディスクI/Oの負荷が分かる」は不正確です。pg_stat_all_tablesはアクセス回数(seq_scan/idx_scan等)の統計で、物理I/O(ブロック読み取り/ヒット)専用のビューはpg_statio_all_tablesです。また「pg_locksのgranted=falseの行が、ロックを保持しているセッションを示す」も誤り=granted=falseは要求中(=待たされている側)で、保持側(加害セッション)は同じrelationに対するgranted=trueの行を探す必要があります。
2.1.3この節のまとめ
- pg_stat_activity=セッション単位(wait_event_type/wait_eventで待機理由特定)。pg_locks=ロック行(granted=falseが待機側・pidでpg_stat_activityと結合)
- pg_stat_database=DB単位集計・pg_stat_all_tables=アクセス回数+n_dead_tup・pg_statio_all_tables=物理I/O専用・pg_stat_archiver=WALアーカイブ成否・pg_stat_bgwriter=チェックポイント/書き出し統計
進捗の記録にはログインが必要です。
理解度チェック
(軽い確認用)Q1. 本番DBで特定のクエリが長時間応答を返さない。まずセッションが何を待っているかを特定したい。最初に確認すべきビューと列の組み合わせは?
Q2. pg_locks と pg_stat_activity を pid で結合して調査したところ、あるセッションが granted=false の行を持っていた。このセッションについて正しい説明は?
Q3. あるテーブルへの更新が徐々に遅くなっている。VACUUMが追いついていないかを調べたい。確認すべきビューと列は?

