[11/15開催: PostgreSQL Conference Japan 2019 参加受付中] 
他のバージョンの文書 11 | 10 | 9.6 | 9.5 | 9.4 | 9.3 | 9.2 | 9.1 | 9.0 | 8.4 | 8.3 | 8.2 | 8.1 | 8.0 | 7.4 | 7.3 | 7.2

名前

pgbenchPostgreSQLに対してベンチマーク試験を行う

概要

pgbench -i [option...] [dbname]

pgbench [option...] [dbname]

説明

pgbenchPostgreSQL上でベンチマーク試験を行う単純なプログラムです。 これは同一のSQLコマンドの並びを何度も実行します。複数の同時実行データベースセッションで実行することもできます。 そして、トランザクションの速度(1秒当たりのトランザクション数)の平均を計算します。 デフォルトでpgbenchは、1トランザクション当たり5つのSELECTUPDATEINSERTコマンドを含むおおよそTPC-Bに基いたシナリオを試験します。 しかし、独自のトランザクションスクリプトファイルを作成することで他の試験ケースを簡単に実行することができます。

pgbenchの典型的な出力を以下に示します。

transaction type: <builtin: TPC-B (sort of)>
scaling factor: 10
query mode: simple
number of clients: 10
number of threads: 1
number of transactions per client: 1000
number of transactions actually processed: 10000/10000
tps = 85.184871 (including connections establishing)
tps = 85.296346 (excluding connections establishing)

最初の6行はいくつかの最重要パラメータの設定を表示しています。 次行が完了トランザクション数と予定トランザクション数です(後者は単なるクライアント数とクライアント毎のトランザクション数の積算結果です。) 実行が完了する前に失敗しない限りこれは等しくなります。 (-Tモードでは、トランザクションの実際の数が表示されます) 最後の2行は、データベースセッションを開始するための時間を含める場合と含めない場合の1秒当たりのトランザクション数を示します。

デフォルトのTPC-Bと似たトランザクション試験では、あらかじめ設定する特定のテーブルが必要です。 これらのテーブルを作成し、データを投入するためには、-i(初期化)オプションを付けてpgbenchを呼び出さなければなりません。 (独自スクリプトを試験する場合、この手順は必要ありません。 しかし代わりに試験に必要な何らかの設定を行わなければならないでしょう。) 初期化は以下のようになります。

pgbench -i [ other-options ] dbname

ここでdbnameは試験用に前もって作成されたデータベースの名前です。 (またデータベースサーバの接続方法を指定するために、-h-p-Uが必要になるかもしれません。)

注意

pgbench -iは4つのテーブルpgbench_accountspgbench_branchespgbench_historypgbench_tellersを作成します。 もしあればこうした名前のテーブルは破壊されます。 もし同じ名前のテーブルが存在する場合にはよく注意してください。

デフォルトの倍数の1では、テーブルは初期状態で以下の行数を含みます。

table                   # of rows
---------------------------------
pgbench_branches        1
pgbench_tellers         10
pgbench_accounts        100000
pgbench_history         0

-s(倍数)オプションを使用して行数を増加させることができます(また、ほとんどの目的ではおそらく増加させるべきです)。 また、-F (フィルファクタ)オプションをここで使用しても構いません。

一度この必要な設定を行った後、以下のように-iを持たないコマンドでベンチマークを行うことができます。

pgbench [ options ] dbname

ほとんどすべての場合、有用な試験とするためにいくつかのオプションが必要になります。 最重要オプションは-c(クライアント数)、-t(トランザクション数)、-T (制限時間)、-f(独自スクリプトファイルの指定)です。 以下の全一覧を参照してください。

オプション

以下では、データベース初期化時に使用されるオプション、ベンチマーク実行時に使用されるオプション、どちらの場合でも使われるオプションの3つに分けて説明します。

初期化用のオプション

pgbenchは以下の初期化用のコマンドライン引数を受け付けます。

-i
--initialize

初期化モードを呼び出すために必要です。

-F fillfactor
--fillfactor=fillfactor

指定したフィルファクタでpgbench_accountspgbench_tellerspgbench_branchesテーブルを作成します。 デフォルトは100です。

-n
--no-vacuum

初期化の後にバキューム処理を行いません。

-q
--quiet

