統計情報収集器

PostgreSQL 8.0.0 文書
前のページ | 巻戻し | 第 23章データベース活動状況の監視 | 早送り | 次のページ

# 23.2. 統計情報収集器

PostgreSQLの統計情報収集器はサーバの活動状況に関する情報を収集し、報告するサブシステムです。 現在、収集器はテーブルとインデックスへのアクセスをディスクブロックおよび個々の行単位で数えることができます。 また、他のサーバプロセスによって現在実行されている問い合わせを正確に決定する機能を持ちます。

## 23.2.1. 統計情報収集のための設定

統計情報の収集によって問い合わせの実行に少しオーバヘッドが加わりますので、システムは情報を収集するようにもしないようにも設定することができます。 これは通常は`postgresql.conf`内で設定される、設定パラメータによって制御されます。 (設定パラメータの設定についての詳細は項16.4を参照してください。)

統計情報収集器を全て起動するには、stats_start_collectorパラメータを`true`に設定する必要があります。 これはデフォルトであり、推奨する設定ですが、統計情報に興味がなく、全ての残存するオーバヘッドを締め出したいのであれば無効にすることもできます。 (しかしこれによる成果はわずかなものです。) サーバ実行中にこのオプションを変更することができないことに注意してください。

stats_command_string、stats_block_level、stats_row_levelパラメータは、収集器に実際に送信される情報量を制御し、つまり、実行時に発生するオーバヘッドの量を決定します。 これらはそれぞれ、サーバプロセスが、現在のコマンド文字列、ディスクブロックレベルのアクセス統計、行レベルのアクセス統計を収集器に送信するかどうかを決定します。 通常、これらの変数は全てのサーバプロセスに適用できるように `postgresql.conf` 内で設定されます。 しかし、SETコマンドを使用して、個別のサーバプロセスで有効または無効にすることができます。 (一般ユーザがその活動を管理者に隠すことを防止するために、スーパーユーザのみが `SET` を使用してこれらのパラメータを変更することができます。)

> 注意: `stats_command_string`、`stats_block_level`、`stats_row_level`パラメータはデフォルトで `false` ですので、デフォルトの設定では実際には統計情報は何も収集されません。 統計情報収集器を使用して有用な結果を得る前に、これらを 1 つまたは複数個設定しなければなりません。

## 23.2.2. 収集した統計情報の表示

統計情報の収集結果を表示するための、多くの定義済みのビューがあり、表23-1 に一覧表示されています。 他にも、基礎的な統計情報関数を使用した独自のビューを構築することもできます。

この統計情報を使用して、現在の活動状況を監視する場合、この情報は即座に更新されないことを認識することが重要です。 個別のサーバプロセスは、待機状態になる直前に、新しいブロックアクセス数と行アクセス数を収集器に送信します。 ですので、実行中の問い合わせやトランザクションは表示上の総和には影響を与えません。 また、収集器自体もおよそ `pgstat_stat_interval` (デフォルトでは 500) ミリ秒に一度新しい報告を出力します。 ですので、表示上の情報は実際の活動から遅れて表示されます。 現在の問い合わせの情報は即座に収集器に報告されますが、表示されるようになる前に`pgstat_stat_interval`に従った遅延があります。

この他の重要なポイントは、いつサーバプロセスが統計情報を表示するように尋ねられるかです。 サーバプロセスは、まず収集器によって発行された最も最近の報告を取り出します。 そして、現在のトランザクションが終わるまで、全ての統計情報ビューと関数においてこのスナップショットを使用し続けます。 ですから、現在のトランザクションを続けている間、統計情報は変更されません。 これはバグではなく、特徴です。 なぜなら、これにより、知らない間に値が変更することを考慮することなく、統計情報に対して複数の問い合わせを実行し、その結果を相関することができるからです。 しかし、各問い合わせで新しい結果を取り出したい場合は、確実にトランザクションブロックの外側でその問い合わせを行なってください。

表 23-1. 標準統計情報ビュー

