Comment améliorer la scalabilité de MySQL pour les tests TPC-C de BenchmarkSQL ?

État actuel de MySQL 5.7

MySQL 5.7 n’est pas idéal en matière de scalaiblité. Le graphique ci-après illustre la relation entre la performance en TPC-C et la concurrence dans MySQL 5.7.39 sous une configuration spécifique. Cela inclut le réglage du niveau d’isolation des transactions à « Read Committed » et l’ajustement du paramètre innodb_spin_wait_delay pour atténuer la dégradation de la performance.

Figure 1 : Problèmes de scalaiblité dans MySQL 5.7.39 lors des tests BenchmarkSQL

Ainsi, il est évident que les problèmes de scalaiblité limitent significativement l’augmentation de la performance de MySQL. Par exemple, après 100 concurrences, la performance commence à décliner.

Pour remédier à ce problème de chute de performance, le pool de threads de Percona a été employé. Le graphique ci-après illustre la relation entre la performance en TPC-C et la concurrence après configuration du pool de threads Percona.

Figure 2 : Le pool de threads de Percona atténue les problèmes de scalaiblité dans MySQL 5.7.39

Bien que le pool de threads ajoute un certain surcoût et que la performance maximale soit descendue, il a atténué le problème de chute de performance à haute concurrence.

État actuel de MySQL 8.0

Maintenant, voyons les efforts que MySQL 8.0 a mis en œuvre en matière de scalaiblité.

Optimisation du journal de redo

La première amélioration majeure est l’optimisation du journal de redo [3].

C++

 

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]>.

Un test comparant la performance en TPC-C avec différents niveaux de concurrence avant et après l’optimisation a été effectué. Les détails spécifiques sont présentés dans le graphique ci-après :

Figure 3 : Impact de l’optimisation du journal de rédo à différents niveaux de concurrence

Les résultats figurant dans la figure montrent une amélioration significative de la throughput à bas niveaux de concurrence.

Optimisation de Lock-Sys par le biais de la segmentation des latches

La deuxième amélioration majeure est l’optimisation de Lock-Sys [5].

C++

 

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

En utilisant BenchmarkSQL pour comparer la throughput TPC-C en fonction de la concurrence avant et après l’optimisation avec Lock-Sys, les résultats précis sont les suivants, comme illustré dans la figure suivante :

Figure 4 : Impact de l’optimisation de Lock-Sys à différents niveaux de concurrence

Apartir de cette figure, on peut observer que l’optimisation de Lock-Sys améliore significativement la throughput sous des conditions de haute concurrence, tandis qu’elle est moins marquée à bas niveau de concurrence en raison de moins de conflits.

Segmentation des latches pour trx-sys

La troisième amélioration majeure concerne la segmentation des latches pour trx-sys.

C++

 

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]

En se basant sur ces optimisations avant et après, en utilisant BenchmarkSQL pour comparer la throughput TPC-C en fonction de la concurrence, les résultats spécifiques sont les suivants, comme illustrés dans la figure suivante :

Figure 5 : Impact de la segmentation des latches dans trx-sys à différents niveaux de concurrence

Apartir de cette figure, on peut observer que cette amélioration augmente significativement la throughput TPC-C, atteignant son pic à 200 concurrences. Il convient de noter que l’impact diminue à 300 concurrences, principalement en raison de problèmes de scalabilité persistants dans le sous-système trx-sys liés à la MVCC ReadView.

Raffinement de MySQL 8.0

Les améliorations restantes sont nos propres améliorations indépendantes.

Amélioration de la structure de données MVCC ReadView

La première amélioration majeure est l’amélioration de la structure de données MVCC ReadView [1].

Des tests de comparaison de performance ont été effectués pour évaluer l’efficacité de l’optimisation de la MVCC ReadView. Le graphique ci-dessous montre une comparaison du throughput TPC-C avec différents niveaux de concurrence, avant et après la modification de la structure de données MVCC ReadView.

Figure 6 : Comparaison de performance avant et après l’adoption de la nouvelle structure hybride de données dans NUMA

Apartir du graphique, il est évident que cette transformation optimise principalement la scalabilité et améliore le throughput de MySQL dans les environnements NUMA.

Éviter les problèmes de double verrou

La deuxième amélioration importante que nous avons réalisée est l’addressage du problème du double verrou, où « double verrou » se réfère à la nécessité du verrou global trx-sys pour les fonctions view_open et view_close [1].

En utilisant la version optimisée MVCC ReadView, comparez le throughput TPC-C avant et après les modifications. Les détails sont montrés dans le graphique suivant :

Figure 7 : Amélioration de la performance après l’élimination du verrouillage double

Apartir du graphique, il est évident que les modifications ont amélioré significativement la scalabilité sous des conditions de haute concurrence.

Mécanisme de limitation de transactions

La dernière amélioration est l’implémentation d’un mécanisme de limitation de transactions pour se protéger contre la chute de performance sous une concurrence extrême [1] [2] [4].

Le graphique ci-après représente la tension de stress de scalabilité TPC-C effectuée après l’implémentation du freinage des transactions. Le test a été réalisé dans un scénario avec le NUMA BIOS désactivé, limitant l’entrée de jusqu’à 512 fils d’utilisateurs dans le système de transactions.

Figure 8 : Throughput maximum de TPC-C dans BenchmarkSQL avec les mécanismes de freinage des transactions

Apartir du graphique, il est évident que l’implémentation de mécanismes de freinage des transactions améliore significativement la scalabilité de MySQL.

Résumé

D’une manière générale, il est complètement réalisable que MySQL maintienne des performances stables sans collapser à des dizaines de milliers de connexions concurrentes dans des scénarios de tests TPC-C de BenchmarkSQL avec peu de conflits.

Références

  1. Bin Wang (2024). L’Art de la Résolution des Problèmes en Informatique :Comment améliorer MySQL.
  2. Le Nouveau Piscine de Threads MySQL
  3. Paweł Olchawa. 2018. MySQL 8.0 : Nouvelle conception de WAL sans verrou, scalable. Archives du Blog MySQL.
  4. Xiangyao Yu. Une évaluation de la gestion de la concurrence avec mille coeurs. Thèse de doctorat, Massachusetts Institute of Technology, 2015.
  5. Manuel de référence de MySQL 8.0

Source:
https://dzone.com/articles/mysql-scalability-improvement-for-benchmarksql