MySQL RP (Restore Performance) として、成果をgithubで公開しながら(利用はMySQL Community Editionと同様のGPLライセンス) 個人でMySQLの性能回復を研究しています。
これまでは、第1段階として、OLTP処理で競合しそうな要素を狙ったSQLでのCPU性能スケールテストを行って、MySQL-8.0で問題のある箇所を修正してきました。RP008で目立った問題は解決したと思われるので、
第2段階として、PGOビルドなしでもシングルスレッド性能で、5.7のノーマルビルド(公平のため -DDISABLE_PSI_MEMORY=ON オプション付きビルド)を超えることを目指します。そうすれば限定句が少し取れて「世界で一番CPU性能が高いMySQL」となります。
(※MySQL-5.7のPSI_MEMORYのコードはperformance_schema=OFFでも非常に重く、5.7の性能を不当に下げています。)
< まず、お願い >
現状の比較結果を簡単に紹介しますが、その前にこの活動の持続のためのご協力のお願いです。
一つの手段は、Patreonのサポートサイトの有料会員になっていただくことです。今回の結果のもっと詳しい説明もありますし、活動の中間報告なども随時しています。RPxxxの各変更も、どの様に分析したかも説明してます。
もう一つの手段は、、、
「よくある事情」により、この活動は求職活動の一環と言う側面も暫くあるので、この活動(とういか生活…)の持続性のために、採用選考・採用面接などの実績もあると助かります。このRP開発活動との折り合いが良ければ実際副業にしますので。 buildup.db@gmail.com まで一報をお願いします。
あとは、結果が出始めたので、この活動について機を見て話題に上げて宣伝していただけると有り難いです。
よろしくお願いいたします。
< 現状の比較結果 >
では現状(第1段階完了)のベンチマーク結果を簡単に。
まずTPC-Cですが、ほんの少ししかベースの8.0と差がないので割愛します。
TPC-CはMySQLのOLTP性能を測る指標としては今はもう緩すぎるようです。個別の要素を調べなければなりません。
(※この20年弱、TPC-C同等処理のベンチマークをOLTP性能の指標にして性能改善を進めてきましたが、既に8.0では十分なスケールが得られているため、より厳しい指標でなければ、もう緩いTPC-Cでは性能が下がっても分からないようです。そのせいで、遅いコードを平気で書く人達が気づかなかった。これは我々開発に関わった人達のミスです。反省しています…)
というわけで、例によって Dimitriさんの BMK-kit の中から各個別要素に一番負荷をかけるSQLを選んでテストしていたわけです。
今までと同様 "Xeon(R) CPU E5-2699 v4 (22cores;44threads)" で 2ノードNUMA、
単純化してできるだけ純粋なCPUスケールを見るために、ストレージは ramfs、
REDOログの書き込み待ち設定 innodb_flush_log_at_trx_commit=0 で io wait を極力排除しています。
(まず、CPU性能を優先してるのは、誤魔化しようがないからです。IOは多少 Durability を犠牲にすれば可能なので後回し。)
比べたのは、これらのバイナリ、
- MySQL 8.4 Community Edition (mysql-8.4.5-linux-glibc2.28-x86_64.tar)
- MySQL 9.3 Community Edition (mysql-9.3.0-linux-glibc2.28-x86_64.tar)
- Percona Server 8.4 (Percona-Server-8.4.5-5-Linux.x86_64.glibc2.31.tar.gz)
- MariaDB 11 (mariadb-11.8.2-linux-systemd-x86_64.tar.gz)
あとは、私がノーマルビルド(但し -DDISABLE_PSI_MEMORY=ON)した、"MySQL-5.7.44"、"MySQL-8.0.42"、"MySQL RP-8.0[RP008]"。そして、MySQL RP-8.0[RP008] は PGOビルドも比較しています。
1.主キーランダム検索性能スケール
セカンダリ索引の範囲スキャンで、索引に無い値を取得するクエリは、1クエリで多数の主キーランダム検索を発生することができます。クライアント通信のラグなどを抑えて、より純粋な性能です。
BMK-kit でいうと、sb_exec/sb11-OLTP_RO_10M_8tab-uniform-s_ranges1-Rsize100-SecIDX-notrx-socket.sh 相当。
2.lock_sysの性能スケール
上記と同様のクエリに "LOCK IN SHARE MODE" 句を足せば、競合しないロック処理のみで lock_sys に負荷をかけられます。
3.log_sysの性能スケール
REDO log バッファへの書き込みは mini-transaction 単位で、それは1レコード毎です。
1クエリで多数のレコードを更新すれば、多数のmini-transactionを発生させて、
log_sys に負荷をかけられます。
BMK-kit でいうと、sb_exec/sb11-OLTP_RW_10M_8tab-uniform-upd_noidx1-upd_range100-notrx-socket.sh 相当。
4.purge_threadsの性能スケール
参照整合性取る必要のなくなった古いUNDOレコードを消すのがバックグラウンドのPurge処理です。innodb_max_purge_lag_delay を使えば、フォアグラウンドの処理がPurgeを置いていかなくなり、Purgeの処理性能が現れます。1クエリで多数のセカンダリ索引キー値を更新すれば、主キーレコードの更新やセカンダリキーレコードの削除・追加などで、大量のUNDOレコードを生成することになりPurge処理が増やせます。このテストは、purge_threads を変更して平衡するスループットを調べます。
BMK-kit でいうと、sb_exec/sb11-OLTP_RW_10M_8tab-uniform-upd_idx1-upd_range100-notrx-socket.sh 相当の最後の値です。
2.と3.は、1.を直したことで性能が高くなっているようです。
というわけで、
1.と4.の問題は、他のMySQLコードでは何も直していないようですので、
現状、世界で一番と言っても良いでしょう。:)
しかし低並列では、RP008ノーマルビルドは5.7ノーマルビルドの真の性能(-DDISABLE_PSI_MEMORY=ON)にまだ負けるので、それが次の課題です。
(PGOビルドはバイナリの再現性が少し良くないので、維持管理上不便なので。不便だとバグを取りこぼしたりビルドによって挙動が違う可能性があったり少し不安要素ですので。処理によっては遅くなるものもあるかも知れない。安全のためにはコード側でコントロールしたいところ。)
うまく行けば、PGOビルドよりも速くなるかも。
そして、ここからがこの活動の本番なのです。何か良い方法をこれから考えます。時間は掛かるかも知れませんが、応援してください。
第2段階のその後はIO性能とか何か劣化を取りこぼしてる処理など(有料会員優先で)募集したりします。
では、ご期待ください。