ビュー名 | 説明
--- | ---
`pg_stat_activity` | サーバプロセス当たり 1 行の形で、プロセスの ID、データベース、ユーザ、現在の問い合わせ、現在の問い合わせの実行開始時刻を表示します。 現在の問い合わせについてのデータは`stats_command_string`パラメータが有効な場合にのみ表示されます。 更に、その列は、ビューを確認するユーザがスーパーユーザ、あるいは、報告対象プロセスを所有するユーザと同じでなければ NULL として読み出されます。 (収集器による報告の遅れのため、現在の問い合わせは長時間実行中の問い合わせにおいてのみ現在のものを表します。)
`pg_stat_database` | データベース当たり 1 行の形で、そのデータベースに対して、活動中のバックエンドサーバ数、コミットされたトランザクションの総数、ロールバックされたトランザクションの総数、読み取られたディスクブロックの総数、バッファヒット (つまり、バッファキャッシュに対象とするブロックが存在するために防止されたブロック読み取り要求) の総数を表示します。
`pg_stat_all_tables` | 現在のデータベース内の各テーブルに関する、シーケンシャルスキャン、インデックススキャンの総数、各種スキャンによって返された行の総数、挿入、更新、削除された行の総数。
`pg_stat_sys_tables` | システムテーブルのみが表示される点を除き、`pg_stat_all_tables` と同じです。
`pg_stat_user_tables` | ユーザテーブルのみが表示される点を除き、`pg_stat_all_tables` と同じです。
`pg_stat_all_indexes` | 現在のデータベース内の各インデックスに関する、そのインデックスを使用したインデックススキャン数、読み取られたインデックス行数、正常に抽出されたヒープ行数 (この値は、有効期限切れとなったヒープ行を示すインデックス項目がある時に小さくなります)。
`pg_stat_sys_indexes` | システムテーブルのインデックスのみが表示される点を除き、`pg_stat_all_indexes` と同じです。
`pg_stat_user_indexes` | ユーザテーブルのインデックスのみが表示される点を除き、`pg_stat_all_indexes` と同じです。
`pg_statio_all_tables` | 現在のデータベース内の各テーブルに関する、そのテーブルから読み取られたディスクブロックの総数、バッファヒット数、そのテーブルに関する全てのインデックスに関する読み取られたディスクブロック数とバッファヒット数、(存在する場合)そのテーブルの補助的な TOAST テーブルから読み取られたディスクブロック数とバッファヒット数、TOAST テーブルのインデックスに関する読み取られたディスクブロック数とバッファヒット数。
`pg_statio_sys_tables` | システムテーブルのみが表示される点を除き、`pg_statio_all_tables` と同じです。
`pg_statio_user_tables` | ユーザテーブルのみが表示される点を除き、`pg_statio_all_tables` と同じです。
`pg_statio_all_indexes` | 現在のデータベース内の各インデックスに関する、そのインデックスの読み取られたディスクブロック数とバッファヒット数。
`pg_statio_sys_indexes` | システムテーブルのインデックスのみが表示される点を除き、`pg_statio_all_indexes` と同じです。
`pg_statio_user_indexes` | ユーザテーブルのインデックスのみが表示される点を除き、`pg_statio_all_indexes` と同じです。
`pg_statio_all_sequences` | 現在のデータベース内の各シーケンスオブジェクトに関する、そのシーケンスの読み取られたディスクブロック数とバッファヒット数。
`pg_statio_sys_sequences` | システムシーケンスのみが表示される点を除き、`pg_statio_all_sequences` と同じです。 (現時点では、システムシーケンスは定義されていませんので、このビューは常に空です。)
`pg_statio_user_sequences` | ユーザシーケンスのみが表示される点を除き、`pg_statio_all_sequences` と同じです。

インデックス単位の統計情報は、どのインデックスが使用され、どの程度効果があるのかを評価する際に、特に有用です。

`pg_statio_` ビューは主に、バッファキャッシュの効率を評価する際に有用です。 実ディスク読み取りの数がバッファヒットの数よりもかなり少ないのであれば、そのキャッシュはカーネル呼び出しを行なうことなく、ほとんどの読み取り要求を満足させています。 しかし、PostgreSQLバッファキャッシュに存在しないデータはカーネルのI/Oキャッシュにある可能性があり、そのため、物理的な読み取りを行うことなく取り出される可能性があるというPostgreSQLのディスクI/Oの取扱いのため、これらの統計情報は、完全な論拠を提供しません。 PostgreSQL I/O動作に関するより詳細な情報を入手したいのであれば、PostgreSQL統計情報収集器とカーネルのI/Oの取扱いの監視を行うオペレーティングシステムユーティリティを組み合わせることを勧めます。

統計情報を参照する他の方法は、上述の標準ビュー同様に、基礎的な統計情報アクセス関数を使用した問い合わせを作成することで設定することができます。 これらの関数は 表23-2 にリストされています。 データベース毎のアクセス関数は、どのデータベースに対して報告するのかを識別するためにデータベースの OID を受け付けます。 テーブル毎、インデックス毎の関数はテーブルの、もしくは、インデックスの OID を受け付けます。 (この関数を使用して参照できるテーブルとインデックスは現在のデータベース内のものだけであることに注意してください。) バックエンドプロセス毎のアクセス関数はバックエンドプロセス ID 番号を受け付けます。 取り得る範囲は1から現時点で活動中のバックエンドプロセスの数までです。