ログ処理を、5秒に1つの進行メッセージのみを生成する静寂モードに切り替えます。 デフォルトのログ処理では、10000行毎にメッセージを1つ出力し、(特に優れたハードウェアでは)1秒当たりに多くのメッセージを出力します。

-s scale_factor
--scale=scale_factor

この倍率で生成される行数を積算します。 例えば、-s 100pgbench_accountsテーブルに10,000,000行を生成することを意味します。 デフォルトは1です。 この倍率が20000以上になると、アカウント識別子の範囲を保持できる程度に大きくなるように、アカウント識別子を保持するために使用される列(aid列)はより大きな整数(bigint)を使用するように切り替わります。

--foreign-keys

標準テーブル間で外部キー制約を作成します。

--index-tablespace=index_tablespace

デフォルトのテーブル空間ではなく、指定したテーブル空間の中にインデックスを作成します。

--tablespace=tablespace

デフォルトのテーブル空間ではなく、指定したテーブル空間の中にテーブルを作成します。

--unlogged-tables

永続テーブルではなくログを取らないテーブルとしてテーブルを作成します。

ベンチマーク用オプション

pgbenchは以下のベンチマーク用コマンドライン引数を受け付けます。

-b scriptname[@weight]
--builtin=scriptname[@weight]

指定の組み込みスクリプトを実行されたスクリプトのリストに追加します。 オプションで@の後に整数のweight(重み)をつけることで、そのスクリプトが選ばれる確率を調整することができます。 指定しなかった場合は1に設定されます。 利用可能な組み込みのスクリプトは、tpcb-likesimple-updateselect-onlyです。 組み込みの名前の曖昧な接頭辞も受け付けられます。 特別な名前listを使うと、組み込みスクリプトのリストを表示して、即座に終了します。

-c clients
--client=clients

模擬するクライアント数、つまり、同時に実行されるデータベースセッション数です。 デフォルトは1です。

-C
--connect

各クライアントセッションが一度だけ接続を確立するのではなく、各トランザクションが新しい接続を確立します。 これは接続オーバーヘッドを測定する場合に有用です。

-d
--debug

デバッグ用出力を表示します。

-D varname=value
--define=varname=value

独自スクリプト(後述)で使用される変数を定義します。 複数の-Dオプションを使用することができます。

-f filename[@weight]
--file=filename[@weight]

filenameから読み取ったトランザクションスクリプトを実行されたスクリプトのリストに追加します。 オプションで@の後に整数のweight(重み)をつけることで、そのテストが選ばれる確率を調整することができます。 詳細は後で説明します。

-j threads
--jobs=threads

pgbench内のワーカスレッド数です。 複数のスレッドを使用することはマルチCPUマシンで有用になります。 クライアントは利用可能なスレッドの間でできる限り均等に分散されます。 デフォルトは1です。

-l
--log

各トランザクションで費やした時間をログファイルに書き出します。 後で詳細を説明します。

-L limit
--latency-limit=limit

limitミリ秒以上続くトランザクションが計数され、別途遅いトランザクションとして報告されます。

制限が使用されると(--rate=...)、limitミリ秒以上遅延がスケジュールされたトランザクションは遅延制限を満たす可能性がないため、サーバに送信されることは決してありません。 これらのトラザクションは計数され、別途スキップされたとして報告されます。

-M querymode
--protocol=querymode

サーバへ問い合わせを送信するために使用するプロトコルです。

  • simple: 簡易問い合わせプロトコルを使用します。

  • extended: 拡張問い合わせプロトコルを使用します。

  • prepared: プリペアドステートメントを伴う拡張問い合わせプロトコルを使用します。

デフォルトは簡易問い合わせプロトコルです。 (詳しい情報は51章フロントエンド/バックエンドプロトコルを参照してください)

-n
--no-vacuum

試験を実行する前にバキュームを行いません。 pgbench_accountspgbench_branchespgbench_historypgbench_tellers標準テーブルを含まない独自試験シナリオを実行する場合、このオプションは必要です。

-N
--skip-some-updates

組み込みのsimple-update(単純な更新)のスクリプトを実行します。 -b simple-updateの短縮形です。

-P sec
--progress=sec

sec秒毎の進捗レポートを表示します。 レポートには起動からの経過時間、前回レポート時からのtps、前回レポート時からのトランザクションの平均待ち時間、標準偏差を含んでいます。 (-R)オプションによる制限下では、待ち時間はトランザクションの実開始時間ではなく、予定開始時間で算出されていますので、平均予定遅延時間が含まれています。

