Dans la première partie de ce blog, nous avons fourni un aperçu de la nouvelle fonctionnalité de réplication en continu dans MySQL Galera Cluster. Dans ce blog, nous allons vous montrer comment l'activer et jeter un œil aux résultats.
Activer la réplication en continu
Il est fortement recommandé d'activer la réplication en continu au niveau de la session pour les transactions spécifiques qui interagissent avec votre application/client.
Comme indiqué dans le blog précédent, Galera enregistre ses jeux d'écriture dans la table wsrep_streaming_log de la base de données MySQL. Cela a le potentiel de créer un goulot d'étranglement des performances, en particulier lorsqu'une restauration est nécessaire. Cela ne signifie pas que vous ne pouvez pas utiliser Streaming Replication, cela signifie simplement que vous devez concevoir efficacement votre client d'application lors de l'utilisation de Streaming Replication afin d'obtenir de meilleures performances. Néanmoins, il est préférable d'avoir la réplication en continu pour traiter et réduire les transactions volumineuses.
L'activation de la réplication en continu nécessite que vous définissiez l'unité de réplication et le nombre d'unités à utiliser pour former les fragments de transaction. Deux paramètres contrôlent ces variables :wsrep_trx_fragment_unit et wsrep_trx_fragment_size.
Vous trouverez ci-dessous un exemple de configuration de ces deux paramètres :
SET SESSION wsrep_trx_fragment_unit='statements';
SET SESSION wsrep_trx_fragment_size=3;
Dans cet exemple, le fragment est défini sur trois instructions. Pour chaque trois déclarations d'une transaction, le nœud générera, répliquera et certifiera un fragment.
Vous pouvez choisir entre quelques unités de réplication lors de la formation de fragments :
- octets - Cela définit la taille du fragment en octets.
- lignes - Cela définit la taille du fragment comme le nombre de lignes que le fragment met à jour.
- déclarations - Cela définit la taille du fragment comme le nombre d'instructions dans un fragment.
Choisissez l'unité de réplication et la taille de fragment qui conviennent le mieux à l'opération spécifique que vous souhaitez exécuter.
Réplication de flux en action
Comme discuté dans notre autre blog sur la gestion des transactions volumineuses dans Mariadb 10.4, nous avons effectué et testé le fonctionnement de la réplication en continu lorsqu'elle était activée sur la base de ces critères...
- Base de référence, définissez global wsrep_trx_fragment_size=0 ;
- set global wsrep_trx_fragment_unit='rows' ; définir global wsrep_trx_fragment_size=1 ;
- set global wsrep_trx_fragment_unit='statements' ; définir global wsrep_trx_fragment_size=1 ;
- set global wsrep_trx_fragment_unit='statements' ; définir global wsrep_trx_fragment_size=5 ;
Et les résultats sont
Transactions: 82.91 per sec., queries: 1658.27 per sec. (100%)
Transactions: 54.72 per sec., queries: 1094.43 per sec. (66%)
Transactions: 54.76 per sec., queries: 1095.18 per sec. (66%)
Transactions: 70.93 per sec., queries: 1418.55 per sec. (86%)
Pour cet exemple, nous utilisons Percona XtraDB Cluster 8.0.15 directement depuis leur branche de test en utilisant Percona-XtraDB-Cluster_8.0.15.5-27dev.4.2_Linux.x86_64.ssl102.tar.gz construire.
Nous avons ensuite essayé un cluster Galera à 3 nœuds avec les informations sur les hôtes ci-dessous :
testnode11 = 192.168.10.110
testnode12 = 192.168.10.120
testnode13 = 192.168.10.130
Nous avons pré-rempli une table à partir de ma base de données sysbench et avons essayé de supprimer de très grandes lignes.
[email protected][sbtest]#> select count(*) from sbtest1;
+----------+
| count(*) |
+----------+
| 12608218 |
+----------+
1 row in set (25.55 sec)
Au début, s'exécutant sans Streaming Replication,
[email protected][sbtest]#> select @@wsrep_trx_fragment_unit, @@wsrep_trx_fragment_size, @@innodb_lock_wait_timeout;
+---------------------------+---------------------------+----------------------------+
| @@wsrep_trx_fragment_unit | @@wsrep_trx_fragment_size | @@innodb_lock_wait_timeout |
+---------------------------+---------------------------+----------------------------+
| bytes | 0 | 50000 |
+---------------------------+---------------------------+----------------------------+
1 row in set (0.00 sec)
Puis exécutez,
[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;
Cependant, nous avons fini par obtenir une restauration...
---TRANSACTION 648910, ACTIVE 573 sec rollback
mysql tables in use 1, locked 1
ROLLING BACK 164858 lock struct(s), heap size 18637008, 12199395 row lock(s), undo log entries 11961589
MySQL thread id 183, OS thread handle 140041167468288, query id 79286 localhost 127.0.0.1 root wsrep: replicating and certifying write set(-1)
delete from sbtest1 where id >= 2000000
Utiliser les tableaux de bord ClusterControl pour recueillir une vue d'ensemble de toute indication de contrôle de flux, puisque la transaction s'exécute uniquement sur le nœud maître (rédacteur actif) jusqu'au moment de la validation, il n'y a aucune indication d'activité pour le contrôle de flux :
Au cas où vous vous poseriez la question, la version actuelle de ClusterControl ne fonctionne pas encore avoir un support direct pour PXC 8.0 avec Galera Cluster 4 (car il est encore expérimental). Vous pouvez cependant essayer de l'importer... mais il nécessite des ajustements mineurs pour que vos tableaux de bord fonctionnent correctement.
Retour au processus de requête. Il a échoué car il a été annulé !
[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;
ERROR 1180 (HY000): Got error 5 - 'Transaction size exceed set threshold' during COMMIT
quel que soit wsrep_max_ws_rows ou wsrep_max_ws_size,
[email protected][sbtest]#> select @@global.wsrep_max_ws_rows, @@global.wsrep_max_ws_size/(1024*1024*1024);
+----------------------------+---------------------------------------------+
| @@global.wsrep_max_ws_rows | @@global.wsrep_max_ws_size/(1024*1024*1024) |
+----------------------------+---------------------------------------------+
| 0 | 2.0000 |
+----------------------------+---------------------------------------------+
1 row in set (0.00 sec)
Il a finalement atteint le seuil.
Pendant ce temps, la table système mysql.wsrep_streaming_log est vide, ce qui indique que la réplication en continu ne se produit pas ou n'est pas activée,
[email protected][sbtest]#> select count(*) from mysql.wsrep_streaming_log;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.01 sec)
[email protected][sbtest]#> select count(*) from mysql.wsrep_streaming_log;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)
et cela est vérifié sur les 2 autres nœuds (testnode12 et testnode13).
Maintenant, essayons de l'activer avec Streaming Replication,
[email protected][sbtest]#> select @@wsrep_trx_fragment_unit, @@wsrep_trx_fragment_size, @@innodb_lock_wait_timeout;
+---------------------------+---------------------------+----------------------------+
| @@wsrep_trx_fragment_unit | @@wsrep_trx_fragment_size | @@innodb_lock_wait_timeout |
+---------------------------+---------------------------+----------------------------+
| bytes | 0 | 50000 |
+---------------------------+---------------------------+----------------------------+
1 row in set (0.00 sec)
[email protected][sbtest]#> set wsrep_trx_fragment_unit='rows'; set wsrep_trx_fragment_size=100;
Query OK, 0 rows affected (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
[email protected][sbtest]#> select @@wsrep_trx_fragment_unit, @@wsrep_trx_fragment_size, @@innodb_lock_wait_timeout;
+---------------------------+---------------------------+----------------------------+
| @@wsrep_trx_fragment_unit | @@wsrep_trx_fragment_size | @@innodb_lock_wait_timeout |
+---------------------------+---------------------------+----------------------------+
| rows | 100 | 50000 |
+---------------------------+---------------------------+----------------------------+
1 row in set (0.00 sec)
À quoi s'attendre lorsque Galera Cluster Streaming Replication est activé ?
Lorsque la requête a été effectuée dans testnode11,
[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;
Ce qui se passe, c'est qu'il fragmente la transaction pièce par pièce en fonction de la valeur définie de la variable wsrep_trx_fragment_size. Vérifions ceci dans les autres nœuds :
Hôte testnode12
[email protected][sbtest]#> pager sed -n '/TRANSACTIONS/,/FILE I\/O/p'; show engine innodb status\G nopager; show global status like 'wsrep%flow%'; select count(*) from mysql.wsrep_streaming_log;
PAGER set to 'sed -n '/TRANSACTIONS/,/FILE I\/O/p''
TRANSACTIONS
------------
Trx id counter 567148
Purge done for trx's n:o < 566636 undo n:o < 0 state: running but idle
History list length 44
LIST OF TRANSACTIONS FOR EACH SESSION:
..
...
---TRANSACTION 421740651985200, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 553661, ACTIVE 190 sec
18393 lock struct(s), heap size 2089168, 1342600 row lock(s), undo log entries 1342600
MySQL thread id 898, OS thread handle 140266050008832, query id 216824 wsrep: applied write set (-1)
--------
FILE I/O
1 row in set (0.08 sec)
PAGER set to stdout
+----------------------------------+--------------+
| Variable_name | Value |
+----------------------------------+--------------+
| wsrep_flow_control_paused_ns | 211197844753 |
| wsrep_flow_control_paused | 0.133786 |
| wsrep_flow_control_sent | 633 |
| wsrep_flow_control_recv | 878 |
| wsrep_flow_control_interval | [ 173, 173 ] |
| wsrep_flow_control_interval_low | 173 |
| wsrep_flow_control_interval_high | 173 |
| wsrep_flow_control_status | OFF |
+----------------------------------+--------------+
8 rows in set (0.00 sec)
+----------+
| count(*) |
+----------+
| 13429 |
+----------+
1 row in set (0.04 sec)
Hôte testnode13
[email protected][sbtest]#> pager sed -n '/TRANSACTIONS/,/FILE I\/O/p'; show engine innodb status\G nopager; show global status like 'wsrep%flow%'; select count(*) from mysql.wsrep_streaming_log;
PAGER set to 'sed -n '/TRANSACTIONS/,/FILE I\/O/p''
TRANSACTIONS
------------
Trx id counter 568523
Purge done for trx's n:o < 567824 undo n:o < 0 state: running but idle
History list length 23
LIST OF TRANSACTIONS FOR EACH SESSION:
..
...
---TRANSACTION 552701, ACTIVE 216 sec
21587 lock struct(s), heap size 2449616, 1575700 row lock(s), undo log entries 1575700
MySQL thread id 936, OS thread handle 140188019226368, query id 600980 wsrep: applied write set (-1)
--------
FILE I/O
1 row in set (0.28 sec)
PAGER set to stdout
+----------------------------------+--------------+
| Variable_name | Value |
+----------------------------------+--------------+
| wsrep_flow_control_paused_ns | 210755642443 |
| wsrep_flow_control_paused | 0.0231273 |
| wsrep_flow_control_sent | 1653 |
| wsrep_flow_control_recv | 3857 |
| wsrep_flow_control_interval | [ 173, 173 ] |
| wsrep_flow_control_interval_low | 173 |
| wsrep_flow_control_interval_high | 173 |
| wsrep_flow_control_status | OFF |
+----------------------------------+--------------+
8 rows in set (0.01 sec)
+----------+
| count(*) |
+----------+
| 15758 |
+----------+
1 row in set (0.03 sec)
Remarquablement, le contrôle de flux vient de démarrer !
Et les files d'attente WSREP envoyées/reçues ont également démarré :
Hôte testnode12 (192.168.10.120) Hôte testnode13 (192.168.10.130)Développons maintenant davantage le résultat depuis la table mysql.wsrep_streaming_log,
[email protected][sbtest]#> pager sed -n '/TRANSACTIONS/,/FILE I\/O/p'|tail -8; show engine innodb status\G nopager;
PAGER set to 'sed -n '/TRANSACTIONS/,/FILE I\/O/p'|tail -8'
MySQL thread id 134822, OS thread handle 140041167468288, query id 0 System lock
---TRANSACTION 649008, ACTIVE 481 sec
mysql tables in use 1, locked 1
53104 lock struct(s), heap size 6004944, 3929602 row lock(s), undo log entries 3876500
MySQL thread id 183, OS thread handle 140041167468288, query id 105367 localhost 127.0.0.1 root updating
delete from sbtest1 where id >= 2000000
--------
FILE I/O
1 row in set (0.01 sec)
puis en prenant le résultat de,
[email protected][sbtest]#> select count(*) from mysql.wsrep_streaming_log;
+----------+
| count(*) |
+----------+
| 38899 |
+----------+
1 row in set (0.40 sec)
Il indique combien de fragments ont été répliqués à l'aide de Streaming Replication. Maintenant, faisons quelques calculs de base :
[email protected][sbtest]#> select 3876500/38899.0;
+-----------------+
| 3876500/38899.0 |
+-----------------+
| 99.6555 |
+-----------------+
1 row in set (0.03 sec)
Je prends les entrées du journal d'annulation du résultat SHOW ENGINE INNODB STATUS\G, puis je divise le nombre total d'enregistrements mysql.wsrep_streaming_log. Comme je l'ai défini précédemment, j'ai défini wsrep_trx_fragment_size=100. Le résultat vous montrera combien de journaux répliqués totaux sont actuellement traités par Galera.
Il est important de prendre note de ce que Streaming Replication essaie d'accomplir... "le nœud divise la transaction en fragments, puis les certifie et les réplique sur les esclaves pendant que la transaction est toujours en cours progression. Une fois certifié, le fragment ne peut plus être interrompu par des transactions en conflit."
Les fragments sont considérés comme des transactions, qui ont été transmises aux nœuds restants du cluster, certifiant la transaction fragmentée, puis appliquant les ensembles d'écriture. Cela signifie qu'une fois que votre transaction importante a été certifiée ou priorisée, toutes les connexions entrantes susceptibles d'avoir un blocage devront attendre la fin des transactions.
Maintenant, le verdict de la suppression d'une immense table ?
[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;
Query OK, 12034538 rows affected (30 min 36.96 sec)
Il se termine avec succès sans aucun échec !
À quoi cela ressemble-t-il dans les autres nœuds ? Dans testnode12,
[email protected][sbtest]#> pager sed -n '/TRANSACTIONS/,/FILE I\/O/p'|tail -8; show engine innodb status\G nopager; show global status like 'wsrep%flow%'; select count(*) from mysql.wsrep_streaming_log;
PAGER set to 'sed -n '/TRANSACTIONS/,/FILE I\/O/p'|tail -8'
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 421740651985200, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 553661, ACTIVE (PREPARED) 2050 sec
165631 lock struct(s), heap size 18735312, 12154883 row lock(s), undo log entries 12154883
MySQL thread id 898, OS thread handle 140266050008832, query id 341835 wsrep: preparing to commit write set(215510)
--------
FILE I/O
1 row in set (0.46 sec)
PAGER set to stdout
+----------------------------------+--------------+
| Variable_name | Value |
+----------------------------------+--------------+
| wsrep_flow_control_paused_ns | 290832524304 |
| wsrep_flow_control_paused | 0 |
| wsrep_flow_control_sent | 0 |
| wsrep_flow_control_recv | 0 |
| wsrep_flow_control_interval | [ 173, 173 ] |
| wsrep_flow_control_interval_low | 173 |
| wsrep_flow_control_interval_high | 173 |
| wsrep_flow_control_status | OFF |
+----------------------------------+--------------+
8 rows in set (0.53 sec)
+----------+
| count(*) |
+----------+
| 120345 |
+----------+
1 row in set (0.88 sec)
Il s'arrête à un total de 120345 fragments, et si nous refaites le calcul sur les dernières entrées de journal d'annulation capturées (les journaux d'annulation sont également les mêmes depuis le maître),
[email protected][sbtest]#> select 12154883/120345.0; +-------------------+
| 12154883/120345.0 |
+-------------------+
| 101.0003 |
+-------------------+
1 row in set (0.00 sec)
Nous avons donc eu un total de 120345 transactions fragmentées pour supprimer 12034538 lignes.
Une fois que vous avez fini d'utiliser ou d'activer la réplication de flux, n'oubliez pas de la désactiver car elle enregistrera toujours d'énormes transactions et augmentera considérablement les performances de votre cluster. Pour le désactiver, lancez simplement
[email protected][sbtest]#> set wsrep_trx_fragment_size=0;
Query OK, 0 rows affected (0.04 sec)
Conclusion
Avec la réplication en continu activée, il est important que vous puissiez identifier la taille de votre fragment et l'unité que vous devez choisir (octets, lignes, instructions).
Il est également très important que vous deviez l'exécuter au niveau de la session et bien sûr identifier quand vous n'avez besoin d'utiliser que la réplication en continu.
Lors de l'exécution de ces tests, la suppression d'un grand nombre de lignes dans une immense table avec la réplication en continu activée a sensiblement provoqué un pic élevé d'utilisation du disque et de l'utilisation du processeur. La RAM était plus stable, mais cela pourrait être dû au fait que la déclaration que nous avons effectuée n'est pas hautement un conflit de mémoire.
Il est prudent de dire que la réplication en continu peut entraîner des goulots d'étranglement de performances lorsqu'il s'agit d'enregistrements volumineux. Par conséquent, son utilisation doit être effectuée avec la décision et le soin appropriés.
Enfin, si vous utilisez la réplication en continu, n'oubliez pas de toujours désactiver cette opération une fois effectuée sur la session en cours pour éviter des problèmes indésirables.