pgbench — PostgreSQLに対してベンチマーク試験を行う
pgbench
-i
[option
...] [dbname
]
pgbench
[option
...] [dbname
]
pgbenchはPostgreSQL上でベンチマーク試験を行う単純なプログラムです。
これは同一のSQLコマンドの並びを何度も実行します。複数の同時実行データベースセッションで実行することもできます。
そして、トランザクションの速度(1秒当たりのトランザクション数)の平均を計算します。
デフォルトでpgbenchは、1トランザクション当たり5つのSELECT
、UPDATE
、INSERT
コマンドを含むおおよそTPC-Bに基いたシナリオを試験します。
しかし、独自のトランザクションスクリプトファイルを作成することで他の試験ケースを簡単に実行することができます。
pgbenchの典型的な出力を以下に示します。
transaction type: <builtin: TPC-B (sort of)> scaling factor: 10 query mode: simple number of clients: 10 number of threads: 1 maximum number of tries: 1 number of transactions per client: 1000 number of transactions actually processed: 10000/10000 number of failed transactions: 0 (0.000%) latency average = 11.013 ms latency stddev = 7.351 ms initial connection time = 45.758 ms tps = 896.967014 (without initial connection time)
最初の7行はいくつかの最重要パラメータの設定を表示しています。
6行目では、直列化エラーまたはデッドロックエラーのあるトランザクションの最大試行回数がレポートされます(詳細は直列化の失敗/デッドロック再試行を参照してください)。
8行目では、完了トランザクション数と予定したトランザクション数がレポートされます(後者は単なるクライアント数とクライアント毎のトランザクション数の積算結果です。)
これらは、完了前に実行が失敗した場合や一部のSQLコマンドが失敗した場合を除いて等しくなります(-T
モードでは、実際のトランザクション数のみが出力されます)。
次の行では、直列化エラーまたはデッドロックエラーが原因で失敗したトランザクション数がレポートされます(直列化の失敗/デッドロック再試行を参照してください)。
最後の行は1秒当たりのトランザクション数を示します。
デフォルトのTPC-Bと似たトランザクション試験では、あらかじめ設定する特定のテーブルが必要です。
これらのテーブルを作成し、データを投入するためには、-i
(初期化)オプションを付けてpgbenchを呼び出さなければなりません。
(独自スクリプトを試験する場合、この手順は必要ありません。
しかし代わりに試験に必要な何らかの設定を行わなければならないでしょう。)
初期化は以下のようになります。
pgbench -i [other-options
]dbname
ここでdbname
は試験用に前もって作成されたデータベースの名前です。
(またデータベースサーバの接続方法を指定するために、-h
、-p
、-U
が必要になるかもしれません。)
pgbench -i
は4つのテーブルpgbench_accounts
、pgbench_branches
、pgbench_history
、pgbench_tellers
を作成します。
もしあればこうした名前のテーブルは破壊されます。
もし同じ名前のテーブルが存在する場合にはよく注意してください。
デフォルトの「倍率」の1では、テーブルは初期状態で以下の行数を含みます。
table # of rows --------------------------------- pgbench_branches 1 pgbench_tellers 10 pgbench_accounts 100000 pgbench_history 0
-s
(倍率)オプションを使用して行数を増加させることができます(また、ほとんどの目的ではおそらく増加させるべきです)。
また、-F
(fillfactor)オプションをここで使用しても構いません。
一度この必要な設定を行った後、以下のように-i
を持たないコマンドでベンチマークを行うことができます。
pgbench [options
]dbname
ほとんどすべての場合、有用な試験とするためにいくつかのオプションが必要になります。
最重要オプションは-c
(クライアント数)、-t
(トランザクション数)、-T
(制限時間)、-f
(独自スクリプトファイルの指定)です。
以下の全一覧を参照してください。
以下では、データベース初期化時に使用されるオプション、ベンチマーク実行時に使用されるオプション、どちらの場合でも使われるオプションの3つに分けて説明します。
pgbenchは以下の初期化用のコマンドライン引数を受け付けます。
dbname
#
試験するデータベースの名前を指定します。
これが指定されていない場合、環境変数PGDATABASE
が使用されます。
この変数も設定されていない場合は、接続のために指定されたユーザ名が使用されます。
-i
--initialize
#初期化モードを呼び出すために必要です。
-I init_steps
--init-steps=init_steps
#
標準の初期化ステップの内、選択したものだけを実行します。
init_steps
では、各ステップ毎に1文字を使って、実行する初期化ステップを指定します。
各ステップは指定した順で実行されます。
デフォルトはdtgvp
です。
有効なステップは以下の通りです。
d
(Drop) #既存のpgbenchのテーブルを全て削除します。
t
(create Tables) #
標準のpgbenchシナリオで使われるテーブル、すなわちpgbench_accounts
、pgbench_branches
、pgbench_history
およびpgbench_tellers
を作成します。
g
またはG
(Generate data, クライアント側、またはサーバ側) #データを生成し、既存データを置き換えて、標準の各テーブルに読み込みます。
g
(クライアント側データ生成)は、データはpgbench
クライアントで生成されてからサーバに送られます。
これはCOPY
でクライアント/サーバの帯域を大きく使います。
pgbench
は、バージョン14またはそれ以降のPostgreSQLを持つフリーズオプションを使用して、パーティションが有効になっていない限り、その後のVACUUM
を高速化します。
g
を使うと、pgbench_accounts
テーブルのためにデータを生成する間、100,000行毎にメッセージを1つログ出力するようになります。
G
(サーバ側データ生成)では、小さな問い合わせだけがpgbench
クライアントから送られ、データは実際にはサーバで生成されます。
こちらは帯域を著しく要求することはありませんが、サーバが、より多くの作業をすることになります。
G
を使うと、データを生成する間は進捗メッセージをログ出力しなくなります。
デフォルトの初期化動作は、クライアント側のデータ生成(g
と同じ)を使います。
v
(Vacuum) #
標準の各テーブルに対してVACUUM
を実行します。
p
(create Primary keys) #標準の各テーブルにプライマリキーインデックスを作成します。
f
(create Foreign keys) #標準のテーブル間に外部キー制約を作成します。 (このステップはデフォルトでは実行されないことに注意してください)
-F
fillfactor
--fillfactor=
fillfactor
#
指定したfillfactorでpgbench_accounts
、pgbench_tellers
、pgbench_branches
テーブルを作成します。
デフォルトは100です。
-n
--no-vacuum
#
初期化でバキュームを実行しません。
(このオプションは-I
で指定されていたとしても初期化ステップv
を抑止します。)
-q
--quiet
#ログ処理を、5秒に1つの進行メッセージのみを生成する静寂モードに切り替えます。 デフォルトのログ処理では、100,000行毎にメッセージを1つ出力し、(特に優れたハードウェアでは)1秒当たりに多くのメッセージを出力します。
-I
の中でG
が指定されていれば、この設定は影響しません。
-s
scale_factor
--scale=
scale_factor
#
この倍率で生成される行数を積算します。
例えば、-s 100
は pgbench_accounts
テーブルに10,000,000行を生成することを意味します。
デフォルトは1です。
この倍率が20000以上になると、アカウント識別子の範囲を保持できる程度に大きくなるように、アカウント識別子を保持するために使用される列(aid
列)はより大きな整数(bigint
)を使用するように切り替わります。
--foreign-keys
#
標準テーブル間で外部キー制約を作成します。
(このオプションは初期化ステップの並びに、もし無かったならf
ステップを追加します。)
--index-tablespace=index_tablespace
#デフォルトのテーブル空間ではなく、指定したテーブル空間の中にインデックスを作成します。
--partition-method=NAME
#
NAME
メソッドでパーティション化されたpgbench_accounts
テーブルを作成します。
期待される値はrange
またはhash
です。
このオプションは--partitions
が0でない値に設定されていることを要求します。
指定されなければ、デフォルトはrange
です。
--partitions=NUM
#
アカウントの数に比例したほぼ等しい大きさのNUM
個のパーティションにパーティション化されたpgbench_accounts
テーブルを作成します。
デフォルトは0
で、パーティション化しないことを意味します。
--tablespace=tablespace
#デフォルトのテーブル空間ではなく、指定したテーブル空間の中にテーブルを作成します。
--unlogged-tables
#永続テーブルではなくログを取らないテーブルとしてテーブルを作成します。
pgbenchは以下のベンチマーク用コマンドライン引数を受け付けます。
-b
scriptname[@weight]
--builtin
=scriptname[@weight]
#
指定の組み込みスクリプトを実行するスクリプトのリストに追加します。
利用可能な組み込みのスクリプトは、tpcb-like
、simple-update
、select-only
です。
組み込みの名前の曖昧な接頭辞も受け付けられます。
特別な名前list
を使うと、組み込みスクリプトのリストを表示して、即座に終了します。
オプションで、@
の後に整数のweight(重み)を書くことで、他のスクリプトと比較してそのスクリプトが選ばれる確率を調整することができます。
デフォルトの重みは1です。
詳細は以下を参照してください。
-c
clients
--client=
clients
#模擬するクライアント数、つまり、同時に実行されるデータベースセッション数です。 デフォルトは1です。
-C
--connect
#各クライアントセッションが一度だけ接続を確立するのではなく、各トランザクションが新しい接続を確立します。 これは接続オーバーヘッドを測定する場合に有用です。
-d
--debug
#デバッグ用出力を表示します。
-D
varname
=
value
--define=
varname
=
value
#
独自スクリプト(後述)で使用される変数を定義します。
複数の-D
オプションを使用することができます。
-f
filename[@weight]
--file=
filename[@weight]
#
filename
から読み取ったトランザクションスクリプトを実行されるスクリプトのリストに追加します。
オプションで、@
の後に整数のweight(重み)をつけることで、他のスクリプトと比較してそのスクリプトが選ばれる確率を調整することができます。
デフォルトの重みは1です。
(@
文字を含むスクリプトファイル名を使用するには、 filen@me@1
のように曖昧さがないように重みを付けます。)
詳細は以下を参照してください。
-j
threads
--jobs=
threads
#pgbench内のワーカースレッド数です。 複数のスレッドを使用することはマルチCPUマシンで有用になります。 クライアントは利用可能なスレッドの間でできる限り均等に分散されます。 デフォルトは1です。
-l
--log
#各トランザクションに関する情報をログファイルに書き出します。 詳細は以下を参照してください。
-L
limit
--latency-limit=
limit
#
limit
ミリ秒以上続くトランザクションが計数され、別途遅いトランザクションとして報告されます。
制限が使用されると(--rate=...
)、limit
ミリ秒以上遅延がスケジュールされたトランザクションは遅延制限を満たす可能性がないため、サーバに送信されることは決してありません。
これらのトランザクションは計数され、別途スキップされたとして報告されます。
--max-tries
オプションが使用されている場合、直列化異常またはデッドロックのために失敗したトランザクションは、すべての試行の合計時間がlimit
より大きい場合、再試行されません。
試行回数ではなく試行時間のみを制限するには、--max-tries=0
を使用します。
デフォルトでは、--max-tries
オプションは1に設定されており、直列化エラー/デッドロックエラーのあるトランザクションは再試行されません。
このようなトランザクションの再試行の詳細は直列化の失敗/デッドロック再試行を参照してください。
-M
querymode
--protocol=
querymode
#サーバへ問い合わせを送信するために使用するプロトコルです。
simple
: 簡易問い合わせプロトコルを使用します。
extended
: 拡張問い合わせプロトコルを使用します。
prepared
: プリペアドステートメントを伴う拡張問い合わせプロトコルを使用します。
prepared
モードでは、pgbenchは問い合わせの2回目の繰り返しからは構文解析結果を再利用しますので、pgbenchは他のモードよりも速く動作します。
デフォルトは簡易問い合わせプロトコルです。 (詳しい情報は第55章を参照してください)
-n
--no-vacuum
#
試験を実行する前にバキュームを行いません。
pgbench_accounts
、pgbench_branches
、pgbench_history
、
pgbench_tellers
標準テーブルを含まない独自試験シナリオを実行する場合、このオプションは必要です。
-N
--skip-some-updates
#
組み込みのsimple-update(単純な更新)のスクリプトを実行します。
-b simple-update
の短縮形です。
-P
sec
--progress=
sec
#
sec
秒毎の進捗レポートを表示します。
レポートには起動からの経過時間、前回レポート時からのTPS、前回レポート時からのトランザクションの平均待ち時間、標準偏差、最後のレポートからの失敗したトランザクションの数を含んでいます。
(-R
)オプションによる制限下では、待ち時間はトランザクションの実開始時間ではなく、予定開始時間で算出されていますので、平均予定遅延時間が含まれています。
--max-tries
を使用して直列化エラー/デッドロックエラー後のトランザクション再試行を有効にする場合、レポートには再試行されたトランザクションの数とすべての再試行の回数が含まれます。
-r
--report-per-command
#
ベンチマークの終了後、各コマンドについて、文ごとの平均待機時間(クライアントから見た実行時間)、失敗回数、およびこのコマンドの直列化エラーまたはデッドロックエラー後の再試行回数の統計をレポートします。
レポートに再試行統計が表示されるのは、--max-tries
オプションが1以外の場合のみです。
-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_tellers
とpgbench_branches
テーブルをバキュームし、pgbench_history
内のデータをすべて消去します。
--aggregate-interval=seconds
#
集約間隔の長さ(秒単位)です。
これは-l
と一緒でのみ使用できます。
このオプションを付けると、ログには以下で説明するような指定間隔単位の要約が含まれます。
--failures-detailed
#トランザクションごとおよび集約ログ、メインレポートおよびスクリプトごとのレポートで、次のタイプにグループ化された失敗をレポートします。
直列化失敗
デッドロック障害
詳細については、直列化の失敗/デッドロック再試行を参照してください。
--log-prefix=prefix
#
--log
により作成されるログファイルのファイル名の先頭につける文字列を設定します。
デフォルトはpgbench_log
です。
--max-tries=number_of_tries
#
直列化エラー/デッドロックエラーのあるトランザクションの再試行を有効にし、これらの試行の最大数を設定します。
このオプションは、すべてのトランザクション試行の合計時間を制限する--latency-limit
オプションと組み合せることができます。
また、--latency-limit
または--time
を指定せずに試行回数を無制限に使用することはできません(--max-tries=0
)。
デフォルト値は1で、直列化エラー/デッドロックエラーのあるトランザクションは再試行されません。
このようなトランザクションの再試行の詳細は、直列化の失敗/デッドロック再試行を参照してください。
--progress-timestamp
#
進捗を表示(-P
オプション)しているとき、実行開始以後の経過秒数の代わりにタイムスタンプ(Unixエポック時刻)を使用します。
単位は秒で、ドットの後にミリ秒の精度が付きます。
これは様々なツールで生成されたログを比較するのに役立つでしょう。
--random-seed=
seed
#
ランダムジェネレータのシードを設定します。
各スレッド毎の初期ジェネレータ状態から一連の値を生成する、システム乱数ジェネレータの種となります。
seed
の値は以下が可能です。
time
(デフォルト、現在時刻に基づくシード)、rand
(強いランダムソースを使用、使用できなければ失敗します)、あるいは符号無し整数値です。
ランダムジェネレータはpgbenchスクリプト(random...
関数)から明示的に、あるいは暗黙に(例えばオプション--rate
がトランザクションのスケジュールに使用します)、実行されます。
明示的に設定した場合、シードに使われる値はターミナルにあらわれます。
seed
に与えることのできる値は何であれ、環境変数PGBENCH_RANDOM_SEED
を通して付与しても良いです。
設定したシードがありうる全ての実行に影響を及ぼすようにするためには、本オプションを最初に置くか、環境変数を使ってください。
明示的にシードを設定することは、乱数に関しては、正確にpgbench
実行を再現することを可能にします。
ランダム状態はスレッド毎に制御されているので、スレッド毎に一つのクライアントであり、外的な依存やデータ依存が無い場合、同一の起動に対して正確に同じpgbench
実行することを意味します。
統計的観点からは、性能のばらつきを隠したり、例えば前回実行と同じページにヒットすることで不当に性能改善するので、正確な再現実行は悪い考えです。
しかしながら、例えばエラーを起こすトリッキーなケースを再実行するなど、デバッグには大きな助けとなるでしょう。
賢く使ってください。
--sampling-rate=rate
#データをログに書き出す際に使用される、生成されるログの量を減少するためのサンプリング割合です。 このオプションが指定された場合、指定された割合のトランザクションがログに残ります。 1.0はすべてのトランザクションが、0.05はトランザクションの5%のみがログに残ることを意味します。
ログファイルを処理する際にはこのサンプリング割合を考慮することを忘れないでください。 例えば、TPS値を計算する際には、比例した数を掛け合わせなければなりません(例:サンプリング割合が0.01の場合実際のTPSの1/100を得るだけです。)
--show-script=
scriptname
#
組み込みスクリプトscriptname
の実際のコードを標準エラーに出力し、即座に終了します。
--verbose-errors
#すべてのエラーと失敗(再試行しないエラー)に関するメッセージを表示します。 これには、どの再試行制限を超えたか、および直列化/デッドロックの失敗でどの程度超えたかが含まれます(この場合、出力が大幅に増加することに注意してください)。 詳細は直列化の失敗/デッドロック再試行を参照してください。
実行に成功すればステータス0で終了します。 終了ステータス1は、無効なコマンドラインオプションや発生しないと思われる内部エラーなどの静的の問題を示します。 最初のコネクションの失敗など、ベンチマークの起動時に発生する初期エラーも、終了ステータス1になります。 データベースエラーやスクリプトでの問題などの実行中のエラーは終了ステータス2になります。 後者の場合、pgbenchは部分的な結果を表示します。
PGDATABASE
PGHOST
PGPORT
PGUSER
#デフォルトの接続パラメータです。
このユーティリティは、他のほとんどのPostgreSQLユーティリティと同様、libpqでサポートされる環境変数を使用します(34.15を参照してください)。
環境変数PG_COLOR
は診断メッセージで色を使うかどうかを指定します。
可能な値はalways
、auto
、never
です。
pgbenchは指定したリストからランダムに選択したテストスクリプトを実行します。
これには-b
の組み込みスクリプトと-f
のユーザ定義カスタムスクリプトが含まれることがあります。
各スクリプトには@
の後に指定される相対的な重みを与えることができ、それが選ばれる確率を変更することができます。
デフォルトの重みは1
です。
重みが0
のスクリプトは無視されます。
デフォルトの組み込みトランザクションスクリプト(-b tpcb-like
とすることでも実行されます)は、aid
、tid
、bid
、delta
からランダムに選択され、トランザクション毎に7つのコマンドを発行します。
このシナリオはTPC-Bベンチマークに示唆を受けたものですが、実際にはTPC-Bではないので、この名前になっています。
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;
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行で書き、終わりにセミコロンを付けるようにしてください。
pgbenchスクリプトにはSQLトランザクションの不完全なブロックが含まれていないと想定されています。 実行時にクライアントが最後のトランザクションブロックを完了せずにスクリプトの最後に到達した場合、クライアントは中断されます。
スクリプトファイル向けの簡単な変数置換機能があります。
変数名は最初の文字が数字以外で文字(非ラテン文字を含む)、数字およびアンダースコアで構成されていなければなりません。
上で説明したように変数を-D
コマンドラインオプションで設定することができます。
また、後で説明するようにメタコマンドで設定することもできます。
-D
コマンドラインオプションで設定された変数の他に、表 293に記載されているように、自動的に設定される変数がいくつかあります。
-D
を使ってこれらの変数に設定された値は、自動設定の値より優先されます。
一度設定すると、変数の値は、:
variablename
と書かれてSQLコマンドに挿入されます。
1つ以上のクライアントセッションが実行される場合、セッション毎に独自の変数群を持ちます。
pgbenchは1つの文内で255個までの変数の利用をサポートします。
表293 pgbench Automatic Variables
変数 | 説明 |
---|---|
client_id | クライアントセッションを識別する一意の数値(ゼロから始まる) |
default_seed | デフォルトでハッシュ関数や疑似ランダム置換関数で使われるシード |
random_seed | ランダムジェネレータのシード(-D で上書きされていないなら) |
scale | 現在の倍率 |
スクリプトファイルのメタコマンドはバックスラッシュ(\
)から始まり、通常は行末まで続きますが、バックスラッシュと改行を書くことで、追加の行に続けることができます。
メタコマンドへの引数は空白文字で区切られます。
以下のメタコマンドがサポートされています。
\gset [prefix
]
\aset [prefix
]
#
このコマンドは、終了を意味するセミコロン(;
)の置き換えで、SQL問い合わせを終えるために使われます。
\gset
コマンドが使われると、それまでのSQL問い合わせは1行を返すものと期待され、その行の列は列名にちなんだ名前の変数に格納されます。prefix
が指定されていれば、変数名の前に付きます。
\aset
コマンドが使われると、(\;
で分けられた)すべての結合したSQL問い合わせは、その列が列名にちなんだ名前の変数に格納されます。prefix
が指定されていれば、変数名の前に付きます。
問い合わせが行を返さなければ、割り当ては行なわれませんので、これを検出するために変数の存在をテストできます。
問い合わせが2行以上返した場合、最後の値が保持されます。
\gset
と\aset
はパイプラインモードでは使用できません。
これは、コマンドで必要になるまでに問い合わせの結果がまだ利用できないためです。
以下の例は、最初の問い合わせからの最終的な口座残高を変数abalance
に入れ、変数p_two
とp_three
を3番目の問い合わせからの整数で埋めます。
2番目の問い合わせの結果は捨てられます。
最後の2つの結合した問い合わせの結果は、変数four
とfive
に格納されます。
UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid RETURNING abalance \gset -- 2つの問い合わせの組み合わせ SELECT 1 \; SELECT 2 AS two, 3 AS three \gset p_ SELECT 4 AS four \; SELECT 5 AS five \aset
\if
expression
\elif
expression
\else
\endif
#
このコマンド群はpsql
の\if
expression
と似た、入れ子にできる条件ブロックを実現します。
条件式は\set
と同じで、非ゼロ値は真と解釈されます。
\set varname
expression
#
varname
変数をexpression
から計算された値に設定します。
式(expression)には、NULL
定数、真理値定数のTRUE
とFALSE
、5432
のような整数の定数、3.14159
のような倍精度実数の定数、変数を参照する :
variablename
、通常のSQLの優先度と結合規則での演算子、関数呼び出し、SQLのCASE
一般条件式および括弧を含むことができます。
関数と大部分の演算子はNULL
入力にNULL
を返します。
条件の用途では非ゼロの数値はTRUE
、ゼロ数値とNULL
はFALSE
です。
大きすぎるもしくは小さすぎる整数や倍精度実数の定数は、整数算術演算子(+
、-
、*
、/
)と同様にオーバーフローエラーになります。
CASE
に最後のELSE
句が与えられないとき、デフォルト値はNULL
です。
例
\set ntellers 10 * :scale \set aid (1021 * random(1, 100000 * :scale)) % \ (100000 * :scale) + 1 \set divx CASE WHEN :x <> 0 THEN :y/:x ELSE NULL END
\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
\startpipeline
\endpipeline
#これらのコマンドは、SQL文のパイプラインの開始と終了を区切ります。 パイプラインモードでは、文は前の文の結果を待つことなくサーバに送信されます。 詳細は34.5を参照してください。 パイプラインモードでは、拡張問い合わせプロトコルを使用する必要があります。
表 294に載っている算術、ビットごと、比較、論理の演算子はpgbenchに組み込まれていて、\set
の式で使用できます。
演算子は優先度の低い順に載っています。
注意書きがある場合を除いて、2つの数値を取る演算子は、入力の片方が倍精度実数であれば倍精度実数の値を結果とし、そうでなければ整数の結果になります。
表294 pgbenchの演算子
演算子 説明 例 |
---|
論理OR
|
論理AND
|
論理NOT
|
ブール値のテスト
|
NULLであるかのテスト
|
等価
|
不等
|
不等
|
より小さい
|
以下
|
より大きい
|
以上
|
ビット毎のOR
|
ビット毎のXOR
|
ビット毎のAND
|
ビット毎のNOT
|
ビット毎の左シフト
|
ビット毎の右シフト
|
加算
|
減算
|
乗算
|
除算(入力が両方とも整数であれば、結果は0に向けて丸められる)
|
剰余(余り)
|
符号反転
|
表 295に示す関数はpgbenchに組み込まれており、\set
に現れる式の中で使うことができます。
表295 pgbenchの関数
関数 説明 例 |
---|
絶対値
|
引数をstderrに出力し、引数を返す。
|
倍精度実数にキャストする。
|
指数(
|
引数の中で最大の値を選択する。
|
これは
|
FNV-1aハッシュを計算する。
|
MurmurHash2ハッシュを計算する。
|
整数にキャストする。
|
引数の中で最小の値を選択する。
|
自然対数
|
剰余(余り)
|
|
πの近似値
|
|
|
|
|
|
平方根
|
random
関数は一様分布を使って値を生成します。
つまり、すべての値は指定された範囲内で同じ確率で発生します。
random_exponential
、random_gaussian
、および、random_zipfian
関数は追加の倍精度実数のパラメータを必要とし、それによって分布の正確な形が決まります。
指数分布では、parameter
が分布を制御します。
急速に減少する指数分布をparameter
で切り捨て、境界範囲内の整数に射影します。
正確には、以下の式に従います。
f(x) = exp(-parameter * (x - min) / (max - min + 1)) / (1 - exp(-parameter))
これにより、min
とmax
の間(両端を含む)の間の値i
がf(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)
とすると、min
とmax
の間(両端を含む)の値i
が発生する確率はf(i + 0.5) - f(i - 0.5)
になります。
直感的には、parameter
が大きくなれば、間隔の中間に近い値になる確率が高く、また、min
とmax
の境界に近い値になる確率は低くなります。
約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です。
random_zipfian
は制限付きのジップ分布を生成します。
parameter
はどれほど歪んだ分布かを定義します。
より大きいparameter
ほど、より高頻度に区間の始点に近い値が描かれます。
範囲が1から始まるとして、k
を描く確率とk+1
を描く確率の比が((
という分布になります。
例えば、k
+1)/k
)**parameter
random_zipfian(1, ..., 2.5)
は、値1
を2
の約(2/1)**2.5 = 5.66
倍高い頻度で生成し、値2
を3
の約(3/2)**2.5 = 2.76
倍高い頻度で生成し、以下同様に続きます。
pgbenchの実装は「Non-Uniform Random Variate Generation」Luc Devroye(Springer 1986, p. 550-551)に基づいており、parameter
値は[1.001, 1000]の範囲に限定されています。
行を不均一に選択するベンチマークを設計する場合、選択された行はシーケンスからのIDや物理的な行の順序など他のデータと相関している可能性があり、性能測定に影響を与える可能性があることに留意してください。
これを避けるには、permute
関数、または同様の効果を持つ他の追加手順を使用して、選択した行をシャッフルし、そのような相関関係を削除することをお勧めします。
ハッシュ関数hash
、hash_murmur2
およびhash_fnv1a
は入力値とオプションシードパラメータを受け付けます。
シードが与えられなかった場合、:default_seed
の値が使われます。これは、コマンドライン-D
オプションで設定されない限りランダムに初期化されたものです。
permute
は、入力値とサイズとオプションシードパラメータを受け付けます。
[0, size)
の範囲の整数の疑似ランダム置換を生成し、並べ替えられた値の入力値のインデックスを返します。
選択される並べ替えはシードによってパラメータ化され、指定されていない場合:default_seed
がデフォルトになります。
ハッシュ関数とは異なり、permute
は出力値に衝突や穴がないことを保証します。
区間外の入力値は、サイズを法として解釈されます。サイズが正でない場合、関数はエラーを発生させます。
permute
はrandom_zipfian
やrandom_exponential
のような不均一なランダム関数の分布を分散させて、より頻繁に導出される値が自明に相関しないようにすることができます。
たとえば、以下のpgbenchスクリプトは、僅かなアカウントが過大な負荷を生成するソーシャルメディアやブログのプラットフォームで起こりえる現実世界のワークロードをシミュレートします。
\set size 1000000 \set r random_zipfian(1, :size, 1.07) \set k 1 + permute(:r, :size)
一部のケースでは、互いに無関係ないくつかの異なる分布が必要で、これはオプションのシードパラメータが役立ちます。
\set k1 1 + permute(:r, :size, :default_seed + 123) \set k2 1 + permute(:r, :size, :default_seed + 321)
同様の動作は、hash
でも近似的に行うことができます。
\set size 1000000 \set r random_zipfian(1, 100 * :size, 1.07) \set k 1 + abs(hash(:r)) % :size
しかし、hash
は衝突を発生させるため、到達できない値もあれば、元の分布から予想されるよりも頻度が高い値もあります。
例えば、組み込みの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は各トランザクションに関する情報をログファイルに書き出します。
ログファイルの名前は
で、prefix
.nnn
prefix
のデフォルトはpgbench_log
、nnn
はpgbenchプロセスのPIDです。
ファイル名の先頭の文字列は--log-prefix
オプションを使って変更することができます。
-j
オプションが2以上で複数のワーカースレッドがある場合、それぞれが独自のログファイルを持つことになります。
最初のワーカーは標準的な単一ワーカーの場合と同じ名前を持つログファイルを使用します。
他のワーカー用の追加のログファイルは
と命名され、ここでprefix
.nnn
.mmm
mmm
は1から始まる各ワーカーの連番です。
ログファイルの各行には1つのトランザクションが記述されています。 このログファイルには、スペースで区切られた次のフィールドが含まれています:
client_id
トランザクションを実行したクライアントセッションを示します
transaction_no
そのセッションで実行されたトランザクションの数をカウントします
time
トランザクションの経過時間(マイクロ秒)
script_no
トランザクションに使用されたスクリプトファイルを示します(複数のスクリプトが-f
または-b
で指定されている場合に便利です)
time_epoch
トランザクションの完了時刻(Unixエポックタイムスタンプ)
time_us
トランザクションの完了時間の分数秒部分(マイクロ秒)
schedule_lag
トランザクション開始遅延、つまりトランザクションのスケジュールされた開始時刻と実際に開始された時刻の差をマイクロ秒単位で表したものです(--rate
が指定されている場合にのみ存在します)
retries
直列化エラーまたはトランザクション中のデッドロックエラー後の再試行のカウントします
(--max-tries
が1でない場合にのみ存在する)
--rate
と--latency-limit
の両方を使用すると、スキップされたトランザクションのtime
はskipped
として報告されます。
トランザクションが失敗で終了した場合、time
はfailed
として報告されます。
--failures-detailed
オプションを使用すると、失敗したトランザクションのtime
は、障害のタイプに応じて直列化
またはデッドロック
として報告されます(詳細は直列化の失敗/デッドロック再試行を参照してください)。
単一クライアントでの実行で生成されたログファイルの一部を示します。
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つのトランザクションは、開始する前にすでに遅れてしまっているため、スキップされています。
次の例は、最大試行回数を10に設定した失敗と再試行のログファイルの一部を示しています(追加再試行
列に注意)。
3 0 47423 0 1499414498 34501 3 3 1 8333 0 1499414498 42848 0 3 2 8358 0 1499414498 51219 0 4 0 72345 0 1499414498 59433 6 1 3 41718 0 1499414498 67879 4 1 4 8416 0 1499414498 76311 0 3 3 33235 0 1499414498 84469 3 0 0 failed 0 1499414498 84905 9 2 0 failed 0 1499414498 86248 9 3 4 8307 0 1499414498 92788 0
--failures-detailed
オプションを使用すると、障害のタイプは次のように時間
で報告されます。
3 0 47423 0 1499414498 34501 3 3 1 8333 0 1499414498 42848 0 3 2 8358 0 1499414498 51219 0 4 0 72345 0 1499414498 59433 6 1 3 41718 0 1499414498 67879 4 1 4 8416 0 1499414498 76311 0 3 3 33235 0 1499414498 84469 3 0 0 serialization 0 1499414498 84905 9 2 0 serialization 0 1499414498 86248 9 3 4 8307 0 1499414498 92788 0
大量のトランザクションを処理することができるハードウェアで長時間試験を実行する場合、ログファイルは非常に大きくなる可能性があります。
--sampling-rate
オプションを使用して、トランザクションのランダムなサンプルだけをログに記録することができます。
--aggregate-interval
オプションを使用すると、ログファイルに異なるフォーマットが使用されます。
各ログ行は1つの集約間隔を記述します。
このログ行には、スペースで区切られた次のフィールドが含まれます:
interval_start
間隔の開始時刻(Unixエポックタイムスタンプ)
num_transactions
間隔内のトランザクション数
sum_latency
トランザクション待ち時間の合計
sum_latency_2
トランザクション待ち時間の平方和
min_latency
最小トランザクション待ち時間
max_latency
最大トランザクション待ち時間
sum_lag
トランザクション開始遅延の合計(--rate
が指定されていない場合は0)
sum_lag_2
トランザクション開始遅延の平方和(--rate
が指定されていない場合は0)
min_lag
最小トランザクション開始遅延(--rate
が指定されていない場合は0)
max_lag
最大トランザクション開始遅延(--rate
が指定されていない場合は0)
skipped
開始が遅すぎたためにスキップされたトランザクションの数(--rate
と--latency-limit
が指定されていない場合は0)
retried
再試行されたトランザクションの数(--max-tries
が1でない場合は0)
retries
直列化エラーまたはデッドロックエラー後の再試行回数
(--max-tries
が1でない場合は0)
serialization_failures
直列化エラーが発生し、その後再試行されなかったトランザクションの数(--failures-detailed
が指定されていない場合は0)
deadlock_failures
デッドロックエラーが発生し、その後再試行されなかったトランザクションの数(--failures-detailed
が指定されていない場合は0)
以下に、これらのオプションで生成された出力例を示します。
pgbench --aggregate-interval=10 --time=20 --client=10 --log --rate=1000 --latency-limit=10 --failures-detailed --max-tries=10 test
1650260552 5178 26171317 177284491527 1136 44462 2647617 7321113867 0 9866 64 7564 28340 4148 0
1650260562 4808 25573984 220121792172 1171 62083 3037380 9666800914 0 9998 598 7392 26621 4527 0
通常の(集約されていない)ログフォーマットは、各トランザクションについてどのスクリプトファイルが使用されたかを示しますが、集約されたログにはそれがないことに注意してください。 このためスクリプト単位のデータが必要な場合は、自身でデータを集約する必要があります。
-r
オプションを使用すると、pgbenchは文ごとに次の統計情報を収集します。
latency
—各文の経過トランザクション時間。
pgbenchは文のすべての成功した実行の平均値を報告します。
この文の失敗数。 詳細は直列化の失敗/デッドロック再試行を参照してください。
この文の直列化エラーまたはデッドロックエラー後の再試行回数。 詳細は直列化の失敗/デッドロック再試行を参照してください。
レポートに再試行統計情報が表示されるのは、--max-tries
オプションが1に等しくない場合だけです。
すべての値は、各クライアントによって実行される文ごとに計算され、ベンチマークが終了した後に報告されます。
デフォルトのスクリプトの場合、出力は次のようになります。
starting vacuum...end. transaction type: <builtin: TPC-B (sort of)> scaling factor: 1 query mode: simple number of clients: 10 number of threads: 1 maximum number of tries: 1 number of transactions per client: 1000 number of transactions actually processed: 10000/10000 number of failed transactions: 0 (0.000%) number of transactions above the 50.0 ms latency limit: 1311/10000 (13.110 %) latency average = 28.488 ms latency stddev = 21.009 ms initial connection time = 69.068 ms tps = 346.224794 (without initial connection time) statement latencies in milliseconds and failures: 0.012 0 \set aid random(1, 100000 * :scale) 0.002 0 \set bid random(1, 1 * :scale) 0.002 0 \set tid random(1, 10 * :scale) 0.002 0 \set delta random(-5000, 5000) 0.319 0 BEGIN; 0.834 0 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid; 0.641 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid; 11.126 0 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid; 12.961 0 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid; 0.634 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP); 1.957 0 END;
デフォルトトランザクション分離レベルにシリアライザブルを使用したデフォルトスクリプトの別の出力例(PGOPTIONS='-c default_transaction_isolation=serializable'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 maximum number of tries: 10 number of transactions per client: 1000 number of transactions actually processed: 6317/10000 number of failed transactions: 3683 (36.830%) number of transactions retried: 7667 (76.670%) total number of retries: 45339 number of transactions above the 50.0 ms latency limit: 106/6317 (1.678 %) latency average = 17.016 ms latency stddev = 13.283 ms initial connection time = 45.017 ms tps = 186.792667 (without initial connection time) statement latencies in milliseconds, failures and retries: 0.006 0 0 \set aid random(1, 100000 * :scale) 0.001 0 0 \set bid random(1, 1 * :scale) 0.001 0 0 \set tid random(1, 10 * :scale) 0.001 0 0 \set delta random(-5000, 5000) 0.385 0 0 BEGIN; 0.773 0 1 UPDATE pgbench_accounts SET abalance = abalance + :delta WHERE aid = :aid; 0.624 0 0 SELECT abalance FROM pgbench_accounts WHERE aid = :aid; 1.098 320 3762 UPDATE pgbench_tellers SET tbalance = tbalance + :delta WHERE tid = :tid; 0.582 3363 41576 UPDATE pgbench_branches SET bbalance = bbalance + :delta WHERE bid = :bid; 0.465 0 0 INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (:tid, :bid, :aid, :delta, CURRENT_TIMESTAMP); 1.933 0 0 END;
複数のスクリプトファイルが定義された場合、すべての統計処理はそれぞれのスクリプトファイル毎に分けて報告されます。
文ごとのレイテンシを計算するために必要となる、追加のタイミング情報を収集することは、オーバーヘッドが加わることに注意してください。 これは平均実行速度を遅くし、計測TPSを小さくするでしょう。 低下量はプラットフォームとハードウェアに依存して著しく変わります。 レイテンシの報告を有効にする、有効にしないで平均TPS値を比較することは、タイミング・オーバーヘッドが顕著かどうかを測定するには良い方法です。
pgbenchの実行時に発生する主なエラーには以下の3種類があります。
メインプログラムのエラーです。 これらは最も深刻で、常にpgbenchを即座に終了し、対応するエラーメッセージが表示されます。 これらのエラーには以下のようなものがあります:
pgbenchの先頭のエラー(例えば無効なオプション値)。
初期化モードでエラーが発生する(例えば、組み込みスクリプト用のテーブルを作成するクエリが失敗する)。
スレッドを開始する前のエラー(データベースサーバに接続できない、メタコマンドの構文エラー、スレッド作成の失敗など)。
内部pgbenchエラーです(決して発生しないはずです…)。
スレッドがクライアントを管理するときのエラー(クライアントがデータベースサーバへの接続を開始できなかった/クライアントをデータベースサーバに接続するためのソケットが無効になったなど)。 このような場合、このスレッドのすべてのクライアントは停止し、他のスレッドは作業を継続します。
直接的なクライアントエラーです。 内部pgbenchエラーの場合にのみpgbenchを即座に終了し、対応するエラーメッセージが表示されます(これは決して発生しないはずです…)。 そうでなければ、最悪の場合には、他のクライアントが実行を継続している間に、失敗したクライアントが中断されるだけです(ただし、クライアントエラーの中には、クライアントの中断なしに処理され、別途報告されるものもあります。以下を参照してください)。 この節の後半では、説明されているエラーは直接的なクライアントエラーだけであり、内部pgbenchエラーではないと仮定します。
重大なエラーが発生した場合、クライアントの実行は中断されます。
たとえば、データベースサーバーとの接続が失われた場合や、最後のトランザクションを完了せずにスクリプトの終了に達した場合などです。
また、SQLまたはメタコマンドの実行が直列化エラーまたはデッドロックエラー以外の理由で失敗した場合、クライアントは中断されます。
そうでない場合、SQLコマンドが直列化エラーまたはデッドロックエラーで失敗した場合、クライアントは中断されません。
このような場合、現在のトランザクションがロールバックされます。
これには、クライアント変数がこのトランザクションの実行前の状態に設定されます(1つのトランザクションスクリプトには1つのトランザクションのみが含まれていると仮定されます。詳細はpgbenchで実際に実行される"トランザクション"は何か?を参照してください)。
直列化エラーまたはデッドロックエラーのあるトランザクションは、正常に完了するか、最大試行回数(--max-tries
オプションで指定/最大再試行時間(--latency-limit
オプションで指定)/ベンチマークの終了(--time
オプションで指定)に達するまで、ロールバック後に繰り返されます。
最後の試運転が失敗した場合、このトランザクションは失敗として報告されますが、クライアントは中断されずに処理を続行します。
--max-tries
オプションを指定しない場合、デフォルト値が1であるため、シリアライゼーションエラーまたはデッドロックエラーの後にトランザクションが再試行されることはありません。
試行回数を無制限にし(--max-tries=0
)、--latency-limit
オプションを使用して、試行の最大時間のみを制限します。
また、--time
オプションを使用して、試行回数を無制限にしてベンチマーク期間を制限することもできます。
複数のトランザクションを含むスクリプトを繰り返す場合は注意が必要です。 スクリプトは常に完全に再試行されるため、成功したトランザクションが複数回実行される可能性があります。
シェルコマンドでトランザクションを繰り返す場合は注意してください。
SQLコマンドの結果とは異なり、\setshell
コマンドの変数値を除いて、シェルコマンドの結果はロールバックされません。
成功したトランザクションの待機時間には、ロールバックおよび再試行によるトランザクションの実行時間全体が含まれます。 待機時間は、成功したトランザクションおよびコマンドについてのみ測定され、失敗したトランザクションまたはコマンドについては測定されません。
メインレポートには、失敗したトランザクションの数が含まれます。
--max-tries
オプションが1以外の場合、メインレポートには再試行に関する統計(再試行されたトランザクションの合計数と再試行の合計数)も含まれます。
スクリプト単位のレポートは、メインレポートからこれらのフィールドをすべて継承します。
文単位のレポートには、--max-tries
オプションが1以外の場合にのみ再試行の統計が表示されます。
トランザクションごとおよび集約ログ、メインレポートおよびスクリプトごとのレポートで障害を基本タイプ別にグループ化する場合は、--failures-detailed
オプションを使用します。
また、すべてのエラーおよび障害(再試行しない場合のエラー)をタイプ別に区別する場合は、--verbose-errors
オプションを使用します。
これには、直列化エラー/デッドロック障害でどの再試行制限を超えたか、どの程度超えたかなどが含まれます。
pgbenchテーブルにはテーブルアクセスメソッドを指定できます。
環境変数PGOPTIONS
は、コマンドライン経由でPostgreSQLに渡されるデータベース設定オプションを指定します(20.1.4を参照してください)。
例えば、pgbenchが作成するテーブル用のwuzza
と呼ばれる架空のデフォルトテーブルアクセスメソッドは、次のように指定できます。
PGOPTIONS='-c default_table_access_method=wuzza'
まったく無意味な数値を生み出すようにpgbenchを使用することは非常に簡単です。 以下に有意な結果を生み出す手助けとなるガイドラインをいくつか示します。
まず第一に、数秒で終わる試験を決して信用しないでください。
-t
または-T
オプションを使って、雑音を取り除くために、少なくとも数分試験にかかるようにしてください。
再現可能な数値を得るために数時間必要になる場合もあります。
数回試験を繰り返し、数値が再現できるかどうか確認することを勧めます。
デフォルトのTPC-Bのような試験シナリオでは、初期倍率(-s
)を試験予定のクライアント数(-c
)の最大値と同程度にしなければなりません。
pgbench_branches
テーブルには-s
行しかありません。
また、全トランザクションはその内の1つを更新しようとします。
ですので、-c
値を-s
より大きくすると、他のトランザクションを待機するためにブロックされるトランザクションが多くなることは間違いありません。
デフォルトの試験シナリオはまた、テーブルを初期化してからの経過時間に非常に敏感です。 テーブル内の不要行や不要空間の累積により結果が変わります。 結果を理解するためには、更新された行数とバキューム時期を把握する必要があります。 自動バキュームが有効な場合、性能を測定する上で結果は予測できないほど変わる可能性があります。
pgbenchの制限は、多くのクライアントセッションを試験しようとする際にpgbench自身がボトルネックになる可能性があることです。 これは、データベースサーバとは別のマシンでpgbenchを実行することで緩和させることが可能です。 しかし、多少のネットワーク遅延が重要です。 同一データベースサーバに対し複数のクライアントマシンから複数のpgbenchインスタンスを同時に実行することが有用かもしれません。
安全なスキーマの利用パターンを適用していないデータベースに信頼できないユーザがアクセス可能な場合、そのデータベースでpgbenchを実行しないでください。 pgbenchは修飾していない名前を使っており、またサーチパスを操作していません。