10.2. 統計情報収集器

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

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

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

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

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

Important: STATS_COMMAND_STRINGSTATS_BLOCK_LEVELSTATS_ROW_LEVEL 変数はデフォルトで false ですので、デフォルトの設定では実際には統計情報は何も収集されません。統計情報表示機能を使用して有用な結果を得る前に、これらを 1 つまたは複数個設定しなければなりません。

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

統計情報の収集結果を表示するための、多くの定義済みのビューがあります。他にも、基礎的な統計情報関数を使用したカスタムビューを構築することもできます。

この統計情報を使用して、現在の活動状況を監視する場合、この情報は即座に更新されないことを認識することが重要です。個別のサーバプロセスは、他のクライアントからのコマンドを待つ直前に、新しいアクセス数を収集器に送信します。ですので、実行中の問い合わせは表示上の総和には影響を与えません。また、収集器自体もおよそ PGSTAT_STAT_INTERVAL(デフォルトでは 500 ミリ秒) に一度新しい総和を発行します。ですので、表示上の総和は実際の活動から遅れて表示されます。

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

Table 10-1. 標準統計情報ビュー

ビュー名説明
pg_stat_activityサーバプロセス当たり 1 行の形で、プロセスの PID、データベース、ユーザ、現在の問い合わせを表示します。現在の問い合わせの列はスーパユーザのみアクセスできます。他のユーザからは 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_ ビューは主に、バッファキャッシュの効率を評価する際に有用です。実ディスク読みとりの数がバッファヒットの数よりもかなり少ないのであれば、そのキャッシュはカーネル呼び出しを行なうことなく、ほとんどの読みとり要求を満足させています。

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

Table 10-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からNまでで、ただし、Nは活動中バックエンド数)設定します。以下の使用例を参照して下さい。
pg_stat_get_backend_pid(integer)integer バックエンドプロセスの PID。
pg_stat_get_backend_dbid(integer)oid バックエンドプロセスのデータベース ID。
pg_stat_get_backend_userid(integer)oid バックエンドプロセスのユーザ ID。
pg_stat_get_backend_activity(integer)text バックエンドプロセスの現在の問い合わせ。(呼び出し実行者がスーパユーザではない場合は NULL。)

注意: (blocks_fetched - 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;