-r
--report-latencies

ベンチマーク完了後の各コマンドにおけるステートメント毎の平均レイテンシ(クライアントから見た実行時間)を報告します。詳しくは下を参照してください。

-R rate
--rate=rate

トランザクションを可能な限り高速(デフォルト)で実行するのではなく、指定された目標レートで実行します。 レートは1秒あたりのトランザクション数で与えられます。目標レートが実施可能な最大レートを越えている場合、レート制限は結果に影響を与えません。

レートはトランザクションの開始予定タイムラインがポアソン分布に沿う事を目標としています。 期待される開始時刻の予定は、前トランザクションの終了時ではなくクライアントの初期起動時に基づいて動かします。 このアプローチはトランザクションがオリジナルの終了予定時刻を過ぎた場合でも、後でまた追い付けることを意味します。

制限がアクティブになると、実行終了時に報告されるトランザクション待ち時間は、予定開始時刻から計算されるので、 各トランザクションが前トランザクションの終了を待たねばならなかった時間を含んでいます。 この待ち時間はスケジュールラグタイムと呼ばれ、平均と最大値も別々に報告されます。 実トランザクション開始時刻についてのトランザクション待ち時間、つまりデータベース内でトランザクションの実行に要した時間は、報告された待ち時間からスケジュールラグタイムを減算することで算出することができます。

--latency-limit--rateと一緒に指定された場合、トランザクションは、先行するトランザクションが終了した際にすでに遅延制限を超えていて、非常に遅れてしまうことがあり得ます。 そのようなトランザクションはサーバに送信さることなくスキップされ、別途カウントされます。

スケジュールラグタイムの高い値は、システムが選択されたクライアント数とスレッド数で、指定されたレートでトランザクションを処理できなかったことを示しています。 トランザクションの平均実行時間が各トランザクション間で予定されていた間隔より長い場合、各逐次トランザクションは更に遅くなり、 スケジュールラグタイムはテスト実行がより長く増加し続けます。 これが起こる場合、指定トランザクションレートを減らす必要があります。

-s scale_factor
--scale=scale_factor

pgbenchの出力で指定した倍率を報告します。 これは組み込みの試験では必要ありません。 正確な倍率がpgbench_branchesテーブルの行数を数えることで検出されます。 しかし、独自ベンチマーク(-fオプション)のみを試験している場合、このオプションを使用しない限り、倍率は1として報告されます。

-S
--select-only

組み込みのselect-only(SELECTのみ)のスクリプトを実行します。 -b select-onlyの短縮形です。

-t transactions
--transactions=transactions

各クライアントが実行するトランザクション数です。 デフォルトは10です。

-T seconds
--time=seconds

クライアントあたりのトランザクション数を固定で指定するよりも長くテストを実行したい場合、ここに指定した秒数でテストを実行します。 -t-Tは互いに排他的です。

-v
--vacuum-all

試験前に4つの標準テーブルすべてをバキュームを行います。 -n-vもなければ、pgbenchはpgbench_tellerspgbench_branchesテーブルをバキュームし、pgbench_history内のデータをすべて消去します。

--aggregate-interval=seconds

集約間隔の長さ(秒単位)です。 これは-lと一緒でのみ使用される可能性があります。 このオプションを付けると、ログには指定間隔単位の要約(トランザクション数、最大レイテンシ、最小レイテンシ、分散の推定に役に立つ2つの追加フィールド)が含まれます。

現在このオプションはWindowsではサポートされていません。

--progress-timestamp

進捗を表示(-Pオプション)しているとき、実行開始以後の経過秒数の代わりにタイムスタンプ(Unixエポック時刻)を使用します。 単位は秒で、ドットの後にミリ秒の精度が付きます。 これは様々なツールで生成されたログを比較するのに役立つでしょう。

--sampling-rate=rate

データをログに書き出す際に使用される、生成されるログの量を減少するためのサンプリング割合です。 このオプションが指定された場合、指定された割合のトランザクションがログに残ります。 1.0はすべてのトランザクションが、0.05はトランザクションの5%のみがログに残ることを意味します。

ログファイルを処理する際にはこのサンプリング割合を考慮することを忘れないでください。 例えば、tps値を計算する際には、比例した数を掛け合わせなければなりません(例:サンプリング割合が0.01の場合実際のtpsの1/100を得るだけです。)

