MySQL 5.7の現在の状態
MySQL 5.7はスケーラビリティーの観点から理想的ではありません。以下の図は、特定の設定下でMySQL 5.7.39のTPC-Cのスループと并发性の関係を示しています。これには、トランザクションの孤立レベルをRead Committedに設定し、innodb_spin_wait_delay
パラメータを調整してスループのデgradationを軽減するものも含まれます。
図1: BenchmarkSQLテスト中のMySQL 5.7.39のスケーラビリティー問題
図から、スケーラビリティー問題がMySQLのスループの増加を大幅に制限することが明らかです。たとえば、100の并发性後、スループは開始して下降します。
前述の性能の崩壊問題を解決するために、Perconaのスレッドプールが採用されました。Perconaスレッドプールを設定後のTPC-Cのスループと并发性の関係を示す図が以下の通りです。
図2: MySQL 5.7.39のスケーラビリティー問題を軽減するPerconaスレッドプール
スレッドプールはいくらかのオーバーヘッドを導入し、最高性能が低下しましたが、高并发性のための性能の崩壊問題を軽減しています。
MySQL 8.0の現在の状態
MySQL 8.0にはスケーラビリティーに取り組む努力があることを見てみましょう。
重書きログの最適化
最初の主要な改善は重書きログの最適化です[3]。
commit 6be2fa0bdbbadc52cc8478b52b69db02b0eaff40
Author: Paweł Olchawa <[email protected]>
Date: Wed Feb 14 09:33:42 2018 +0100
WL#10310 Redo log optimization: dedicated threads and concurrent log buffer.
0. Log buffer became a ring buffer, data inside is no longer shifted.
1. User threads are able to write concurrently to log buffer.
2. Relaxed order of dirty pages in flush lists - no need to synchronize
the order in which dirty pages are added to flush lists.
3. Concurrent MTR commits can interleave on different stages of commits.
4. Introduced dedicated log threads which keep writing log buffer:
* log_writer: writes log buffer to system buffers,
* log_flusher: flushes system buffers to disk.
As soon as they finished writing (flushing) and there is new data to
write (flush), they start next write (flush).
5. User threads no longer write / flush log buffer to disk, they only
wait by spinning or on event for notification. They do not have to
compete for the responsibility of writing / flushing.
6. Introduced a ring buffer of events (one per log-block) which are used
by user threads to wait for written/flushed redo log to avoid:
* contention on single event
* false wake-ups of all waiting threads whenever some write/flush
has finished (we can wake-up only those waiting in related blocks)
7. Introduced dedicated notifier threads not to delay next writes/fsyncs:
* log_write_notifier: notifies user threads about written redo,
* log_flush_notifier: notifies user threads about flushed redo.
8. Master thread no longer has to flush log buffer.
...
30. Mysql test runner received a new feature (thanks to Marcin):
--exec_in_background.
Review: RB#15134
Reviewers:
- Marcin Babij <[email protected]>,
- Debarun Banerjee <[email protected]>.
Performance tests:
- Dimitri Kravtchuk <[email protected]>,
- Daniel Blanchard <[email protected]>,
- Amrendra Kumar <[email protected]>.
QA and MTR tests:
- Vinay Fisrekar <[email protected]>.
优化前後で concurrent レベルの異なるTPC-Cのスループとの比較を行ったテストがあり、以下の図に特定の詳細が示されています。
図3: 重試ログ最適化の影響を調べる(異なる並列性レベルで)
図に示される結果は、低い並列性レベルでの吞吐量を大幅に改善することを示しています。
Latch Shardingを使用してLock-Sysを最適化する
第2の主要な改善点は、Lock-Sysの最適化です。[5]
commit 1d259b87a63defa814e19a7534380cb43ee23c48
Author: Jakub Łopuszański <[email protected]>
Date: Wed Feb 5 14:12:22 2020 +0100
WL#10314 - InnoDB: Lock-sys optimization: sharded lock_sys mutex
The Lock-sys orchestrates access to tables and rows. Each table, and each row,
can be thought of as a resource, and a transaction may request access right for
a resource. As two transactions operating on a single resource can lead to
problems if the two operations conflict with each other, Lock-sys remembers
lists of already GRANTED lock requests and checks new requests for conflicts in
which case they have to start WAITING for their turn.
Lock-sys stores both GRANTED and WAITING lock requests in lists known as queues.
To allow concurrent operations on these queues, we need a mechanism to latch
these queues in safe and quick fashion.
In the past a single latch protected access to all of these queues.
This scaled poorly, and the managment of queues become a bottleneck.
In this WL, we introduce a more granular approach to latching.
Reviewed-by: Pawel Olchawa <[email protected]>
Reviewed-by: Debarun Banerjee <[email protected]>
RB:23836
Lock-Sysを最適化前後のプログラムに基づいて、BenchmarkSQLを使用して、TPC-Cの吞吐量を並列性によって比較しました。以下の図に示される具体的结果があります。
図4: 異なる並列性レベルでのlock-sys最適化の影響
図から、lock-sysの最適化が高い並列性条件下で吞吐量を大幅に改善することがわかりますが、低い並列性条件では、衝突が少ないため、影響が小さいです。
trx-sysに対するLatch Sharding
第3の主要な改善点は、trx-sysに対するLatch Shardingです。
commit bc95476c0156070fd5cedcfd354fa68ce3c95bdb
Author: Paweł Olchawa <[email protected]>
Date: Tue May 25 18:12:20 2021 +0200
BUG#32832196 SINGLE RW_TRX_SET LEADS TO CONTENTION ON TRX_SYS MUTEX
1. Introduced shards, each with rw_trx_set and dedicated mutex.
2. Extracted modifications to rw_trx_set outside its original critical sections
(removal had to be extracted outside trx_erase_lists).
3. Eliminated allocation on heap inside TrxUndoRsegs.
4. [BUG-FIX] The trx->state and trx->start_time became converted to std::atomic<>
fields to avoid risk of torn reads on egzotic platforms.
5. Added assertions which ensure that thread operating on transaction has rights
to do so (to show there is no possible race condition).
RB: 26314
Reviewed-by: Jakub Łopuszański [email protected]
これらの最適化前後に基づいて、BenchmarkSQLを使用して、並列性によってTPC-Cの吞吐量を比較しました。以下の図に示される具体的结果があります。
図5: 異なる並列性レベルでのtrx-sysのLatch Shardingの影響
図から、この改善点がTPC-Cの吞吐量を显著に向上させ、200の並列性でピークを達することがわかります。注意すべきことですが、300の並列性では、影響が衰えますが、主にMVCC ReadViewに関連するtrx-sysサブシステムのスケール性问题によるものです。
MySQL 8.0を细かく調整する
残りの改善点は、私たちの独自の改善です。
MVCC ReadViewの強化
MVCC ReadView データ構造の最初の主要な改善は、MVCC ReadViewの性能向上に関する調査を行ったことである[1]。
以下の図は、MVCC ReadViewデータ構造の変更後の效果を評価したTPC-Cのスループットの比較である。
図6: NUMA環境で新しいハイブリッドデータ構造を采用した前後の性能比較
この図から、この変換は主にスケーラビリティを最適化し、MySQLがNUMA環境でのピークスループットを向上させたことが明らかです。
二重锁定問題の解決
私たちが行った第2の主要な改善は、「二重锁定」問題の解決です。ここで「二重锁定」は、view_open
およびview_close
両方でグローバルなtrx-sysロッチを必要としていることを指します[1]。
MVCC ReadViewを最適化した版を使用し、変更の前後のTPC-Cのスループットを比較しましょう。以下の図に詳細が示されています。
図7: 二重锁定の瓶颈を除去した後の性能改善
この図から、変更は高コンカーrency状況下でのスケーラビリティを大幅に改善したことが明らかです。
トランザクションの制限機構
最後の改善は、极端なコンカーrencyによる性能観念を防ぐためのトランザクション制限機構の実装です[1] [2] [4]。
以下の図は、トランザクションのスローイングを実装した後のTPC-Cのスケーラビリティーテストを示しています。このテストは、NUMA BIOSを無効にし、トランザクションシステムに512以下のユーザースレッドの进入を制限するシナリオで行われました。
図8: トランザクションスローイング機構を実装したBenchmarkSQLの最大TPC-Cスループと
図から、トランザクションスローイング機構の実装がMySQLのスケーラビリティを显著に改善することが明らかです。
概要
全体的に、MySQLはBenchmarkSQL TPC-Cテストの低コンフリクトシナリオで数千の同時接続を维持してパフォーマンスを崩れないでいくことが完全に可能です。
参照
- Bin Wang (2024). ソフトウェアエンジニアリングで問題解決の術: MySQLをより良くする方法.
- 新しいMySQLスレッドプール
- Paweł Olchawa. 2018. MySQL 8.0: 新しいロック無し、スケーラブルなWAL設計. MySQLブログアーカイブ.
- Xiangyao Yu. 千核での并发的控制の評価. マサチューセッツ工科大学の博士論文, 2015.
- MySQL 8.0 リファレンスマニュアル
Source:
https://dzone.com/articles/mysql-scalability-improvement-for-benchmarksql