I den første del af denne blog gav vi et overblik over den nye streamingreplikeringsfunktion i MySQL Galera Cluster. I denne blog vil vi vise dig, hvordan du aktiverer det og tage et kig på resultaterne.
Aktivering af streamingreplikering
Det anbefales stærkt, at du aktiverer streamingreplikering på sessionsniveau for de specifikke transaktioner, der interagerer med din applikation/klient.
Som angivet i den forrige blog, logger Galera sine skrivesæt til tabellen wsrep_streaming_log i MySQL-databasen. Dette har potentialet til at skabe en flaskehals i ydeevnen, især når en tilbagerulning er nødvendig. Dette betyder ikke, at du ikke kan bruge Streaming Replication, det betyder blot, at du skal designe din applikationsklient effektivt, når du bruger Streaming Replication, så du får bedre ydeevne. Alligevel er det bedst at have streamingreplikering til at håndtere og reducere store transaktioner.
At aktivere streamingreplikering kræver, at du definerer replikeringsenheden og antallet af enheder, der skal bruges til at danne transaktionsfragmenterne. To parametre styrer disse variable:wsrep_trx_fragment_unit og wsrep_trx_fragment_size.
Nedenfor er et eksempel på, hvordan man indstiller disse to parametre:
SET SESSION wsrep_trx_fragment_unit='statements';
SET SESSION wsrep_trx_fragment_size=3;
I dette eksempel er fragmentet sat til tre udsagn. For hver tre udsagn fra en transaktion vil noden generere, replikere og certificere et fragment.
Du kan vælge mellem nogle få replikeringsenheder, når du danner fragmenter:
- bytes - Dette definerer fragmentstørrelsen i bytes.
- rækker - Dette definerer fragmentstørrelsen som antallet af rækker, fragmentet opdaterer.
- udsagn - Dette definerer fragmentstørrelsen som antallet af udsagn i et fragment.
Vælg den replikeringsenhed og fragmentstørrelse, der passer bedst til den specifikke operation, du vil køre.
Streaming replikering i aktion
Som diskuteret i vores anden blog om håndtering af store transaktioner i Mariadb 10.4, udførte og testede vi, hvordan streamingreplikering fungerede, når den var aktiveret, baseret på dette kriterium...
- Baseline, sæt global wsrep_trx_fragment_size=0;
- set global wsrep_trx_fragment_unit='rows'; sæt global wsrep_trx_fragment_size=1;
- sæt globale wsrep_trx_fragment_unit='udsagn'; sæt global wsrep_trx_fragment_size=1;
- sæt globale wsrep_trx_fragment_unit='udsagn'; sæt global wsrep_trx_fragment_size=5;
Og resultaterne er
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%)
I dette eksempel bruger vi Percona XtraDB Cluster 8.0.15 direkte fra deres testgren ved hjælp af Percona-XtraDB-Cluster_8.0.15.5-27dev.4.2_Linux.x86_64.ssl102.tar.gz bygge.
Vi prøvede derefter en 3-node Galera-klynge med værtsoplysninger nedenfor:
testnode11 = 192.168.10.110
testnode12 = 192.168.10.120
testnode13 = 192.168.10.130
Vi præfyldte en tabel fra min sysbench-database og forsøgte at slette en meget stor række.
[email protected][sbtest]#> select count(*) from sbtest1;
+----------+
| count(*) |
+----------+
| 12608218 |
+----------+
1 row in set (25.55 sec)
Kører først uden streamingreplikering,
[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)
Kør derefter,
[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;
Vi endte dog med at få en tilbagerulning...
---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
Brug af ClusterControl Dashboards til at samle et overblik over enhver indikation af flowkontrol, da transaktionen udelukkende kører på master (active-writer) noden indtil commit tid, er der ingen indikation af aktivitet for flowkontrol:
Hvis du undrer dig, gør den nuværende version af ClusterControl det ikke endnu har direkte understøttelse af PXC 8.0 med Galera Cluster 4 (da det stadig er eksperimentelt). Du kan dog prøve at importere det... men det kræver mindre justeringer for at få dine Dashboards til at fungere korrekt.
Tilbage til forespørgselsprocessen. Det mislykkedes, da det rullede tilbage!
[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;
ERROR 1180 (HY000): Got error 5 - 'Transaction size exceed set threshold' during COMMIT
uanset wsrep_max_ws_rows eller 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)
Det nåede til sidst tærsklen.
I dette tidsrum er systemtabellen mysql.wsrep_streaming_log tom, hvilket indikerer, at streamingreplikering ikke sker eller er aktiveret,
[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)
og det er verificeret på de andre 2 noder (testnode12 og testnode13).
Lad os nu prøve at aktivere det med 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)
Hvad kan man forvente, når Galera Cluster Streaming-replikering er aktiveret?
Når forespørgsel er blevet udført i testnode11,
[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;
Det, der sker, er, at den fragmenterer transaktionen stykke for stykke afhængigt af den indstillede værdi af variablen wsrep_trx_fragment_size. Lad os tjekke dette i de andre noder:
Vært 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)
Vært 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)
Det er bemærkelsesværdigt, at flowkontrollen lige er startet!
Og WSREP-køer, der er sendt/modtaget, har også været i gang:
Host testnode12 (192.168.10.120) Host testnode13 (192.168.10.130)Lad os nu få mere af resultatet fra tabellen 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)
og derefter tage resultatet af,
[email protected][sbtest]#> select count(*) from mysql.wsrep_streaming_log;
+----------+
| count(*) |
+----------+
| 38899 |
+----------+
1 row in set (0.40 sec)
Det fortæller, hvor meget fragment der er blevet replikeret ved hjælp af Streaming Replication. Lad os nu lave noget grundlæggende matematik:
[email protected][sbtest]#> select 3876500/38899.0;
+-----------------+
| 3876500/38899.0 |
+-----------------+
| 99.6555 |
+-----------------+
1 row in set (0.03 sec)
Jeg tager fortryd-logposterne fra SHOW ENGINE INNODB STATUS\G-resultatet og dividerer derefter det samlede antal mysql.wsrep_streaming_log-poster. Som jeg har indstillet det tidligere, definerede jeg wsrep_trx_fragment_size=100. Resultatet vil vise dig, hvor meget de samlede replikerede logfiler i øjeblikket behandles af Galera.
Det er vigtigt at lægge mærke til, hvad streamingreplikering forsøger at opnå... "knuden opdeler transaktionen i fragmenter, certificerer og replikerer dem derefter på slaverne, mens transaktionen stadig er i gang fremskridt. Når det er certificeret, kan fragmentet ikke længere afbrydes af modstridende transaktioner."
Fragmenterne betragtes som transaktioner, som er blevet videregivet til de resterende noder i klyngen, der bekræfter den fragmenterede transaktion og derefter anvender skrivesættene. Det betyder, at når først din store transaktion er blevet certificeret eller prioriteret, skal alle indgående forbindelser, der muligvis kan have et dødvande, vente, indtil transaktionerne afsluttes.
Nu, dommen om at slette et stort bord?
[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;
Query OK, 12034538 rows affected (30 min 36.96 sec)
Det afsluttes uden fejl!
Hvordan ser det ud i de andre noder? I 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)
Det stopper ved i alt 120345 fragmenter, og hvis vi udfører regnestykket igen på de sidst fangede fortryd-logposter (fortryd-logs er også de samme fra masteren),
[email protected][sbtest]#> select 12154883/120345.0; +-------------------+
| 12154883/120345.0 |
+-------------------+
| 101.0003 |
+-------------------+
1 row in set (0.00 sec)
Så vi havde i alt 120345 transaktioner bliver fragmenteret for at slette 12034538 rækker.
Når du er færdig med at bruge eller aktivere Stream Replication, så glem ikke at deaktivere det, da det altid vil logge store transaktioner og tilføjer en masse ydelsesoverhead til din klynge. For at deaktivere den skal du bare køre
[email protected][sbtest]#> set wsrep_trx_fragment_size=0;
Query OK, 0 rows affected (0.04 sec)
Konklusion
Med Streaming Replikering aktiveret, er det vigtigt, at du er i stand til at identificere, hvor stor din fragmentstørrelse kan være, og hvilken enhed du skal vælge (bytes, rækker, sætninger).
Det er også meget vigtigt, at du skal køre det på sessionsniveau og selvfølgelig identificere, hvornår du kun skal bruge Streaming Replication.
Mens du udfører disse tests, har sletning af et stort antal rækker til en enorm tabel med Streaming Replikering aktiveret mærkbart forårsaget et højt toppunkt for diskudnyttelse og CPU-udnyttelse. RAM var mere stabil, men dette kunne på grund af den erklæring, vi udførte, ikke er meget en hukommelsespåstand.
Det er sikkert at sige, at streaming-replikering kan forårsage flaskehalse i ydeevnen, når man håndterer store poster, så brugen bør ske med den rette beslutning og omhu.
Til sidst, hvis du bruger streamingreplikering, så glem ikke altid at deaktivere dette, når det er gjort på den aktuelle session for at undgå uønskede problemer.