MariaDB(mysql)をsysbenchでベンチマークする

# はじめに
DBのバージョンアップをするときや、パラメタ変更をする際、性能が劣化していないか、または狙った通りに性能が向上しているかを確認することは重要です。今回はsysbenchというツールを使ってみました。

# sysbenchとは
https://github.com/akopytov/sysbench

DBのベンチマークとしてもよく使われますが、サーバのCPU、memory、fileioを計測することもできます。DBに対してはoltp(OnLine Transaction Processing)を使って計測します。

# sysbenchのバージョン
環境はCentOS 6.7です。yumではepelをリポジトリを追加すればinstallできます。インストール方法は省略します。

```
# sysbench --version
sysbench 1.0.9
```

1.0.9を使いました。1系とそれ以前では挙動がかなり違うようなので注意。

# テスト用データベース作成
事前にテスト用のデータベースとユーザを作成しておきましょう。sysbenchはデフォルトでsbtestユーザで接続しにいきます。

```
MariaDB [(none)]> create database sbtest;
Query OK, 1 row affected (0.00 sec)

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sbtest             |
| test               |
+--------------------+
5 rows in set (0.01 sec)

MariaDB [(none)]> GRANT ALL ON sbtest.* TO 'sbtest'@'localhost' IDENTIFIED BY 'sbtest';
Query OK, 0 rows affected (0.00 sec)
```
# テスト用テーブル作成
さて、次はテスト用のテーブル作成ですが、ここからはsysbenchを使用します。

```
# sysbench /usr/share/sysbench/oltp_read_write.lua --db-driver=mysql --table-size=1000000 --mysql-host=localhost --mysql-password=sbtest --time=60 --db-ps-mode=disable prepare
```

* 引数の1つ目でlua scriptを指定します。sysbenchをinstallすると/usr/share/sysbench以下にlua scriptが配置されます。
* db-driverとしてmysqlを指定します。
* table-sizeは100万を指定
* db-ps-modeはprepared-statement、つまりdatabase serverが用意したAPIを使うかどうか。disableとautoが選択可能。

その他接続情報は環境に合わせてください。

# テスト実施
runで実行します。

```
# sysbench /usr/share/sysbench/oltp_read_write.lua --db-driver=mysql --table-size=100000 --mysql-host=localhost --mysql-password=sbtest --time=60 --db-ps-mode=disable --threads=8 run
```

thread数を指定できます。デフォルトは1です。

```
# sysbench /usr/share/sysbench/oltp_read_write.lua --db-driver=mysql --table-size=100000 --mysql-host=localhost --mysql-password=sbtest --time=60 --db-ps-mode=disable --threads=8 run
sysbench 1.0.9 (using system LuaJIT 2.0.4)

Running the test with following options:
Number of threads: 8
Initializing random number generator from current time


Initializing worker threads...

Threads started!

SQL statistics:
    queries performed:
        read:                            365400
        write:                           104362
        other:                           52187
        total:                           521949
    transactions:                        26087  (434.71 per sec.)
    queries:                             521949 (8697.58 per sec.)
    ignored errors:                      13     (0.22 per sec.)
    reconnects:                          0      (0.00 per sec.)

General statistics:
    total time:                          60.0093s
    total number of events:              26087

Latency (ms):
         min:                                  3.52
         avg:                                 18.40
         max:                                 72.39
         95th percentile:                     24.38
         sum:                             479986.45

Threads fairness:
    events (avg/stddev):           3260.8750/10.51
    execution time (avg/stddev):   59.9983/0.00
```

60秒間実行した結果が出ます。性能指標にはtransactionsの値を見るとよいでしょう。

# script化
prepare/run/cleanを実行できるようscript化しました。

```bash:sysbench.sh
#!/bin/sh
LUA=/usr/share/sysbench/oltp_read_write.lua
SIZE=1000000
usage()
{
  echo "Usage: ./sysbench.sh <prepare|run|cleanup> <num of threads>"
  exit "${1}"
}
#chack argumets
if [ "${1}" = "" -o $# -gt 3 ]; then
  usage 1
elif [ "${2}" = "" ]; then
  THREADS=1
else
  THREADS=${2}
fi
sysbench ${LUA} --db-driver=mysql --table-size=${SIZE} --mysql-host=localhost --mysql-password=sbtest --time=60 --db-ps-mode=disable --threads=${THREADS} ${1}
```

このrunをさらにラップし、thread数を変化させて実行するscriptです。

```bash:run.sh
#!/bin/sh
DATE=`date '+%Y%m%d%H%M'`
mkdir $DATE
for thread in 1 2 4 8 16 64 256
do
  ./sysbench.sh run ${thread} >> ${DATE}/sysbench_read_write_${thread}.log
done
```

さらに各thread数での結果のtransaction数を表示するscript。

```bash:result.sh
#!/bin/sh
usage()
{
  echo "Usage: ./result.sh <result's directory>"
  exit "${1}"
}
#chack argumets
if [ "${1}" = "" -o $# -gt 2 ]; then
  usage 1
fi
grep transaction ${1}/*.log | sort -t _ -nk3 | awk '{print $3}'
```
# おわりに
DBのバージョンアップ時や、パラメタ変更時にベンチマークを実施できると安心ですね。

# おまけ：MariaDBバージョン間比較
MariaDBの5.5、10.0、10.1、10.2の各最新版をclean installした結果で、thread数を変えて実施してみました。


|   |5.5.45|10.0.33|10.1.28|10.2.10|
|---|------|-------|-------|-------|
|1  |21516 |19136  |18413  |18942  |
|2  |24803 |28070  |24875  |26851  |
|4  |23361 |20814  |20271  |19981  |
|8  |24338 |24357  |22879  |23146  |
|16 |25256 |27744  |24751  |26371  |
|64 |24425 |26731  |24579  |25566  |

![image.png](https://qiita-image-store.s3.amazonaws.com/0/64903/f994589a-8cb8-ffec-9c4b-bc673e9d4b3a.png)

maxconのdefaultが151のため、256では計測できませんでした。5系と10系で傾向が違うような気もしますが、内部構造に明るいわけではないので、この結果からの考察は特にありません。