CodeGym /コース /SQL SELF /PostgreSQLの基本モニタリングコマンド — pg_stat_activity ...

PostgreSQLの基本モニタリングコマンド — pg_stat_activitypg_stat_user_tables

SQL SELF
レベル 45 , レッスン 1
使用可能

データベースのmonitoringをpg_stat_activitypg_stat_user_tablesなしでやるのは、体温だけで健康を判断するのと同じ感じ。全体しか見えなくて、どこに問題があるのか分からないよね。この2つのPostgreSQLのキーツールを使えば、ただ眺めるだけじゃなくて、実際に何が起きてるかをガッツリ分析できるんだ。

pg_stat_activityって何?

pg_stat_activityは、PostgreSQLのシステムビューで、データベースへの全接続の情報を表示してくれるやつ。誰がDBに繋いでるのか、今どんなクエリが走ってるのか、「アイドル」状態で止まってる接続はどれか、みたいな疑問に答えてくれる。サーバーの今のアクティビティを分析するためのツールだよ。

じゃあ、pg_stat_activityで見れる主なカラムを見てみよう。datnameはクライアントが繋いでるデータベース名、usenameは接続してるユーザー名。application_nameはその接続を使ってるアプリ名、client_addrはサーバーに繋いでるクライアントのIPアドレス。backend_startはクライアントがサーバーに繋いだ時間、stateは今の接続状態(activeidleidle in transactionとか)、queryは今実行中または直近で実行されたクエリが入ってる。

例1: 全アクティブ接続の確認

アクティブな接続を見たいときは、こんなクエリを実行してみて:

SELECT datname, usename, client_addr, state, query
FROM pg_stat_activity
WHERE state = 'active';

queryカラムに注目してみて。今実行中のクエリが見れるよ。もしクエリの実行がやたら長いなら、何か問題があるかも。

例2: トランザクション状態の分析

たまに接続がidle in transaction状態で「詰まる」ことがある。これはトランザクションが始まったまま終わってなくて、ロックの原因になったりするんだ。

SELECT pid, usename, query, state
FROM pg_stat_activity
WHERE state = 'idle in transaction';

どうやって直す? もし「詰まってる」トランザクションを見つけたら、こんなコマンドで終了させられる:

SELECT pg_terminate_backend(pid)
FROM pg_stat_activity
WHERE state = 'idle in transaction';

でも、これにハマりすぎる開発者もいるから注意。まずはチームに「このプロセスkillしていい?」って確認しよう。あ、ごめん、「kill」じゃなくて「接続を終了」だね。

テーブル利用状況のモニタリング: pg_stat_user_tablesビュー

pg_stat_activityが接続の監視なら、pg_stat_user_tablesはテーブルのパフォーマンスを教えてくれるやつ。どのテーブルがどれだけ読まれたり書かれたりしてるか、どのテーブルが一番使われてるか、パフォーマンスの問題がどこにあるかが分かるよ。

pg_stat_user_tablesでチェックしたい主なカラムはこんな感じ。relnameはテーブル名、seq_scanはシーケンシャルスキャン(全件走査)の回数、idx_scanはインデックスを使ったスキャンの回数。n_tup_insはテーブルに挿入された行数、n_tup_updは更新された行数、n_tup_delは削除された行数だよ。

例1: インデックス利用とシーケンシャルスキャンの比較

もしインデックスの利用回数(idx_scan)がほぼゼロなら、そのテーブルへのクエリは最適化できるかも。

SELECT relname, seq_scan, idx_scan
FROM pg_stat_user_tables
ORDER BY seq_scan DESC;

結果例:

例えば、ordersテーブルのseq_scanがめっちゃ多くて、idx_scanが100しかないのに、employeesテーブルはseq_scanが50でidx_scanが1000とかだったら、ordersテーブルにインデックス追加を考えた方がいいよ。これは明らかに最適化のサイン!

例2: テーブルごとの操作数分析

テーブルの「活発さ」を知りたいなら、挿入・更新・削除された行数をチェックしよう:

SELECT relname, n_tup_ins, n_tup_upd, n_tup_del
FROM pg_stat_user_tables
ORDER BY n_tup_ins DESC;

何が分かる? 挿入(n_tup_ins)や削除(n_tup_del)が多いテーブルは、DBの「ホットスポット」になってるかも。そういうテーブルはパフォーマンスに特に気をつけてね。

パフォーマンス分析の実践: pg_stat_activitypg_stat_user_tablesのデータを組み合わせる

DBのパフォーマンスを分析するときは、この2つの情報を組み合わせるのがコツ。まずpg_stat_activityで長時間実行中のクエリを特定して、次にそのクエリが使ってるテーブルをpg_stat_user_tablesでチェック。もしseq_scanが多いテーブルでクエリが遅いなら、クエリの最適化やインデックス追加を検討しよう。

クエリ例:

WITH active_queries AS (
    SELECT pid, query
    FROM pg_stat_activity
    WHERE state = 'active' AND query <> '<IDLE>'
)
SELECT a.pid, a.query, t.relname, t.seq_scan, t.idx_scan
FROM active_queries a
JOIN pg_stat_user_tables t ON a.query LIKE '%' || t.relname || '%';
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION