MySQLのベンチマークツールはいくつかありますが、今回は弊社でもよく利用している sysbench について紹介したいと思います。
sysbench とは?
sysbench はよくデータベースのベンチマークとして使用されますが、ファイルシステムやCPU、メモリなどシステムのベンチマークを行うこともできます。
また、Luaスクリプトで独自のベンチマークシナリオを作成することも可能です。
(弊社記事: sysbench 1.0 でオリジナルのベンチマークシナリオを作成する)
デフォルトのベンチマークシナリオでは比較的処理としてはシンプルなため、データベースの基本性能を測るために使用されることが多い印象です。
参考 : akopytov/sysbench: Scriptable database and system performance benchmark
インストール
インストールは下記の手順のみなので、比較的簡単に使い始めることができます。
1 2 |
curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash sudo yum -y install sysbench |
基本的な使い方
sysbench は以下のようにオプションやテストシナリオ、コマンドを指定して実行します
1 |
$ sysbench [オプション] [テストシナリオ] [コマンド] |
実行例としては以下のようになります。
1 2 3 4 5 6 7 |
$ sysbench --db-driver=mysql \ --mysql-host=172.16.56.200 \ --mysql-user=bench_user \ --mysql-password=password \ --mysql-db=benchmark \ oltp_read_write \ run |
コマンド
MySQL のベンチマークを実行する場合は、以下のようなコマンドがあります。
コマンド名 | 説明 |
---|---|
prepare | テスト用テーブルを作成してテスト用データを作成 |
run | ベンチマークシナリオを実行 |
cleanup | テスト用テーブルを削除 |
help | ベンチマークシナリオのヘルプを表示 |
ベンチマークシナリオ
デフォルトで使用できるベンチマークシナリオはいくつかありますが、よく使われるのは以下になります。
ベンチマークシナリオ名 | 説明 |
---|---|
oltp_read_write | 読み込み/書き込みの OLTP 処理 |
oltp_read_only | 読み込みのみの OLTP 処理 |
oltp_write_only | 書き込みのみの OLTP 処理 |
それ以外のベンチマークシナリオは以下のコードを参考にしてください。
sysbench/src/lua at master · akopytov/sysbench · GitHub
オプション
オプションについてはグローバルなオプションと、テストシナリオに紐づくオプションの2種類があります。
オプションは多岐にわたるため、ここではよく使われるオプションを紹介します。
グローバルオプション
1 2 3 |
--threads=N number of threads to use [1] --events=N limit for total number of events [0] --time=N limit for total execution time in seconds [10] |
オプション名 | 説明 | デフォルト値 |
---|---|---|
threads | 同時実行するスレッド数。MySQLでは同時接続数 | 1 |
events | 実行する合計イベント数 | 0(無制限) |
time | ベンチマークの実行時間。秒数で指定 | 10秒 |
1 |
--db-driver=STRING specifies database driver to use ('help' to get list of available drivers) |
MySQLのベンチマークの場合は上記オプションでは「mysql」を指定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
mysql options: --mysql-host=[LIST,...] MySQL server host [localhost] --mysql-port=[LIST,...] MySQL server port [3306] --mysql-socket=[LIST,...] MySQL socket --mysql-user=STRING MySQL user [sbtest] --mysql-password=STRING MySQL password [] --mysql-db=STRING MySQL database name [sbtest] --mysql-ssl[=on|off] use SSL connections, if available in the client library [off] --mysql-ssl-cipher=STRING use specific cipher for SSL connections [] --mysql-compression[=on|off] use compression, if available in the client library [off] --mysql-debug[=on|off] trace all client library calls [off] --mysql-ignore-errors=[LIST,...] list of errors to ignore, or "all" [1213,1020,1205] --mysql-dry-run[=on|off] Dry run, pretend that all MySQL client API calls are successful without executing them [off] |
上記はMySQLの接続設定のオプションです。
接続先設定はカンマ区切りで複数指定することができます。
ただし、書き込みはこのホスト、読み込みはこのホストというように接続先の振り分けができないので、通常のレプリケーション構成の場合、更新処理だけをマスターサーバーに向けて、参照処理をスレーブサーバーに向けるようなことができません。
「mysql-ignore-errors」については、ベンチマーク実行中に発生したエラーを無視する設定です。エラーコードもしくは”all”を指定します。、カンマ区切りで複数指定することも可能です。
デフォルトでは以下のエラーコードが設定されています
エラーコード | 説明 |
---|---|
1213 | デッドロック |
1020 | 表 ‘%s’ の最後の読み取り時点から、レコードが変化しました |
1205 | ロック待ちがタイムアウトしました。トランザクションを再試行してください |
参考:
MySQL :: MySQL 5.6 リファレンスマニュアル :: 14.19.5 InnoDB のエラーコード
MySQL :: MySQL 5.6 リファレンスマニュアル :: B.3 サーバーのエラーコードおよびメッセージ
シナリオ(oltp_read_write)のオプション
各ベンチマークシナリオのオプションは下記のように「help」コマンドを実行することでオプションが表示されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$ sysbench --db-driver=mysql oltp_read_write help sysbench 1.0.10 (using bundled LuaJIT 2.1.0-beta2) oltp_read_write options: --distinct_ranges=N Number of SELECT DISTINCT queries per transaction [1] --sum_ranges=N Number of SELECT SUM() queries per transaction [1] --skip_trx[=on|off] Don't start explicit transactions and execute all queries in the AUTOCOMMIT mode [off] --secondary[=on|off] Use a secondary index in place of the PRIMARY KEY [off] --create_secondary[=on|off] Create a secondary index in addition to the PRIMARY KEY [on] --index_updates=N Number of UPDATE index queries per transaction [1] --range_size=N Range size for range SELECT queries [100] --auto_inc[=on|off] Use AUTO_INCREMENT column as Primary Key (for MySQL), or its alternatives in other DBMS. When disabled, use client-generated IDs [on] --delete_inserts=N Number of DELETE/INSERT combination per transaction [1] --tables=N Number of tables [1] --mysql_storage_engine=STRING Storage engine, if MySQL is used [innodb] --non_index_updates=N Number of UPDATE non-index queries per transaction [1] --table_size=N Number of rows per table [10000] --pgsql_variant=STRING Use this PostgreSQL variant when running with the PostgreSQL driver. The only currently supported variant is 'redshift'. When enabled, create_secondary is automatically disabled, and delete_inserts is set to 0 --simple_ranges=N Number of simple range SELECT queries per transaction [1] --order_ranges=N Number of SELECT ORDER BY queries per transaction [1] --range_selects[=on|off] Enable/disable all range SELECT queries [on] --point_selects=N Number of point SELECT queries per transaction [10] |
よく使うオプションとしては下記の2つです
1 2 |
--tables=N Number of tables [1] --table_size=N Number of rows per table [10000] |
オプション名 | 説明 | デフォルト値 |
---|---|---|
tables | テストテーブルの数を指定 | 1 |
table_size | 1つのテストテーブルに挿入されるテストデータのレコード数 | 10000 |
それ以外にも以下のようなオプションを指定することで、作られるテストテーブルの設定が変わります。
--secondary=off
(デフォルト)
1 2 3 4 5 6 7 8 9 10 11 12 |
mysql> show create table sbtest1\G *************************** 1. row *************************** Table: sbtest1 Create Table: CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120) NOT NULL DEFAULT '', `pad` char(60) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) |
idカラムをプライマリーキーとしてテストテーブルを作成します。
--secondary=on
1 2 3 4 5 6 7 8 9 10 11 12 |
mysql> show create table sbtest1\G *************************** 1. row *************************** Table: sbtest1 Create Table: CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120) NOT NULL DEFAULT '', `pad` char(60) NOT NULL DEFAULT '', KEY `xid` (`id`), KEY `k_1` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) |
id カラムをプライマリーキー指定せずにセカンダリインデックスとしてテストテーブルを作成します。
--create_secondary=off
1 2 3 4 5 6 7 8 9 10 11 |
mysql> show create table sbtest1\G *************************** 1. row *************************** Table: sbtest1 Create Table: CREATE TABLE `sbtest1` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120) NOT NULL DEFAULT '', `pad` char(60) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=latin1 1 row in set (0.00 sec) |
セカンダリインテックスを作成しないでテストテーブルを作成します。
インデックスの有無による性能差や、プライマリインデックスとセカンダリインデックスの性能差を見るために使うと良いかと思います。
oltp_read_write ベンチマークシナリオで実行されるクエリ
MySQLの「long_query_time」を0秒に指定して、ベンチマーク実行中に発行されるクエリを取得してみました。
種別によるクエリの割合は以下の通りです。
種別 | 割合 |
---|---|
SELECT | 82% |
UPDATE | 12% |
INSERT | 6% |
参照クエリーが全体の8割以上を占めています。
個別のクエリの実行回数と実行例です。シンプルなクエリのみで構成されています。
実行回数 | クエリ |
---|---|
316450 | SELECT c FROM sbtest3 WHERE id=5011 |
31645 | SELECT DISTINCT c FROM sbtest1 WHERE id BETWEEN 5025 AND 5124 ORDER BY c |
31645 | SELECT c FROM sbtest4 WHERE id BETWEEN 4981 AND 5080 ORDER BY c |
31645 | SELECT c FROM sbtest3 WHERE id BETWEEN 4232 AND 4331 |
31645 | UPDATE sbtest5 SET k=k+1 WHERE id=4996 |
31645 | SELECT SUM(k) FROM sbtest4 WHERE id BETWEEN 4984 AND 5083 |
31645 | UPDATE sbtest4 SET c=’33807164901-98674870960-30739544988-00494030323-58074804184-54497108430-96465631765-54975371777-86989435703-06577856858′ WHERE id=5023 |
31645 | INSERT INTO sbtest5 (id, k, c, pad) VALUES (4498, 5023, ‘81672753779-75750369178-87933664834-21280372467-27872254074-27478851448-54563374845-76108710036-90957389581-17596638045’, ‘40711790231-95597061593-77660822141-56395044528-86019133058’) |
まとめ
今回はMySQLのベンチマークとしてよく使われている sysbench について基本的な使い方から、実行されているクエリーについて紹介させていただきました。MySQLで使えるベンチマークツールはsysbench以外にもあるので機会があればそれらについても紹介させていただければと思います。