pgbenchはPostgreSQL上でベンチマーク試験を行う単純なプログラムです。 これは同一のSQLコマンドの並びを何度も実行します。複数の同時実行データベースセッションで実行することもできます。 そして、トランザクションの速度(1秒当たりのトランザクション数)の平均を計算します。 デフォルトでpgbenchは、1トランザクション当たり5つのSELECT、UPDATE、INSERTコマンドを含むおおよそTPC-Bに基いたシナリオを試験します。 しかし、独自のトランザクションスクリプトファイルを作成することで他の試験ケースを簡単に実行することができます。
pgbenchの典型的な出力を以下に示します。
transaction type: TPC-B (sort of) scaling factor: 10 query mode: simple number of clients: 10 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)
最初の5行はいくつかの最重要パラメータの設定を表示しています。 次行が完了トランザクション数と予定トランザクション数です(後者は単なるクライアント数とクライアント毎のトランザクション数の積算結果です。) 実行が完了する前に失敗しない限りこれは等しくなります。 最後の2行は、データベースセッションを開始した時と含める場合と含めない場合のTPS速度を示します。
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 (フィルファクタ)オプションをここで使用しても構いません。
一度この必要な設定を行った後、以下のように-iを持たないコマンドでベンチマークを行うことができます。
pgbench [ options ] dbname
ほとんどすべての場合、有用な試験とするためにいくつかのオプションが必要になります。 最重要オプションは-c(クライアント数)、-t(トランザクション数)、-T (制限時間) -f(独自スクリプトファイルの指定)です。 以下の全一覧を参照してください。
表F-14はデータベース初期化時に使用されるオプションを示します。 表F-15はベンチマーク実行時に使用されるオプションを示します。 そして、表F-16はどちらの場合でも使用されるオプションを示します。
表 F-14. pgbench初期化オプション
オプション | 説明 |
---|---|
-i | 初期化モードを呼び出すために必要です。 |
-s scale_factor | この倍率で生成される行数を積算します。 例えば、-s 100は pgbench_accountsテーブルに10,000,000行を生成することを意味します。 デフォルトは1です。 |
-F fillfactor | 指定したフィルファクタでpgbench_accounts、pgbench_tellers、pgbench_branchesテーブルを作成します。 デフォルトは100です。 |
表 F-15. pgbenchベンチマーク用オプション
オプション | 説明 |
---|---|
-c clients | 模擬するクライアント数、つまり、同時に実行されるデータベースセッション数です。 デフォルトは1です。 |
-t transactions | 各クライアントが実行するトランザクション数です。 デフォルトは10です。 |
-T seconds | クライアントあたりのトランザクション数を固定で指定するよりも長くテストを実行したい場合、ここに指定した秒数でテストを実行します。 -tと-Tは互いに排他的です。 |
-M querymode |
|
-N | pgbench_tellersとpgbench_branchesを更新しません。 これは両テーブル上の重度の更新の競合を防ぎますが、TPC-Bのような試験ケースを行わなくなります。 |
-S | TPC-Bのような試験ではなく読み取りのみのトランザクションを実行します。 |
-f filename | トランザクションスクリプトをfilenameから読み取ります。 詳細は後で説明します。 -N、-S、-fは互いに排他的です。 |
-n | 試験を実行する前にバキュームを行いません。 pgbench_accounts、pgbench_branches、pgbench_history、 pgbench_tellers標準テーブルを含まない独自試験シナリオを実行する場合、このオプションは必要です。 |
-v | 試験前に4つの標準テーブルすべてをバキュームを行います。 -nまたは-vがなければ、pgbenchはpgbench_tellersとpgbench_branchesテーブルをバキュームし、pgbench_history内のデータをすべて消去します。 |
-D varname=value | 独自スクリプト(後述)で使用される変数を定義します。 複数の-Dオプションを使用することができます。 |
-C | 各クライアントスレッドが一度だけ接続を確立するのではなく、各トランザクションが新しい接続を確立します。 これは接続オーバーヘッドを測定する場合に有用です。 |
-l | 各トランザクションで費やした時間をログファイルに書き出します。 後で詳細を説明します。 |
-s scale_factor | pgbenchの出力で指定した倍率を報告します。 これは組み込みの試験では必要ありません。 正確な倍率がpgbench_branchesテーブルの行数を数えることで検出されます。 しかし、独自ベンチマーク(-fオプション)を試験している場合、このオプションを使用しない限り、倍率は1として報告されます。 |
-d | デバッグ用出力を表示します。 |
デフォルトのトランザクションスクリプトは、1トランザクションで以下の7コマンドを発行します。
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;
-Nを指定した場合、第4コマンドと第5コマンドはトランザクションに含まれません。 -Sを指定した場合、SELECTのみが発行されます。
pgbenchは、ファイルから読み込んだトランザクションスクリプト(-fオプション)でデフォルトのトランザクションスクリプト(上述)を置き換えて独自のベンチマークシナリオを実行する機能をサポートします。 この場合、"トランザクション"はスクリプトファイルの1回の実行として数えられます。 複数のスクリプトを指定する(複数の-fオプション)ことさえ可能です。 この場合、クライアントセッションが新しいトランザクションを開始する時にランダムにスクリプトの1つが選択されます。
スクリプトファイルの書式は、1行1 SQLコマンドという形で、複数行に跨るSQLコマンドはサポートされません。 空行および--から始まる行は無視されます。 スクリプトファイルの行には、pgbench自身が解釈する"メタコマンド"(後述)も記述することができます。
スクリプトファイル向けの簡単な変数置換機能があります。 上で説明したように変数を-Dコマンドラインオプションで設定することができます。 また、後で説明するようにメタコマンドで設定することもできます。 -Dコマンドラインオプションで設定された変数の他に、scale変数は現在の倍率に設定されています。 一度設定すると、:variablenameと記述することで変数の値はSQLコマンドに挿入されます。 1つ以上のクライアントセッションを実行する時、セッション毎に独自の変数群を持ちます。
スクリプトファイルメタコマンドはバックスラッシュ(\)から始まります。 メタコマンドへの引数は空白文字で区切られます。 以下のメタコマンドがサポートされています。
varname変数を計算された整数値に設定します。 各operandは整数定数か整数値を持つ変数への:variablename参照のいずれかです。 operatorは+、-、*、/を取ることができます。
例
\set ntellers 10 * :scale
varname変数をminからmaxまでの範囲のランダムな整数値に設定します。 各制限整数定数か整数値を持つ変数への:variablename参照のいずれかです。
例
\setrandom aid 1 :naccounts
スクリプトの実行をマイクロ秒(us)、ミリ秒(ms)、秒(s)単位で指定した間待機させます。 単位を省略した場合、デフォルトは秒です。 number整数定数か整数値を持つ変数への:variablename参照のいずれかです。
例
\sleep 10 ms
例えば、組込みのTPC-Bのようなトランザクションの完全な定義を示します。
\set nbranches :scale \set ntellers 10 * :scale \set naccounts 100000 * :scale \setrandom aid 1 :naccounts \setrandom bid 1 :nbranches \setrandom tid 1 :ntellers \setrandom delta -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;
このスクリプトにより、トランザクションを繰り返す度に異なる、ランダムに選ばれた行を参照することができます。 (この例はまた、各クライアントセッションがなぜ独自の変数を持つことが重要なのかも表しています。 これがないと、異なる行を独立して参照することができないのです。)
-lオプションを使用すると、pgbenchは各トランザクションで要した時間をログファイルに書き出します。 ログファイルの名前はpgbench_log.nnnです。 ここでnnnはpgbenchプロセスのPIDです。 ログの書式は以下の通りです。
client_id transaction_no time file_no time_epoch time_us
ここでtimeはマイクロ秒単位のトランザクション処理時間、file_noは使用されたスクリプトファイルを識別するもの(-fにより複数のスクリプトが指定された場合に有用)、time_epoch/time_usはマイクロ秒のオフセットを持つUNIXエポック書式のタイムスタンプ(秒部分付きのISO 8601タイムスタンプの作成に適します)でトランザクションの完了時刻を示します。
以下に出力例を示します。
0 199 2241 0 1175850568 995598 0 200 2465 0 1175850568 998079 0 201 2513 0 1175850569 608 0 202 2038 0 1175850569 2663
まったく無意味な数値を生み出すようにpgbenchを使用することは非常に簡単です。 以下に有意な結果を生み出す手助けとなるガイドラインをいくつか示します。
まず第一に、数秒で終わる試験を決して信用しないでください。 -tまたは-Tオプションを使って、雑音を取り除くために、少なくとも数分試験にかかるようにしてください。 再現可能な数値を得るために数時間必要になる場合もあります。 数回試験を繰り返し、数値が再現できるかどうか確認することを勧めます。
デフォルトのTPC-Bのような試験シナリオでは、初期倍率(-s)を試験予定のクライアント数(-c)の最大値と同程度にしなければなりません。 pgbench_branchesテーブルには-s行しかありません。 また、前トランザクションはその内の1つを更新しようとします。 ですので、-c値を-sより大きくすると、他のトランザクションを待機するためにブロックされるトランザクションが多くなることは間違いありません。
デフォルトの試験シナリオはまた、テーブルを初期化してからの経過時間に非常に敏感です。 テーブル内の不要行や不要空間の累積により結果が変わります。 結果を理解するためには、更新された行数とバキューム時期を把握する必要があります。 自動バキュームが有効な場合、性能を測定する上で結果は予測できないほど変わる可能性があります。
pgbenchの制限は、多くのクライアントセッションを試験しようとする際にpgbench自身がボトルネックになる可能性があることです。 これは、データベースサーバとは別のマシンでpgbenchを実行することで緩和させることが可能です。 しかし、多少のネットワーク遅延が重要です。 同一データベースサーバに対し複数のクライアントマシンから複数のpgbenchインスタンスを同時に実行することが有用かもしれません。