共通オプション

pgbenchは以下の共通コマンドライン引数を受け付けます。

-h hostname
--host=hostname

データベースサーバのホスト名

-p port
--port=port

データベースサーバのポート番号

-U login
--username=login

接続ユーザ名

-V
--version

pgbenchのバージョンを表示し、終了します。

-?
--help

pgbenchのコマンドライン引数の説明を表示し、終了します。

注釈

pgbenchで実際に実行されるトランザクションは何か?

pgbenchは指定したリストからランダムに選択したテストスクリプトを実行します。 これには-bの組み込みスクリプトと-fのユーザ定義カスタムスクリプトが含まれます。 各スクリプトには@の後に指定される相対的な重みを与えることができ、それが選ばれる確率を変更することができます。 デフォルトの重みは1です。 重みが0のスクリプトは無視されます。

デフォルトの組み込みトランザクションスクリプト(-b tpcb-likeとすることでも実行されます)は、aidtidbidbalanceからランダムに選択され、トランザクション毎に7つのコマンドを発行します。 このシナリオはTPC-Bベンチマークに示唆を受けたものですが、実際にはTPC-Bではないので、この名前になっています。

  1. BEGIN;

  2. UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;

  3. SELECT abalance FROM pgbench_accounts WHERE aid = :aid;

  4. UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;

  5. UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;

  6. INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);

  7. END;

simple-updateの組み込みを選択した(あるいは-Nを指定した)場合、第4ステップと第5ステップはトランザクションに含まれません。 これにより、これらのテーブルに対する更新の競合を避けられますが、テストケースはさらにTPC-Bらしくなくなります。

select-onlyの組み込みを選択した(あるいは-Sを指定した)場合、SELECTのみが発行されます。

独自スクリプト

pgbenchは、ファイルから読み込んだトランザクションスクリプト(-fオプション)でデフォルトのトランザクションスクリプト(上述)を置き換えて独自のベンチマークシナリオを実行する機能をサポートします。 この場合、トランザクションはスクリプトファイルの1回の実行として数えられます。

スクリプトファイルにはセミコロンで終了するSQLコマンドが1つ以上含まれます。 空行および--から始まる行は無視されます。 スクリプトファイルの行には、pgbench自身が解釈するメタコマンド(後述)も記述することができます。

注記

PostgreSQLの9.6より前では、スクリプトファイル内のSQLコマンドは改行で終了しており、そのため行をまたがって継続することができませんでした。 これからは連続するSQLコマンドを区切るためにセミコロンが必要です(ただし、SQLコマンドの後にメタコマンドが続く場合は、セミコロンは必要ありません)。 pgbenchの古いバージョンと新しいバージョンの両方で動作するスクリプトを作る必要があるなら、各SQLコマンドを1行で書き、終わりにセミコロンを付けるようにしてください。

スクリプトファイル向けの簡単な変数置換機能があります。 上で説明したように変数を-Dコマンドラインオプションで設定することができます。 また、後で説明するようにメタコマンドで設定することもできます。 -Dコマンドラインオプションで設定された変数の他に、表237「自動変数」に記載されているように、自動的に設定される変数がいくつかあります。 -D を使ってこれらの変数に設定された値は、自動設定の値より優先されます。 一度設定すると、変数の値は、:variablenameと書かれてSQLコマンドに挿入されます。 1つ以上のクライアントセッションが実行される場合、セッション毎に独自の変数群を持ちます。

表237 自動変数

変数説明
scale 現在のスケールファクタ
client_id クライアントセッションを識別する一意の数値(ゼロから始まる)

スクリプトファイルメタコマンドはバックスラッシュ(\)から始まり、行末まで続きます。 メタコマンドへの引数は空白文字で区切られます。 以下のメタコマンドがサポートされています。

\set varname expression

varname変数をexpressionから計算された値に設定します。 expression(式)には、5432のような整数の定数、3.14159のような倍精度実数の定数、変数を参照する :variablename、通常の優先順位と結合規則に従う単項演算子(+-)と2項演算子(+-*/%)、関数呼び出し、括弧を含むことができます。

\set ntellers 10 * :scale
\set aid (1021 * random(1, 100000 * :scale)) % (100000 * :scale) + 1
\sleep number [ us | ms | s ]

