この記事は 株式会社カオナビ Advent Calendar 2025 シリーズ3の18日目です。
前回のおさらい
株式会社カオナビ Advent Calendar 2025 シリーズ3 17日目 の記事で MySQL Shell を使ったダンプリストアの方法を説明しました。
従来の mysqldump 同様ローカルストレージ上にファイルとして出力する方法だけではなく、S3 バケットに出力する方法、そういった一時ファイルを出力することなく1ステップでコピーする方法と様々な方法を説明しましたが、速度に関しては言及していませんでした。
今回はそれぞれの方法でどれくらい速度が違うのかを比較してみようと思います。
前回とは違った使い方
ベンチマークの結果を示す前に、前回説明したものとは違った MySQL Shell の使い方の説明をしておきます。
前回は、別途 dumpInstanceFile.js のようなファイルを作成しておいて、それをMySQL Shell に渡すというやり方をしていました。
util.dumpInstance('/home/kunit/mysql-shell-test/dump-files/dump-instance', {
threads: 4,
dryRun: false
})
$ mysqlsh -u kunit --port=3306 --js < dumpInstanceFile.js
MySQL Shell の機能として「APIコマンドライン統合(API Command Line Integration)」と呼ばれるものが準備されており、以下のような形でワンライナーで記述することができます。
$ mysqlsh [options] -- [shell_object]+ object_method [arguments]
APIコマンドライン統合を利用すると次のようにすべてコマンドラインで記述することができます。
$ mysqlsh -u kunit --port=3306 -- util dump-instance "/home/kunit/mysql-shell-test/dump-files/dump-instance" --threads=4 --dryRun=0
このようにワンライナーで MySQL Shell を使ったダンプ処理を行うことができます。
今回の環境
今回は以下のような環境を準備しました。
- WSL2 Ubuntu 上で 以下の2つのコンテナを docker-compose で起動
- MySQL 8.0.44 を Port 3306 で起動。こちらがダンプ元になります
- MySQL 8.0.44 を Port 3307 で起動。こちらがリストア先になります
- 上記の2つのMySQLに WSL2 Ubuntu 上の MySQL Shell から接続します
従来の mysqldump との比較なので、localstack を使った S3経由の速度は計測しません。
今回はベンチマークということで計測したPCのスペックも記載しておきます。
- Intel Core i7 13700F 2.10GHz
- RAM: 32GB
- Windows 11 Home
今回の対象DBについて
前回は少ない量での動作確認をしていましたが、今回は速度比較ということで以下のような形としました。
- データベースは以下の5つが存在
- test_db1
- test_db2
- test_db3
- test_db4
- test_db5
- それぞれのデータベースに5つテーブルが存在
- test_db?_tbl1 から test_db?_tbl5 という命名規則となっています
- それぞれのテーブルには10万コードを挿入済み
ダンプの速度検証
計測するコマンド
mysqldump は以下の引数で実行します。dump1.sql の数字の部分は実行ごとに変更して、毎回新規ファイルに出力します。
$ mysqldump --defaults-extra-file=conf/sql.cnf --port=3306 --all-databases > dump-files/dump1.sql
MySQL Shell ではダンプインスタンスユーティリティを利用します。出力先のディレクトリ dump-instance2-1 の数字部分は実行ごとに変更し、毎回新規ディレクトリに出力します。
また、 threads オプションは 2/4/8/12 の4パターンを試します。
util.dumpInstance('/home/kunit/mysql-shell-test/dump-files/dump-instance2-1', {
threads: 2,
dryRun: false
})
$ mysqlsh -u kunit --port=3306 --js < scripts/dumpInstance.js
両方ともコマンドの前に time をつけることにより実行時間を計測しました。
計測結果
計測結果は以下のようになりました。
- 2スレッドはmysqldumpとほぼ同等
- 4スレッドのmysqlshの段階で、mysqldumpよりも1.76倍速い
- 8スレッドにするとさらに速くなり 2.657倍に
- 12スレッドにすると更に速くなり 3.285倍に
| 実行方法 | threads | 1回目 | 2回目 | 3回目 | 平均 | 比較 |
|---|---|---|---|---|---|---|
| mysqldump | - | 8.126s | 7.705s | 9.235s | 8.355s | 1 |
| mysqlsh | 2 | 8.200s | 8.220s | 8.391s | 8.270s | 1.010 |
| mysqlsh | 4 | 4.995s | 4.496s | 4.752s | 4.748s | 1.760 |
| mysqlsh | 8 | 3.114s | 2.974s | 3.344s | 3.144s | 2.657 |
| mysqlsh | 12 | 2.563s | 2.471s | 2.595s | 2.543s | 3.285 |
今回、最終的に250万レコードに対する比較をしましたが、1/10の25万レコードくらいであれば、優位な差はでなかったので、対象レコード数が増えれば増えるほど効いてくる感がありました。実環境ではもっとレコード数があると思うので、差を実感できる可能性があります。
リストアの速度検証
次にリストアの速度検証を行います。リストアは mysqldump でダンプしたものを mysql コマンドでリストアするという一般的なパターンと mysqlsh との比較になります。
毎回、リストア先のデータベースは初期化して実行します。
$ mysql --defaults-extra-file=conf/sql.cnf --port=3307 < dump-files/dump1.sql
MySQL Shell ではダンプロードユーティリティを利用します。こちらも毎回リスト先のデータベースは初期化して実行します。
こちらも thread オプションは 1/2/4/8/12 の5パターンを試します。
util.loadDump('/home/kunit/mysql-shell-test/dump-files/dump-instance2-1', {
threads: 1,
analyzeTables: 'on',
dryRun: false
})
$ mysqlsh -u kunit --port=3307 --js < scripts/loadDump.js
計測結果
計測結果は以下のようになりました。
- mysql を使ったリストアに比べて、MySQL Shell のほうが全体的に時間がかかっている
- かろうじて thread:1 だけが速かった
- スレッド数が上がるほど遅くなる
上記のような結果となったが、タスクモニターでリソース状況を見る限り、SSDの負荷が高く、ディスクがボトルネックになっていた可能性が高いです。
実際、業務上でAWS環境をつかった確認をしたときには MySQL Shell のほうが圧倒的に速かったので今回の同一ディスクに書き込むという環境の問題だったのではないかと推測しています。Aurora MySQL等のwriteに強いものをつかえばスレッド数を増やすことにより速くすることができるのではないかと思っています。
ダンプ側はスレッドを増やすと速くなるが、ダンプ側のスレッド数はいい感じに調整をする必要がありそうです。
| 実行方法 | threads | 1回目 | 2回目 | 3回目 | 平均 | 比較 |
|---|---|---|---|---|---|---|
| mysql | - | 5m25.852s | 5m6.389s | 4m51.744s | 5m7.995s | 1 |
| mysqlsh | 1 | 4m40.037s | 4m32.943s | 4m38.860s | 4m37.280s | 1.110 |
| mysqlsh | 2 | 5m44.899s | 5m27.887s | 5m34.012s | 5m35.599s | 0.918 |
| mysqlsh | 4 | 6m14.220s | 6m25.385s | 6m10.343s | 6m16.649s | 0.840 |
| mysqlsh | 8 | 7m11.121s | 7m6.739s | 7m0.504s | 7m6.121s | 0.723 |
| mysqlsh | 12 | 7m16.219s | 7m19.571s | 7m50.764s | 7m28.851s | 0.686 |
(参考)コピーユーティリティの速度検証
参考までにMySQL Shellのコピーユーティリティをつかった結果を示します。速度の傾向としてはリストアと同様にスレッド数を増やせば増やすほど遅くなってしまいましたが、これはローカルのディスクIOが限界にきてしまったためと推測しています。
これもAurora MySQLのようなwriteに強いものに対して使えば、速度的な優位性は出るのではないかと期待しています。
| 実行方法 | threads | 1回目 | 2回目 | 3回目 | 平均 |
|---|---|---|---|---|---|
| mysqldump(ダンプ) | - | 8.126s | 7.705s | 9.235s | 8.355s |
| mysql(リストア) | - | 5m25.852s | 5m6.389s | 4m51.744s | 5m7.995s |
| mysqlsh(コピー) | 4 | 5m52.478s | 5m53.030s | 5m57.838s | 5m54.449s |
| mysqlsh(コピー) | 8 | 6m40.761s | 6m39.254s | 7m2.387s | 6m47.467s |
| mysqlsh(コピー) | 12 | 7m23.315s | 7m13.427s | 7m7.304s | 7m14.682s |
最後に
3回に渡って、MySQL Shell の説明をしてみましたが、いかがだったでしょうか。
今回のベンチマークでは、ダンプは速くなったがリストアが遅くなってしまったという結果になりましたが、これは今回準備した環境が良くなかったかなと思ってます。今回の結果をもって、MySQL Shellをつかったリストアが遅いという判断はしないでいただければと思います。(この結果を受けて3回目を没にするかを検討しましたが、ありのまま公開します)
前回の記事で説明しましたが、コピーユーティリティをつかった中間ファイルを使わないコピーはかなり魅力的ですし、S3に直接出力できるというのもメリットだと思いますので、今後も MySQL Shell の利用を検討していこうと思ってます。
株式会社カオナビでは一緒に働く仲間を募集しています。カジュアル面談も行っていますので、ご興味がある方は気軽にお声がけください。
