🐬

mysqlslap を用いた MySQL のロードテスト

2023/08/07に公開

https://dev.mysql.com/doc/refman/8.0/ja/mysqlslap.html
MySQL には mysqlslap という標準のロードテストツールが付属しています。こちらを用いて簡易的なデータベースのパフォーマンスの測定や負荷試験が実施できるようになっています

標準的な使い方としては検証用のテーブルも自動的に作成し(--auto-generate-sql)、そちらを用いて検証をする形になるかなと思います

mysqlslap --concurrency=5 --iterations=20
  --number-int-cols=2 --number-char-cols=3
  --auto-generate-sql

--auto-generate-sql を使用する場合、以下のように int 型と varchar 型のカラム2つのシンプルなデータベースを用いた検証になります

mysql> desc t1;
+----------+--------------+------+-----+---------+-------+
| Field    | Type         | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| intcol1  | int          | YES  |     | NULL    |       |
| charcol1 | varchar(128) | YES  |     | NULL    |       |
+----------+--------------+------+-----+---------+-------+

概ね多くの場合、より実践的な負荷試験を実施しようとすると、以下のような環境での検証が望ましいです。

  • 実際にサービスで使用しているデータベースを用いる
  • データ量についても本稼働の状況を反映したものを用いる

mysqlslap にももちろん任意の SQL を発行することが出来るオプションが存在しています。--create でテーブル作成用の SQL、--query で参照用の SQL を指定することができます。
どちらか片方の指定も可能。

mysqlslap --delimiter=";"
  --create="CREATE TABLE a (b int);INSERT INTO a VALUES (23)"
  --query="SELECT * FROM a" --concurrency=50 --iterations=200

直接 SQL を指定できるとすると、どこから実行する SQL を用意するか、どのように準備するか、というのが課題になりますが、個人的に一番有益そうなユースケースは 「SlowQuery として報告された SQL を mysqlslap 経由で流して性能測定」 かなと想像しています。
多くの正しく運用されているサービスでは SlowQuery についてはログで保存されていると思うので、そちらの情報を用いる事で、実際のワークロードに則した、そして負荷的にも性能的にも問題がある SQL についての検証が行えると思います。

SlowQuery の取得、準備の仕方はサービスによってまちまちだと思いますが、以下のような形で CSV 形式で SQL の一覧をまとめ

select * from A where...;
select * from B where...;
select * from C where...;

以下のような Shell を用意して実行してあげることで、mysqlslap 経由で複数の SQL を実行することができます。

COUNT=1
while read SQL
do
  echo "$COUNT: $SQL"
  COUNT=`expr $COUNT + 1`
  mysqlslap --user=$MYSQL_USER --password=$MYSQL_PASSWORD  --host=$MYSQL_HOST --engine=innodb --create-schema=$MYSQL_DB --concurrency=$CONCURRENCY --iterations=$ITERATIONS --query="$SQL"
  echo ""
done < $CSV

(CSV には、実行したい SQL が格納されている SQL ファイルのパスを指定。他のパラメータは名前で察してください)

ちなみに、mysqlslap コマンドは --query オプションにファイル名を渡すことができるので、上記のような Shell は不要に思えますが、--query 内で実行エラーを起こすような SQL が記載されているとそこで処理がストップしてしまうため、動くか動かないか確証が得られない雑多な SQL を自動的に取得してきているようなケースだと、SQL を一本一本実行するスタイルの方が実用上は便利だと思います。

Discussion