pgbenchでUNLOGGEDの効果を見てみたが・・・

先日、COPY操作に関するUNLOGGEDの効果は確認できたんだけど、ベンチマークではどうなんだろう?と思って、とりあえず簡単に試せそうなpgbenchで試してみようと思ったのだが・・・

pgbenchの改造

PostgreSQL 9.1のcontrib/pgbenchが-iオプションで作成するテーブルは通常のテーブルを生成するので、ここをUNLOGGED TABLEで生成するようにコードをちょっと変更する(詳細は末尾参照)。
UNLOGGDEDオプション追加とか面倒そうなのは今回はパス。

【追記】
過去にもpgbenchが生成するテーブルをUNLOGGEDにするスイッチを追加する提案([PostgreSQL-Hackers] pgbench --unlogged-tables - Grokbase)とかはあったようだけど、少なくともPostgreSQL 9.1のpgbenchには採用されていない(経緯は追うのが面倒なので不明)。

測定条件

PostgreSQL設定

あえてあまり弄らずに。

shared_buffers 32MB
checkpoint_segments 100
pgbench設定
scale factor 100
connect 10
duration 600秒
その他 -rつき

測定結果

tps
FILLFACTOR設定(100%) FILLFACTOR設定(80%)
通常テーブル版 305.912891 542.266888
UNLIGGED版 302.409096 533.564632


うーん、ほとんどUNLOGGEDの効果がない気がする(´・ω・`)。
10分くらい(約200000〜300000トランザクションくらい)動かしているし、pgbenchの場合、1つのトランザクションで更新3回、挿入1回があるんだからそれなりにWALの書き出し量もあると思ったのだが・・・。
ついでに測定したFILLFACTORの適度な設定はpgbenchでは結構効果があるな。

【追記】
永安氏のA Hacker's Diary: pgbench on UNLOGGED table(s), Round 2にも検証した結果があったけど、この結果を見る感じでは結構UNLOGGED化による効果が出ているよなあ・・・。
やっぱり測定方法が何かまずいのかも。

latencies

次にpgbenchの-rオプションで生成されるlatenciesの情報を見てみる。

処理\実行設定 通常/FF=100 通常/FF=80 UL/FF=100 UL/FF=80
BEGIN 0.250474 0.232978 0.284016 0.217452
UPDATE accounts 22.835855 10.799313 22.93067 11.34712
SELECT abalance 6.318071 1.313955 5.772142 1.387759
UPDATE tellers 1.792527 4.441692 0.769518 3.942956
UPDATE branches 0.628328 0.884453 1.933925 0.943259
INSERT hinstory 0.398945 0.450582 1.013554 0.581062
END 0.28274 0.270541 0.316187 0.251898


latenciesを見てもSELECTが支配項になっているようには思えない・・・。accountsへの更新が結構重いが・・・accountsへの競合がそんなに起きるとも思えないしなあ。
ということで謎のままである。この謎解きは別途。

参考:pgbenchの修正コード

それぞれの箇所の"create table テーブル名"を"create unlogged table テーブル名"に修正するだけ。
オプション化して切り替えるところまでは今回はやらなかった。

  • 1235〜1247行目

        static char *DDLs[] = {
"drop table if exists pgbench_branches",
"create table pgbench_branches(bid int not null,bbalance int,filler char(88)) with (fillfactor=%d)",
"drop table if exists pgbench_tellers",
"create table pgbench_tellers(tid int not null,bid int,tbalance int,filler char(84)) with (fillfactor=%d)",
"drop table if exists pgbench_accounts",
"create table pgbench_accounts(aid int not null,bid int,abalance int,filler char(84)) with (fillfactor=%d)",
"drop table if exists pgbench_history",
"create table pgbench_history(tid int,bid int,aid int,delta int,mtime timestamp,filler char(22))"
};

  • 1262〜1270行目

                /*
* set fillfactor for branches, tellers and accounts tables
*/
if ((strstr(DDLs[i], "create table pgbench_branches") == DDLs[i]) ||
(strstr(DDLs[i], "create table pgbench_tellers") == DDLs[i]) ||
(strstr(DDLs[i], "create table pgbench_accounts") == DDLs[i]))
{
char ddl_stmt[128];