HammerDBを使用してPostgreSQLのベンチマークを実施する

# TPCベンチマーク

TPC（Transaction Processing Performance Council)はデータベースのベンチマークの基準を定義している団体です。
OLTP向け（TPC-C、TPC-E）、データウェアハウス向け（TPC-H）などの性能評価基準があります。

このTPCに対応したPostgreSQL用のベンチマークツールは、JdbcRunnerやHammerDBなどがあります。

- [JdbcRunner](https://dbstudy.info/jdbcrunner/) 　TPC-C,TPC-Bに対応。ただし、一部TPC仕様に準拠していない。
- [HammerDB](https://hammerdb.com/)　TPC-C,TPC-Hに対応。ただし、一部TPC仕様に準拠していない。

今回はHammerDBを使用してTPC-Cのベンチマークを実行してみます。

[TPC-C](http://www.tpc.org/tpcc/default5.asp)は、OLTP向けのベンチマークで9つのテーブルに対して5種類のトランザクションが実行されます。OLTP向けには他にTPC-Cよりも複雑なトランザクション処理であるTPC-Eもありますが、対応したツールが見つけられなかったのでTPC-Cを対象にしています。


# 環境

今回利用する環境は以下のとおり。試しなのでDBもベンチマークも同一サーバ上で実行します。

- CentOS 7.5
- PostgreSQL 12


# HammerDBのインストール

以下からモジュールをダウンロードします。
https://hammerdb.com/download.html

「Release 3.3 for Linux 64-bit compressed tar file」をダウンロードし、サーバ上でtar.gzファイルを展開します。

```
tar xvzf HammerDB-3.3.tar.gz
cd HammerDB-3.3
```


# PostgreSQLのライブラリ確認

PostgreSQLに接続するためのライブラリがインストールされているか、librarycheckコマンドで確認します。
今回はHammerDBをPostgreSQLと同じサーバにインストールしているのでライブラリはインストール済みです。


```
# ./hammerdbcli
HammerDB CLI v3.3
Copyright (C) 2003-2019 Steve Shaw
Type "help" for a list of commands
The xml is well-formed, applying configuration
hammerdb>librarycheck
Checking database library for Oracle
Oratcl_Init(): Failed to load /usr/lib/oracle/12.2/client64/lib/lib/libclntsh.so with error /usr/lib/oracle/12.2/client64/lib/lib/libclntsh.so: cannot open shared object file: No such file or directory
Error: failed to load Oratcl - 
Ensure that Oracle client libraries are installed and the location in the LD_LIBRARY_PATH environment variable
Checking database library for MSSQLServer
Error: failed to load tdbc::odbc - couldn't load file "libiodbc.so": libiodbc.so: cannot open shared object file: No such file or directory
Ensure that MSSQLServer client libraries are installed and the location in the LD_LIBRARY_PATH environment variable
Checking database library for Db2
Error: failed to load db2tcl - couldn't load file "/root/HammerDB-3.3/lib/db2tcl2.0.0/libdb2tcl.so.0.0.1": libdb2.so.1: cannot open shared object file: No such file or directory
Ensure that Db2 client libraries are installed and the location in the LD_LIBRARY_PATH environment variable
Checking database library for MySQL
Error: failed to load mysqltcl - couldn't load file "/root/HammerDB-3.3/lib/mysqltcl-3.052/libmysqltcl3.052.so": libmysqlclient.so.21: cannot open shared object file: No such file or directory
Ensure that MySQL client libraries are installed and the location in the LD_LIBRARY_PATH environment variable
Checking database library for PostgreSQL
Success ... loaded library Pgtcl for PostgreSQL★Successになっている
Checking database library for Redis
Success ... loaded library redis for Redis
```


# スキーマ作成

ベンチマーク用のスキーマとテストデータを投入します。
なお、ベンチマーク用のtpccユーザが作成されるので、事前にログインできるようにpg_hba.confを設定しておきます。


```
# ./hammerdbcli

-- 対象DBをPostgreSQLにする
hammerdb>dbset db pg
Database set to PostgreSQL

-- 対象ベンチマークをTPC-Cに設定する
hammerdb>dbset bm TPC-C
Benchmark set to TPC-C for PostgreSQL

-- 接続先ホスト名を指定する。デフォルトはlocalhostなので変更する必要はなかったけど、試しに変更
hammerdb>diset connection pg_host 127.0.0.1
Changed connection:pg_host from localhost to 127.0.0.1 for PostgreSQL

-- スケールファクターを2倍に設定する
hammerdb>diset tpcc pg_count_ware 2
```

pg_count_wareがスケールファクタで、デフォルトだと各テーブルは以下のレコードが作成されます。

customer: 30000
district: 10
history: 30000
item: 100000
new_order: 9000
order_line: 300084
orders: 30000
stock: 100000
warehouse: 1

スケールファクタを"2"に設定すると、item以外のテーブルは2倍になります。
クライアントの並列度をあげた場合は、スケールファクタも調整が必要です。

customer: 60000
district: 20
history: 60000
item: 100000
new_order: 18000
order_line: 600993
orders: 60000
stock: 200000
warehouse: 2


buildschemaコマンドでスキーマを作成します。テストデータも同時に投入されます。

```
hammerdb>buildschema
～省略～
Vuser 1:FINISHED SUCCESS
ALL VIRTUAL USERS COMPLETE

hammerdb>vudestroy
```

なお、buildschemaに失敗した場合は以下を実行し、作成されたDBやテスト実行用クライアント（Virtual User）を削除します。

```
hammerdb>vudestroy

$ dropdb tpcc
$ dropuser tpcc
```


# テストスクリプトのロード

テストスクリプトをロードする前に、テストの設定を変更します。
今回は以下のように設定を変更。

```
-- 同時実行ユーザー数。デフォルトは"1"
hammerdb>diset tpcc pg_num_vu 10
hammerdb>diset tpcc pg_total_iterations 10000
hammerdb>diset tpcc pg_rampup 0
-- 動作検証までは「test」を、実計測時は「timed」を指定
hammerdb>diset tpcc pg_driver timed 
hammerdb>diset tpcc pg_duration 1
hammerdb>diset tpcc pg_timeprofile true
hammerdb>diset tpcc pg_storedprocs true -- これはエラーになったので結局実行せず
hammerdb>print dict
```

loadscriptコマンドでテストスクリプトをロードします。print scriptコマンドでスクリプトを確認できます。

```
hammerdb>loadscript
TPC-C Driver Script
Script loaded, Type "print script" to view
```


# テスト実行用クライアント（Virtual User）の設定

print vuconfコマンドでテスト実行用クライアント（Virtual User）を確認できます。

```
hammerdb>print vuconf
Virtual Users = 1
User Delay(ms) = 500
Repeat Delay(ms) = 500
Iterations = 1
Show Output = 1
Log Output = 0
Unique Log Name = 0
No Log Buffer = 0
Log Timestamps = 0
```

以下ではテスト実行用クライアント（Virtual User）を変更し、テスト実行用クライアントを生成しています。

```
hammerdb>vuset showoutput 1
hammerdb>vuset vu 4
hammerdb>vuset logtotemp 1
hammerdb>print vuconf

hammerdb>vucreate
Vuser 1 created MONITOR - WAIT IDLE
Vuser 2 created - WAIT IDLE
Vuser 3 created - WAIT IDLE
Vuser 4 created - WAIT IDLE
Vuser 5 created - WAIT IDLE
Logging activated
to /tmp/hammerdb.log
5 Virtual Users Created with Monitor VU

hammerdb>vustatus
1 = WAIT IDLE
2 = WAIT IDLE
3 = WAIT IDLE
4 = WAIT IDLE
5 = WAIT IDLE

```

「vuset logtotemp 1」を実行することで、ログが/tmp/hammerdb.logに出力されるようになります。


# ベンチマークの実行

vurunコマンドでベンチマークを実行できます。

```
hammerdb>vurun
RUNNING - PostgreSQL TPC-C Timed
Vuser 1:RUNNING
Vuser 1:Beginning rampup time of 0 minutes
Vuser 1:Rampup complete, Taking start Transaction Count.
Vuser 1:Timing test period of 1 in minutes
Vuser 2:RUNNING
Vuser 2:Processing 10000 transactions with output suppressed...
Vuser 3:RUNNING
Vuser 3:Processing 10000 transactions with output suppressed...
Vuser 4:RUNNING
Vuser 4:Processing 10000 transactions with output suppressed...
Vuser 5:RUNNING
Vuser 5:Processing 10000 transactions with output suppressed...

～省略～

Vuser 1:Test complete, Taking end Transaction Count.
Vuser 1:4 Active Virtual Users configured
Vuser 1:TEST RESULT : System achieved 6374 PostgreSQL TPM at 2771 NOPM
Vuser 1:FINISHED SUCCESS
```

TEST RESULTが結果で、今回はTPMが2,771となりました。

最後に終了処理をします。マニュアルに書いてたので実行しましたが、やらなくて次回実行しても問題なかったので本当に必要あるかは不明。

```
hammerdb>vucomplete
true
hammerdb>vudestroy
Destroying Virtual Users
Virtual Users Destroyed
vudestroy success

hammerdb>clearscript
Script cleared
````

実行結果、各テーブルのレコード数は以下のように変わりました。

customer: 60000
district: 20
history: 60000 -> 62873
item: 100000
new_order: 18000 -> 17925
order_line: 600993 -> 629353
orders: 60000 -> 62865
stock: 200000
warehouse: 2



# 参考

- [Chapter 8. Command Line Interface (CLI) 2. CLI Commands](https://www.hammerdb.com/docs/ch08s02.html)
- [HammerDB Documentation](https://www.hammerdb.com/docs/index.html)
- [HammerDBをCLIで使うなど：まとめ、あるいは、目次の代わりに](https://atsuizo.hatenadiary.jp/entry/2019/09/09/090000)
- [JdbcRunner](https://dbstudy.info/jdbcrunner/)
- [HammerDB](https://hammerdb.com/)
- [TPC-C](http://www.tpc.org/tpcc/default5.asp)