スクリプトの実行をマイクロ秒(us)、ミリ秒(ms)、秒(s)単位で指定した間待機させます。 単位を省略した場合、デフォルトは秒です。 numberは整数定数か整数値を持つ変数への:variablename参照のいずれかです。

\sleep 10 ms
\setshell varname command [ argument ... ]

commandシェルコマンドを指定のargumentで実行した結果をvarname変数に設定します。 このコマンドは標準出力を通して整数値を返さなければなりません。

commandおよび各argumentは、テキスト定数または変数を参照する:variablenameとすることができます。 コロンから始まるargumentを使用したい場合、argumentの先頭にさらにコロンを付けなければなりません。

例:

\setshell variable_to_be_assigned command literal_argument :variable ::literal_starting_with_colon
\shell command [ argument ... ]

\setshellと同じですが、コマンドの結果は廃棄されます。

例:

\shell command literal_argument :variable ::literal_starting_with_colon

組み込み関数

表238「pgbenchの関数」に示す関数はpgbenchに組み込まれており、\setに現れる式の中で使うことができます。

表238 pgbenchの関数

関数戻り型説明結果
abs(a)aと同じ絶対値abs(-17)17
debug(a)aと同じastderrに出力し、aを返すdebug(5432.1)5432.1
double(i)double倍精度実数にキャストするdouble(5432)5432.0
greatest(a [, ... ] )aのどれかがdoubleならdouble、そうでなければinteger引数の中で最大の値greatest(5, 4, 3, 2)5
int(x)integer整数にキャストするint(5.4 + 3.8)9
least(a [, ... ] )aのどれかがdoubleならdouble、そうでなければinteger引数の中で最小の値least(5, 4, 3, 2.1)2.1
pi()double定数PI(円周率)の値pi()3.14159265358979323846
random(lb, ub)integer[lb, ub]内の一様分布の整数の乱数random(1, 10)110の間の整数
random_exponential(lb, ub, parameter)integer[lb, ub]内の指数分布の整数の乱数、後述random_exponential(1, 10, 3.0)110の間の整数
random_gaussian(lb, ub, parameter)integer[lb, ub]内のガウス分布の整数の乱数、後述random_gaussian(1, 10, 2.5)110の間の整数
sqrt(x)double平方根sqrt(2.0)1.414213562

random関数は一様分布を使って値を生成します。 つまり、すべての値は指定された範囲内で同じ確率で発生します。 random_exponential関数とrandom_gaussian関数は、追加の倍精度実数のパラメータを必要とし、それによって分布の正確な形が決まります。

  • 指数分布では、parameterが分布を制御します。 急速に減少する指数分布をparameterで切り捨て、境界範囲内の整数に射影します。 正確には、以下の式に従います。

    f(x) = exp(-parameter * (x - min) / (max - min + 1)) / (1 - exp(-parameter))

    これにより、minmaxの間(両端を含む)の間の値if(i) - f(i + 1)の確率で生成されます。

    直感的には、parameterが大きければ、minに近い値が発生する確率が高くなり、maxに近い値が発生する確率が低くなります。 parameterが0に近ければ、発生の分布はより平ら(より一様)になります。 大雑把に分布を近似すると、minに近い最頻の1%の範囲の値は、parameter%の割合で発生します。 parameterの値は厳密に正でなければなりません。

  • ガウス分布では、標準的な正規分布(古典的なベルの形をしたガウス曲線)で、左に-parameter、右に+parameterのところで切り捨てられたものに間隔が射影されます。 間隔の中間の値が発生する確率が最も高くなります。 正確に言うと、PHI(x)は標準正規分布の累積分布関数、平均値mu(max + min) / 2.0と定義し、さらに

    f(x) = PHI(2.0 * parameter * (x - mu) / (max - min + 1)) /
           (2.0 * PHI(parameter) - 1)

    とすると、minmaxの間(両端を含む)の値iが発生する確率はf(i + 0.5) - f(i - 0.5)になります。 直感的には、parameterが大きくなれば、間隔の中間に近い値になる確率が高く、また、minmaxの境界に近い値になる確率は低くなります。 約67%の値は、中間の1.0 / parameterの範囲、つまり平均値から0.5 / parameterの範囲から、また95%は中間の2.0 / parameterの範囲、つまり平均値から1.0 / parameterの範囲に発生します。 例えばparameterが4.0なら、67%の値は間隔の中間の4分の1(1.0/4.0)から(つまり3.0 / 8.0から5.0 / 8.0まで)、95%は間隔の中間の半分(2.0 / 4.0)から(2番目と3番目の四分位)から発生します。 ボックス=ミュラーの変換のパフォーマンスのため、最小のparameterは2.0です。

