Hatena::Grouppostgresql

PostgreSQL 雑記 このページをアンテナに追加 RSSフィード

2009-02-22サンプリング・プロファイラ (仮) このエントリーを含むブックマーク このエントリーのブックマークコメント

追記:「2009-03-10 : Sampling Profler for Postgres」でアップデートしています。

データベースといえばチューニングが付き物です。もちろん適当に自立的に動作してくれるのが一番なのですが、なかなか理想通りには行かず、どうしてもボトルネック解析が必要になってきます。ボトルネック解析の方法はいろいろありますが、SQLそれぞれを個別に調査する方法は、バージョン 8.4 の pg_stat_statements で(いちおう)実現できました。次は、システム全体をざっくりと調査するツールが必要かと思って、日曜大工してみたのがコレです。今のところは elog() に垂れ流していますが、最終的にはきちんとビューにするつもりです。

LOG:  Condition : 722 samples
LOG:                  IDLE : 493
LOG:   IDLE_IN_TRANSACTION : 1026
LOG:                   CPU : 298
LOG:             DATA_READ : 0
LOG:            DATA_WRITE : 0
LOG:            XLOG_WRITE : 130
LOG:            XLOG_FLUSH : 0
LOG:           LWLOCK_WAIT : 13
LOG:             LOCK_WAIT : 865

実装は非常に単純で、backend 各々が PgBackendStatus.st_condition フィールド (新規) に「今自分が何をしているか」を表す値を書き込み、統計情報収集プロセス (stats collector) が定期的にポーリングして集計しています。サンプリングなので統計的な値しか得られませんが、何度も繰り返すことで、それなりの精度になるはずです。既存の実装でも、st_waiting フィールドで「ロック待機中か」を追跡しており pg_stat_activity.waiting 列で観察することができますが、これを他の処理にも拡張した形です。

設定を変えながら pgbench で実験してみた結果は以下です。何が性能要因になっているかをある程度推測できそうです。情報収集の中では特に追加のロックも不要なので、軽量なプロファイラとして実サービスでも on のまま運用できるかなと見込んでいます。

ID1234
pgbench-S-S-N(TPC-B)
shared_buffers32MB4MB32MB32MB
tps12894112451586896
IDLE_IN_TRANSACTION0.0%0.0%46.2%44.0%
CPU99.2%93.7%13.4%12.8%
DATA_READ0.1%3.8%0.0%0.0%
DATA_WRITE0.0%0.0%0.0%0.0%
XLOG_WRITE0.0%0.0%18.1%5.6%
XLOG_FLUSH0.0%0.0%0.0%0.0%
LWLOCK_WAIT0.7%2.4%22.3%0.6%
LOCK_WAIT0.0%0.0%0.0%37.1%
  • 1, 2 は参照のみなので CPU ネック。2 はバッファ不足のため若干 READ の影響がある。
  • 3 は更新があり、WAL 書き出しがネックになっている。
  • 4 は1行しかない表を更新するので、ロックに時間がかかっている。