表 23-2. 統計情報アクセス関数

関数 | 戻り値の型 | 説明
--- | --- | ---
``pg_stat_get_db_numbackends`(`oid`)` | `integer` | データベース内で活動中のバックエンド数。
``pg_stat_get_db_xact_commit`(`oid`)` | `bigint` | データベース内でコミットされたトランザクション。
``pg_stat_get_db_xact_rollback`(`oid`)` | `bigint` | データベース内でロールバックされたトランザクション。
``pg_stat_get_db_blocks_fetched`(`oid`)` | `bigint` | データベースに関する、ディスクブロック抽出要求数。
``pg_stat_get_db_blocks_hit`(`oid`)` | `bigint` | データベースに関する、ディスクブロック要求の内キャッシュに存在した数。
``pg_stat_get_numscans`(`oid`)` | `bigint` | 引数がテーブルの場合、シーケンシャルスキャンの実行回数。 引数がインデックスの場合インデックススキャンの実行回数。
``pg_stat_get_tuples_returned`(`oid`)` | `bigint` | 引数がテーブルの場合、シーケンシャルスキャンによって読み取られた行数。 引数がインデックスの場合、読み取られたインデックス行数。
``pg_stat_get_tuples_fetched`(`oid`)` | `bigint` | 引数がテーブルの場合、シーケンシャルスキャンで抽出された、有効な(破棄されていない)テーブル行数。 引数がインデックスの場合、このインデックスを使用したインデックススキャンで抽出された、有効な(破棄されていない)テーブル行数。
``pg_stat_get_tuples_inserted`(`oid`)` | `bigint` | テーブルに挿入された行数。
``pg_stat_get_tuples_updated`(`oid`)` | `bigint` | テーブルで更新された行数。
``pg_stat_get_tuples_deleted`(`oid`)` | `bigint` | テーブルで削除された行数。
``pg_stat_get_blocks_fetched`(`oid`)` | `bigint` | テーブル、または、インデックスに関する、ディスクブロック抽出要求数。
``pg_stat_get_blocks_hit`(`oid`)` | `bigint` | テーブル、または、インデックスに関する、ディスクブロック抽出要求の内キャッシュ内に存在した数。
``pg_stat_get_backend_idset`()` | `set of integer` | 現在活動中のバックエンド ID を(1から活動中バックエンドプロセス数までの間で)設定します。 以下の使用例を参照してください。
``pg_backend_pid`()` | `integer` | 現在のセッションに接続するバックエンドプロセスのプロセス ID。
``pg_stat_get_backend_pid`(`integer`)` | `integer` | 指定されたバックエンドプロセスのプロセス ID。
``pg_stat_get_backend_dbid`(`integer`)` | `oid` | 指定されたバックエンドプロセスのデータベース ID。
``pg_stat_get_backend_userid`(`integer`)` | `oid` | 指定されたバックエンドプロセスのユーザ ID。
``pg_stat_get_backend_activity`(`integer`)` | `text` | バックエンドプロセスの現在の問い合わせ。 (現在のユーザがスーパーユーザではない場合や問い合わせ先セッションのユーザと異なる場合、`stats_command_string`が無効な場合は NULL。)
``pg_stat_get_backend_activity_start`(`integer`)` | `timestamp with time zone` | 指定されたバックエンドプロセスが実行中の問い合わせが開始した時刻。 (現在のユーザがスーパーユーザではない場合や問い合わせ先セッションのユーザと異なる場合、`stats_command_string`が無効な場合は NULL。)
``pg_stat_reset`()` | `boolean` | 現在までに収集された統計情報を全てリセット。

> 注意: `pg_stat_get_db_blocks_fetched`から`pg_stat_get_db_blocks_hit`を引くと、そのテーブル、インデックス、データベースに対して発行されたカーネルの`read()`コール数がわかります。 しかし、実際の物理的な読み取り数は、カーネルレベルのバッファ処理のために通常これより小さくなります。

`pg_stat_get_backend_idset` 関数は、活動中バックエンドプロセスそれぞれについて1行を作成する簡便な方法を提供します。 例えば、全てのバックエンドプロセスの PID と現在の問い合わせを表示するには、以下を行います。

    SELECT pg_stat_get_backend_pid(s.backendid) AS procpid,
           pg_stat_get_backend_activity(s.backendid) AS current_query
        FROM (SELECT pg_stat_get_backend_idset() AS backendid) AS s;

前のページ | ホーム | 次のページ
データベース活動状況の監視 | 上に戻る | ロックの表示