例えば、組み込みのTPC-Bのようなトランザクションの完全な定義を示します。

\set aid random(1, 100000 * :scale)
\set bid random(1, 1 * :scale)
\set tid random(1, 10 * :scale)
\set delta random(-5000, 5000)
BEGIN;
UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
END;

このスクリプトにより、トランザクションを繰り返す度に異なる、ランダムに選ばれた行を参照することができます。 (この例はまた、各クライアントセッションがなぜ独自の変数を持つことが重要なのかも表しています。 これがないと、異なる行を独立して参照することができないのです。)

トランザクション毎のログ処理

--aggregate-intervalを付けずに-lオプションを使用すると、 pgbenchは各トランザクションで要した時間をログファイルに書き出します。 ログファイルの名前はpgbench_log.nnnです。 ここでnnnはpgbenchプロセスのPIDです。 -jオプションが2以上の場合、それぞれ独自のログファイルを持つ複数のワーカスレッドが生成されます。 最初のワーカは標準的な単一ワーカの場合と同じ名前を持つログファイルを使用します。 他のワーカ用の追加のログファイルはpgbench_log.nnn.mmmのように命名されます。 ここでmmmは1から始まる各ワーカの連番です。

ログの書式は以下の通りです。

client_id transaction_no time script_no time_epoch time_us [schedule_lag]

ここでtimeはマイクロ秒単位の総トランザクション処理時間、 script_noは使用されたスクリプトファイルを識別するもの(-fまたは-bにより複数のスクリプトが指定された場合に有用)、 time_epoch/time_usはマイクロ秒のオフセットを持つUNIXエポック書式のタイムスタンプ(小数秒付きのISO 8601タイムスタンプの作成に適します) でトランザクションの完了時刻を示します。 フィールドschedule_lagは、マイクロ秒単位のトランザクションの予定開始時刻と実開始時刻の差です。 これは--rateオプションを使用した時だけ表示されます。 --rate--latency-limitの両方のオプションを使用した時は、スキップされたトランザクションのtimeskippedとして表示されます。

生成されたログファイルの一部を示します。

0 199 2241 0 1175850568 995598
0 200 2465 0 1175850568 998079
0 201 2513 0 1175850569 608
0 202 2038 0 1175850569 2663

--rate=100 と --latency-limit=5 を指定した例を示します。(schedule_lag列が追加されていることに注意)

0 81 4621 0 1412881037 912698 3005
0 82 6173 0 1412881037 914578 4304
0 83 skipped 0 1412881037 914578 5217
0 83 skipped 0 1412881037 914578 5099
0 83 4722 0 1412881037 916203 3108
0 84 4142 0 1412881037 918023 2333
0 85 2465 0 1412881037 919759 740

この例では、トランザクション82は遅延(6.173ミリ秒)が5ミリ秒を越えており、遅れています。 次の2つのトランザクションは、開始する前にすでに遅れてしまっているため、スキップされています。

大量のトランザクションを処理することができるハードウェアで長時間試験を実行する場合、ログファイルは非常に大きくなる可能性があります。 --sampling-rateオプションを使用して、トランザクションのランダムなサンプルだけをログに記録することができます。

ログ処理の集約

--aggregate-intervalオプションを付ける場合、以下のようにログの書式が多少異なります。

interval_start num_of_transactions latency_sum latency_2_sum min_latency max_latency [lag_sum lag_2_sum min_lag max_lag [skipped_transactions]]

ここで、interval_startはインターバルの開始時刻(Unixエポック書式のタイムスタンプ)、 num_of_transactionsはインターバル内のトランザクション数、 latency_sumはレイテンシの総和です(これらを使って簡単に平均レイテンシを計算できます)。 以下2つのフィールドは分散推定の際に有用です。 latency_sumはレイテンシの総和であり、latency_2_sumはレイテンシの二乗の総和です。 次の2つのフィールドは、インターバル内の最小レイテンシであるmin_latencyと、インターバル内の最大レイテンシであるmax_latencyです。 インターバル内でコミットされた時点でトランザクションとしてカウントされます。 最後の方のフィールドlag_sumlag_2_summin_lagmax_lag--rateオプションが使われた時だけ表示されます。 最後のskipped_transactionsもやはり--latency-limitが指定された時だけ表示されます。 これらは、各トランザクションが前のトランザクション終了を待つ時間、つまり各トランザクションの予定開始時刻と実開始時刻の差から算出されます。

