【実務・中級編】 pg_stat_activity – PostgreSQL

「なんか最近DB重くない?」と言われたらまず見るべき場所:pg_stat_activityの活用術

現場で働いていると、たまに「アプリのレスポンスが妙に遅いぞ」とか「特定のバッチが終わらない」なんてトラブルに遭遇するよね。そんなとき、慌ててログファイルを漁ったり、適当に `EXPLAIN` を投げたりするのはまだ早い。

まずは「今、PostgreSQLの中で何が起きているのか?」を可視化すること。そのための最強のツールが `pg_stat_activity` だ。今日は、僕が現場でトラブルシューティングをする際に必ず使う、このビューの「実戦的な使い方」を共有するよ。

—

pg_stat_activity とは何か?

一言で言えば、「データベースの現在地」がすべて書かれている動的なレポートだ。
現在接続しているセッション、実行中のSQL、開始時刻、待機イベントまで、DBの「今」が詰まっている。

まずは、今の接続状況をざっくり把握するための基本クエリを紹介するね。

SELECT
pid,
usename,
application_name,
state,
query_start,
wait_event_type,
wait_event,
query
FROM pg_stat_activity
WHERE state != ‘idle’ — 待機中の接続は邪魔なので除外
ORDER BY query_start ASC;

これを見るだけで、「誰が、いつから、どんなSQLを投げているか」が一目瞭然だ。

—

実務で「これだけは確認しろ」という3つのポイント

ただ眺めるだけじゃなくて、現場では「何に注目するか」が重要だ。僕がトラブル時にまずチェックする項目はこれだよ。

1. 「実行時間」の長すぎるクエリを特定する

`query_start` を見れば、そのクエリが何秒前から走り続けているか計算できる。

SELECT
pid,
now() – query_start AS duration,
query
FROM pg_stat_activity
WHERE state = ‘active’
AND (now() – query_start) > interval ’10 seconds’
ORDER BY duration DESC;

10秒以上動いているクエリがあれば、インデックスが効いていないか、デッドロックでハマっている可能性が高い。まずはここを疑おう。

2. ロック待ち(Block)の状況を探る

DBが重い原因の多くは、「誰かがロックを掴んだまま離さない」ことにある。`wait_event_type` が `Lock` になっているセッションを探し出すのがコツだ。

SELECT
pid,
wait_event_type,
wait_event,
query
FROM pg_stat_activity
WHERE wait_event_type = ‘Lock’;

もしこれが見つかったら、そのクエリが「どのテーブルのロックを待っているか」をさらに深掘りする必要がある。`pg_locks` と結合して調査するのが定石だね。

3. Idle in transaction の放置を叩く

新人さんがよくやらかすのが、トランザクションを開いたまま処理を放置するやつ。「`BEGIN` して処理して、`COMMIT` するのを忘れる」というパターンだ。これは他の処理の邪魔でしかない。

SELECT pid, usename, query, state_change
FROM pg_stat_activity
WHERE state = ‘idle in transaction’;

もしこれを見つけたら、即座にプロセスを終了させて(`pg_terminate_backend(pid)`)状況を正常に戻す判断が必要になることもある。

—

先輩からのアドバイス:運用への備え

`pg_stat_activity` は非常に強力だけど、「今の瞬間」しか見えないという弱点がある。もし、「さっき一瞬だけ重かった」という現象を追いかけたいなら、PostgreSQLの設定値を見直すことも検討してみて。

  • `log_min_duration_statement`: 一定時間以上かかったクエリをログに出す設定。
  • `pg_stat_statements`: 拡張機能を有効にして、クエリの実行統計(平均実行時間や呼び出し回数)を永続的に記録する。

トラブルが起きてから焦って設定を変えるのはリスクがあるから、普段からこれらの仕組みを入れておくのが、優秀なエンジニアの「守り」だよ。

—

最後に

`pg_stat_activity` は、いわばDBの健康診断ツールだ。
「最近ちょっと重いな」と感じたとき、感覚で「DBが悪い」と決めつけるんじゃなくて、このビューを使って「どのクエリが、なぜ待たされているのか」を客観的に指摘できるようになると、周囲からの信頼もグッと上がるはず。

まずは、今の自分の環境でこのクエリを叩いてみて。意外な「隠れ犯人」が見つかるかもしれないよ。

何か困ったことがあったら、またいつでも聞いてくれ。応援してるぞ。

コメント

タイトルとURLをコピーしました