HammerDBでOracleのベンチマークテスト

# はじめに

HammerDBでOracleのベンチマークテストを行う。

# 環境

Ubuntu上のDockerにOracleのコンテナを立てて、その中にHammerDBというツールを入れて、測定する。

- Ubuntu 18.04.4 LTS (Bionic Beaver)
- [Oracle Database 11g ExpressEdition](https://www.oracle.com/technetwork/jp/database/database-technologies/express-edition/downloads/xe-prior-releases-5172097-ja.html)
- [oracle/docker-images](https://github.com/oracle/docker-images/tree/master/OracleDatabase/SingleInstance/dockerfiles/11.2.0.2)
- [HammerDB 3.3](https://hammerdb.com/document.html)
- Docker 19.03.6

# 測定するベンチマーク

TPC-C相当とTPC-H相当の性能値を測定する。「相当」のニュアンスは後述する。

TPCとはデータベースのベンチマークテストの仕様を策定している団体である。intel,OracleなどのIT系のHW、SWベンダーが参画している。

## TPC-C

TPCが公開しているベンチマークテストの中で最もオーソドックスなもの。OLTP(On-Line Transaction Processing)向けのベンチマークテスト。

具体的には以下の図のような発注システムに対して、insert/updateだけのトランザクションを実行したさいの1分あたりのトランザクション数を測定するベンチマークである。

![](https://www.hammerdb.com/docs/resources/ch3-2.png)

図中のWはスケールファクタである。この値を任意に変更することで異なるスケールのベンチマーク測定が可能である。ただし、スケールファクタが異なるベンチマーク同士の比較はできないことに注意する。

このとき、トランザクションは以下の5種類ある。この5種類を一定の割合でランダムに実行したときの性能を測定する。

- New-order: receive a new order from a customer: 45%
- Payment: update the customers balance to record a payment: 43%
- Delivery: deliver orders asynchronously: 4%
- Order-status: retrieve the status of customers most recent order: 4%
- Stock-level: return the status of the warehouses inventory: 4%

## TPC-H

TPCが公開しているベンチマークテストの中で2番目に有名なもの。Eコマース等の新しいビジネスシーンにおけるベンチマークを測定するために制定された。

具体的には以下の図のような発注システムに対して、select/deleteも含むトランザクションを実行した際の1クエリあたりの処理時間を測定するベンチマークである。

![](https://hammerdb.com/docs/resources/ch9-1.png)

このとき、クエリは22種類ある。それぞれのクエリは、TPC-Cより複雑で、より多くのデータを処理するものである。

ベンチマークには、この22種類の処理時間の平均値を用いる。

## TPC「相当」の意味

HammerDBによれば、TPCに完全に準拠するとコストも高く処理も複雑であるため、HammerDBではTPCに(based on)しているが、準拠していない(NOT implement a full specification)とする。

このため、厳密にTPCで測定した結果(tpmC)との比較は不可能である。

- TPC-C相当
    - TPM (Transaction per minute)：1分間に処理できるトランザクションの数。database typeによってトランザクションの定義が異なるため、異なるdatabase同士では比較できない。
    - NOPM (New Orders per minute)：1分間に処理できる新規注文(new order)の数。databaseによらずに等しく定義できるため、異なるdatabase同士で比較可能。
- TPC-H相当
    - the geomean of the query times: 1クエリあたりの幾何平均処理時間。

# HammerDBのダウンロード

[HammerDB 3.3](https://hammerdb.com/document.html)からLinux向けのインストーラをダウンロード

# docker-image起動

- 以下のサイトの [oracle/docker-imagesのREADME](https://github.com/oracle/docker-images/tree/master/OracleDatabase/SingleInstance/) に従って、Oracleコンテナを起動する。
- HammerDBを起動したOracleコンテナに入れる。

# 事前設定

ライブラリパスを設定する。これを設定しないと、hammerdbがOracle Instance Clientのlibファイルを発見できず、OracleDBへのアクセスができない。

```shell:bash
export LD_LIBRARY_PATH=$ORACLE_HOME/lib
```

# TPC-C

## 事前設定

sqlplusを起動する。ここでユーザ名はsystem、パスワードはmanager、Oracleへ接続するポート番号は1521とする。

```shell:bash
sqlplus system/manager@//localhost:1521/XE
```

次に、表領域を作成する。`size 1g`は環境に応じて変えて良い。なお、HammerDBのオフィシャルマニュアルでは`100g`となっている。

```sql:sqlplus
create bigfile tablespace tpcctab datafile '/u01/app/oracle/oradata/XE/tpcctab.dbf' size 1g; 
```

## hammerdbcli起動

次にhammerdbのCLIツールを起動する。GUI版もあるがDockerの中にアクセスできないので、CLI版を使う。

```shell:bash
./hammerdbcli
```

## TPC-C実行設定

TPC-Cの実行設定をする。

```shell:hammercli
print dict
dbset db ora
dbset bm TPC-C
diset connection system_user system
diset connection system_password manager
diset connection instance localhost:1521/XE
diset tpcc ora_driver timed
diset tpcc timeprofile true
print dict
```

ここでやっているのは次のようなことである。

- `print` : 設定内容を標準出力に表示する。ここでは`dict`と呼ばれる`connection`と`tpcc`の設定を表示する。
- `dbset db`: データベースの種類を指定。MySQLなども指定できるが今回はora(Oracle)を指定。
- `dbset bm` : ベンチマークの種類を指定。ここではTPC-Cを選択。
- `diset connection` : データベースへ接続するユーザ名、パスワード、インスタンスのパスを指定。
- `diset tpcc` : TPC-Cの実行設定。

## スキーマ生成

次にベンチマークテストに使うスキーマを作成する。

```shell:hammercli
vustatus
buildschema
vustatus
vudestroy
vustatus
```

ここでやっているのは次のようなことである。

- `vustatus` : データベースへトランザクションを接続する仮想ユーザ(Virtual User)の状態を確認する。
- `buildschema` : スキーマを作成する。 5分くらいかかる。
- `vudestroy` : 仮想ユーザを破棄する。スキーマ作成時に、仮想ユーザを自動的に作るが、破棄されずに残り続ける。このため、イチイチ破棄すること。仮想ユーザを破棄せず新しい仮想ユーザを作成することはできない。

## TPC-C実行

TPC-Cに使うスクリプトを読み込む。

```shell:hammercli
loadscript
```

ベンチマーク実行設定をする。

```shell:hammercli
print vuconf
vuset vu 4
vuset logtotemp 1
vuset unique 1
vuset timestamps 1
print vuconf
```

ここでやっているのは次のようなことである。

- `vuset vu` : 仮想ユーザ数を4に設定する。

最後に、ベンチマークテストを実行する。

```shell:hammercli
vucreate
vustatus
vurun
```

ここでやっているのは次のようなことである。

- `vucreate` : 仮想ユーザを作成する。
- `vurun` : ベンチマークテストを実行する。

## 結果の確認

結果を確認する。仮想ユーザ数を1,10,20と変更しつつ3回実行した。

```text:仮想ユーザ数=1
Vuser 1:Test complete, Taking end AWR snapshot.
Vuser 1:End Snapshot 19 taken at 29 FEB 2020 15:54 of instance XE (1) of database XE (2914738967)
Vuser 1:Test complete: view report from SNAPID 18 to 19
Vuser 1:1 Active Virtual Users configured
Vuser 1:TEST RESULT : System achieved 0 Oracle TPM at 3566 NOPM
Vuser 1:FINISHED SUCCESS
Vuser 2:|PERCENTILES 2020-02-29 15:54:20 to 2020-02-29 15:54:30
Vuser 2:|slev|MIN-68544|P50%-87479|P95%-111317|P99%-123524|MAX-125753|SAMPLES-62
Vuser 2:|neword|MIN-1082|P50%-3401|P95%-6400|P99%-7013|MAX-7698|SAMPLES-602
Vuser 2:|payment|MIN-772|P50%-1694|P95%-3020|P99%-3533|MAX-6903|SAMPLES-643
Vuser 2:|delivery|MIN-2579|P50%-7346|P95%-12301|P99%-12916|MAX-13242|SAMPLES-64
Vuser 2:|ostat|MIN-211|P50%-987|P95%-1362|P99%-1536|MAX-1683|SAMPLES-74
Vuser 2:|gettimestamp|MIN-3|P50%-12|P95%-19|P99%-31|MAX-78|SAMPLES-1307
Vuser 2:+-----------------+--------------+------+--------+--------------+--------------+
Vuser 2:+-----------------+--------------+------+--------+--------------+--------------+
Vuser 2:|PROCNAME | EXCLUSIVETOT| %| CALLNUM| AVGPERCALL| CUMULTOT|
Vuser 2:+-----------------+--------------+------+--------+--------------+--------------+
Vuser 2:|slev | 235086228|59.65%| 2436| 96505| 235090068|
Vuser 2:|neword | 88018839|22.33%| 24682| 3566| 92603011|
Vuser 2:|payment | 48539203|12.32%| 24771| 1959| 53133283|
Vuser 2:|delivery | 18963964| 4.81%| 2493| 7606| 19421429|
Vuser 2:|ostat | 1960477| 0.50%| 2402| 816| 1964192|
Vuser 2:|gettimestamp | 1567613| 0.40%| 51946| 30| 9125952|
Vuser 2:|TOPLEVEL | 2900| 0.00%| 1| 2900| NOT AVAILABLE|
Vuser 2:|prep_statement | 190| 0.00%| 5| 38| 193|
Vuser 2:+-----------------+--------------+------+--------+--------------+--------------+
```

```text:仮想ユーザ数=10
Vuser 1:Test complete, Taking end AWR snapshot.
Vuser 1:End Snapshot 9 taken at 29 FEB 2020 06:58 of instance XE (1) of database XE (2914738967)
Vuser 1:Test complete: view report from SNAPID 8 to 9
Vuser 1:10 Active Virtual Users configured
Vuser 1:TEST RESULT : System achieved 0 Oracle TPM at 6160 NOPM
Vuser 1:FINISHED SUCCESS
Vuser 6:FINISHED SUCCESS
Vuser 2:+-----------------+--------------+------+--------+--------------+--------------+
Vuser 2:|PROCNAME | EXCLUSIVETOT| %| CALLNUM| AVGPERCALL| CUMULTOT|
Vuser 2:+-----------------+--------------+------+--------+--------------+--------------+
Vuser 2:|payment | 167509068|40.27%| 3574| 46868| 168294670|
Vuser 2:|neword | 163009998|39.19%| 3576| 45584| 163828652|
Vuser 2:|slev | 60987628|14.66%| 349| 174749| 60988291|
Vuser 2:|delivery | 18169353| 4.37%| 338| 53755| 18241982|
Vuser 2:|ostat | 6046076| 1.45%| 355| 17031| 6046685|
Vuser 2:|gettimestamp | 271617| 0.07%| 7488| 36| 1585888|
Vuser 2:|TOPLEVEL | 4239| 0.00%| 1| 4239| NOT AVAILABLE|
Vuser 2:|prep_statement | 258| 0.00%| 5| 51| 262|
```

```text:仮想ユーザ数=20
Vuser 1:Test complete, Taking end AWR snapshot.
Vuser 1:End Snapshot 7 taken at 29 FEB 2020 06:39 of instance XE (1) of database XE (2914738967)
Vuser 1:Test complete: view report from SNAPID 6 to 7
Vuser 1:20 Active Virtual Users configured
Vuser 1:TEST RESULT : System achieved 0 Oracle TPM at 4586 NOPM
Vuser 1:FINISHED SUCCESS
Vuser 16:FINISHED SUCCESS
Vuser 2:+-----------------+--------------+------+--------+--------------+--------------+
Vuser 2:|PROCNAME | EXCLUSIVETOT| %| CALLNUM| AVGPERCALL| CUMULTOT|
Vuser 2:+-----------------+--------------+------+--------+--------------+--------------+
Vuser 2:|payment | 335498296|80.19%| 1652| 203086| 335847374|
Vuser 2:|neword | 45454611|10.86%| 1650| 27548| 45822267|
Vuser 2:|slev | 29101355| 6.96%| 178| 163490| 29101637|
Vuser 2:|delivery | 6049313| 1.45%| 148| 40873| 6081430|
Vuser 2:|ostat | 2138440| 0.51%| 148| 14448| 2138723|
Vuser 2:|gettimestamp | 120737| 0.03%| 3450| 34| 706725|
Vuser 2:|TOPLEVEL | 3002| 0.00%| 1| 3002| NOT AVAILABLE|
Vuser 2:|prep_statement | 300| 0.00%| 5| 60| 303|
Vuser 2:+-----------------+--------------+------+--------+--------------+--------------+
```

# TPC-H

## 事前設定

sqlplusを起動する。ここでユーザ名はsystem、パスワードはmanager、Oracleへ接続するポート番号は1521とする。

```shell:bash
sqlplus system/manager@//localhost:1521/XE
```

次に、表領域を作成する。`size 1g`は環境に応じて変えて良い。なお、HammerDBのオフィシャルマニュアルでは`100g`となっている。

```sql:sqlplus
create bigfile tablespace tpchtab datafile '/u01/app/oracle/oradata/XE/tpchtab.dbf' size 1g; 
```

## hammerdbcli起動

次にhammerdbのCLIツールを起動する。GUI版もあるがDockerの中にアクセスできないので、CLI版を使う。

```shell
./hammerdbcli
```

## TPC-H実行設定

TPC-Hの実行設定をする。

```shell:hammercli
print dict
dbset db ora
dbset bm TPC-H
diset connection system_user system
diset connection system_password manager
diset connection instance localhost:1521/XE
print dict
```

ここでやっているのは次のようなことである。

- `print` : 設定内容を標準出力に表示する。ここでは`dict`と呼ばれる`connection`と`tpcc`の設定を表示する。
- `dbset db`: データベースの種類を指定。MySQLなども指定できるが今回はora(Oracle)を指定。
- `dbset bm` : ベンチマークの種類を指定。ここではTPC-Cを選択。
- `diset connection` : データベースへ接続するユーザ名、パスワード、インスタンスのパスを指定。

## スキーマ生成

次にベンチマークテストに使うスキーマを作成する。

```shell:hammercli
vustatus
buildschema
vustatus
vudestroy
vustatus
```

ここでやっているのは次のようなことである。

- `vustatus` : データベースへトランザクションを接続する仮想ユーザ(Virtual User)の状態を確認する。
- `buildschema` : スキーマを作成する。 5分くらいかかる。
- `vudestroy` : 仮想ユーザを破棄する。スキーマ作成時に、仮想ユーザを自動的に作るが、破棄されずに残り続ける。このため、イチイチ破棄すること。仮想ユーザを破棄せず新しい仮想ユーザを作成することはできない。

## TPC-H実行

TPC-Hに使うスクリプトを読み込む。

```shell:hammercli
loadscript
```

ベンチマーク実行設定をする。

```shell:hammercli
print vuconf
vuset vu 4
vuset logtotemp 1
vuset unique 1
vuset timestamps 1
print vuconf
```

ここでやっているのは次のようなことである。

- `vuset vu` : 仮想ユーザ数を4に設定する。

最後に、ベンチマークテストを実行する。

```shell:hammercli
vucreate
vustatus
vurun
```

ここでやっているのは次のようなことである。

- `vucreate` : 仮想ユーザを作成する。
- `vurun` : ベンチマークテストを実行する。

## 結果の確認

結果を確認する。仮想ユーザ数を1,10,20と変更しつつ3回実行した。

```shell:仮想ユーザ数=1の場合
Vuser 1:Completed 1 query set(s) in 25 seconds
```

```shell:仮想ユーザ数=10の場合
Vuser 7:Completed 1 query set(s) in 157 seconds
Vuser 1:Completed 1 query set(s) in 162 seconds
Vuser 4:Completed 1 query set(s) in 161 seconds
Vuser 3:Completed 1 query set(s) in 163 seconds
Vuser 5:Completed 1 query set(s) in 164 seconds
Vuser 2:Completed 1 query set(s) in 167 seconds
Vuser 9:Completed 1 query set(s) in 166 seconds
Vuser 10:Completed 1 query set(s) in 167 seconds
Vuser 8:Completed 1 query set(s) in 168 seconds
Vuser 6:Completed 1 query set(s) in 170 seconds
```

```shell:仮想ユーザ数=20の場合
Vuser 11:Completed 1 query set(s) in 273 seconds
Vuser 5:Completed 1 query set(s) in 292 seconds
Vuser 7:Completed 1 query set(s) in 309 seconds
Vuser 12:Completed 1 query set(s) in 307 seconds
Vuser 4:Completed 1 query set(s) in 318 seconds
Vuser 6:Completed 1 query set(s) in 322 seconds
Vuser 15:Completed 1 query set(s) in 326 seconds
Vuser 2:Completed 1 query set(s) in 339 seconds
Vuser 9:Completed 1 query set(s) in 336 seconds
Vuser 14:Completed 1 query set(s) in 334 seconds
Vuser 3:Completed 1 query set(s) in 343 seconds
Vuser 8:Completed 1 query set(s) in 341 seconds
Vuser 10:Completed 1 query set(s) in 343 seconds
Vuser 1:Completed 1 query set(s) in 350 seconds
Vuser 16:Completed 1 query set(s) in 344 seconds
Vuser 19:Completed 1 query set(s) in 348 seconds
Vuser 18:Completed 1 query set(s) in 349 seconds
Vuser 17:Completed 1 query set(s) in 350 seconds
Vuser 20:Completed 1 query set(s) in 348 seconds
Vuser 13:Completed 1 query set(s) in 354 seconds
```

`1 query set(s)`が各仮想ユーザの22個のクエリの幾何平均値。しかし、全仮想ユーザの幾何平均値は算出されないらしい。

# 参考サイト

https://qiita.com/gorilla0513/items/f22e8cce4e08da031abe
https://atsuizo.hatenadiary.jp/entry/2019/08/29/090000

------------------------------------
<!--

```sql:18c
alter session set container = XEPDB1;
create bigfile tablespace tpcctab datafile '/opt/oracle/oradata/XE/tpcctab.dbf' size 1g;
create user tpcc identified by tpcc default tablespace tpcctab temporary tablespace temp;
grant connect,resource, create view to tpcc;
alter user tpcc quota unlimited on tpcctab;
```
-->