以下に出力例を示します。

1345828501 5601 1542744 483552416 61 2573
1345828503 7884 1979812 565806736 60 1479
1345828505 7208 1979422 567277552 59 1391
1345828507 7685 1980268 569784714 60 1398
1345828509 7073 1979779 573489941 236 1411

通常の(集約されていない)ログファイルには、カスタムスクリプトファイルへの参照が含まれますが、集約されたログには含まれません。 このためスクリプト単位のデータが必要な場合は、自身でデータを集約しなければなりません。

ステートメント毎のレイテンシ

-rオプションを付けると、pgbenchは各クライアントにより実行されたトランザクションのステートメント毎の経過時間を収集します。 ベンチマークが終了した後、各値の平均値(各ステートメントのレイテンシと呼びます)が報告されます。

標準スクリプトでは、次のような出力になります。

starting vacuum...end.
transaction type: <builtin: TPC-B (sort of)>
scaling factor: 1
query mode: simple
number of clients: 10
number of threads: 1
number of transactions per client: 1000
number of transactions actually processed: 10000/10000
latency average = 15.844 ms
latency stddev = 2.715 ms
tps = 618.764555 (including connections establishing)
tps = 622.977698 (excluding connections establishing)
script statistics:
 - statement latencies in milliseconds:
        0.002  \set aid random(1, 100000 * :scale)
        0.005  \set bid random(1, 1 * :scale)
        0.002  \set tid random(1, 10 * :scale)
        0.001  \set delta random(-5000, 5000)
        0.326  BEGIN;
        0.603  UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid;
        0.454  SELECT abalance FROM pgbench_accounts WHERE aid = :aid;
        5.528  UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid;
        7.335  UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid;
        0.371  INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP);
        1.212  END;

複数のスクリプトファイルが定義された場合、平均値はそれぞれのスクリプトファイル毎に分けて報告されます。

ステートメント毎のレイテンシを計算するために必要となる、追加のタイミング情報を収集することは、オーバーヘッドが加わることに注意してください。 これは平均実行速度を遅くし、計測TPSを小さくするでしょう。 低下量はプラットフォームとハードウェアに依存して著しく変わります。 レイテンシの報告を有効にする、有効にしないで平均TPS値を比較することは、タイミング・オーバーヘッドが顕著かどうかを測定するには良い方法です。

優れた実践

まったく無意味な数値を生み出すようにpgbenchを使用することは非常に簡単です。 以下に有意な結果を生み出す手助けとなるガイドラインをいくつか示します。

まず第一に、数秒で終わる試験を決して信用しないでください。 -tまたは-Tオプションを使って、雑音を取り除くために、少なくとも数分試験にかかるようにしてください。 再現可能な数値を得るために数時間必要になる場合もあります。 数回試験を繰り返し、数値が再現できるかどうか確認することを勧めます。

デフォルトのTPC-Bのような試験シナリオでは、初期倍率(-s)を試験予定のクライアント数(-c)の最大値と同程度にしなければなりません。 pgbench_branchesテーブルには-s行しかありません。 また、全トランザクションはその内の1つを更新しようとします。 ですので、-c値を-sより大きくすると、他のトランザクションを待機するためにブロックされるトランザクションが多くなることは間違いありません。

デフォルトの試験シナリオはまた、テーブルを初期化してからの経過時間に非常に敏感です。 テーブル内の不要行や不要空間の累積により結果が変わります。 結果を理解するためには、更新された行数とバキューム時期を把握する必要があります。 自動バキュームが有効な場合、性能を測定する上で結果は予測できないほど変わる可能性があります。

pgbenchの制限は、多くのクライアントセッションを試験しようとする際にpgbench自身がボトルネックになる可能性があることです。 これは、データベースサーバとは別のマシンでpgbenchを実行することで緩和させることが可能です。 しかし、多少のネットワーク遅延が重要です。 同一データベースサーバに対し複数のクライアントマシンから複数のpgbenchインスタンスを同時に実行することが有用かもしれません。