sql >> Databasteknik >  >> RDS >> MariaDB

En guide till MySQL Galera Cluster Streaming Replication:Del två

I den första delen av den här bloggen gav vi en översikt över den nya strömningsreplikeringsfunktionen i MySQL Galera Cluster. I den här bloggen kommer vi att visa dig hur du aktiverar det och ta en titt på resultaten.

Aktivera strömmande replikering

Det rekommenderas starkt att du aktiverar strömmande replikering på sessionsnivå för de specifika transaktioner som interagerar med din applikation/klient.

Som nämndes i föregående blogg loggar Galera sina skrivuppsättningar till tabellen wsrep_streaming_log i MySQL-databasen. Detta har potential att skapa en prestandaflaskhals, särskilt när en återställning behövs. Detta betyder inte att du inte kan använda Streaming Replication, det betyder bara att du måste designa din applikationsklient effektivt när du använder Streaming Replication så att du får bättre prestanda. Ändå är det bäst att ha Streaming Replication för att hantera och minska stora transaktioner.

Att aktivera strömmande replikering kräver att du definierar replikeringsenheten och antalet enheter som ska användas för att bilda transaktionsfragmenten. Två parametrar styr dessa variabler:wsrep_trx_fragment_unit och wsrep_trx_fragment_size.

Nedan är ett exempel på hur man ställer in dessa två parametrar:

SET SESSION wsrep_trx_fragment_unit='statements';

SET SESSION wsrep_trx_fragment_size=3;

I det här exemplet är fragmentet satt till tre satser. För var tredje påstående från en transaktion kommer noden att generera, replikera och certifiera ett fragment.

Du kan välja mellan några få replikeringsenheter när du bildar fragment:

  • byte - Detta definierar fragmentstorleken i byte.
  • rader - Detta definierar fragmentstorleken som antalet rader som fragmentet uppdaterar.
  • påståenden - Detta definierar fragmentstorleken som antalet påståenden i ett fragment.

Välj den replikeringsenhet och fragmentstorlek som bäst passar den specifika operation du vill köra.

Streamande replikering i funktion

Som diskuteras i vår andra blogg om hantering av stora transaktioner i Mariadb 10.4, utförde och testade vi hur Streaming Replikering fungerade när den var aktiverad baserat på detta kriterium...

  1. Baslinje, ställ in global wsrep_trx_fragment_size=0;
  2. set global wsrep_trx_fragment_unit='rows'; set global wsrep_trx_fragment_size=1;
  3. set global wsrep_trx_fragment_unit='statements'; set global wsrep_trx_fragment_size=1;
  4. set global wsrep_trx_fragment_unit='statements'; set global wsrep_trx_fragment_size=5;

Och resultaten är

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 det här exemplet använder vi Percona XtraDB Cluster 8.0.15 direkt från deras testgren med Percona-XtraDB-Cluster_8.0.15.5-27dev.4.2_Linux.x86_64.ssl102.tar.gz bygga.

Vi provade sedan ett Galera-kluster med 3 noder med värdinformation nedan:

testnode11 = 192.168.10.110

testnode12 = 192.168.10.120

testnode13 = 192.168.10.130

Vi förbefolkade en tabell från min sysbench-databas och försökte ta bort en mycket stor rad.

[email protected][sbtest]#> select count(*) from sbtest1;

+----------+

| count(*) |

+----------+

| 12608218 |

+----------+

1 row in set (25.55 sec)

Körs först utan strömmande replikering,

[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 sedan,

[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;

Men det slutade med att vi fick en återställning...

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

Användning av ClusterControl Dashboards för att samla en översikt över alla indikationer på flödeskontroll, eftersom transaktionen körs enbart på huvudnoden (active-writer) tills commit-tidpunkten, finns det ingen indikation på aktivitet för flödeskontroll:

Om du undrar så fungerar inte den aktuella versionen av ClusterControl ännu har direkt stöd för PXC 8.0 med Galera Cluster 4 (eftersom det fortfarande är experimentellt). Du kan dock försöka importera det... men det behöver mindre justeringar för att dina Dashboards ska fungera korrekt.

Tillbaka till frågeprocessen. Det misslyckades när det rullade tillbaka!

[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;

ERROR 1180 (HY000): Got error 5 - 'Transaction size exceed set threshold' during COMMIT

oavsett 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ådde så småningom tröskeln.

Under denna tid är systemtabellen mysql.wsrep_streaming_log tom, vilket indikerar att strömmande replikering inte sker eller är aktiverad,

[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)

och det är verifierat på de andra två noderna (testnode12 och testnode13).

Nu, låt oss försöka aktivera 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)

Vad kan man förvänta sig när Galera Cluster Streaming Replikering är aktiverad?

När frågan har utförts i testnode11,

[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;

Vad som händer är att den fragmenterar transaktionen bit för bit beroende på inställningsvärdet för variabeln wsrep_trx_fragment_size. Låt oss kontrollera detta i de andra noderna:

Värd 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ärd 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 är märkbart att flödeskontrollen precis startade!

Och WSREP-köer som skickas/mottas har också börjat:

Värd testnode12 (192.168.10.120)  Värd testnode13 (192.168.10.130)

Låt oss nu få mer av resultatet från 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)

och sedan ta resultatet av,

[email protected][sbtest]#> select count(*) from mysql.wsrep_streaming_log;

+----------+

| count(*) |

+----------+

|    38899 |

+----------+

1 row in set (0.40 sec)

Den talar om hur mycket fragment som har replikerats med Streaming Replication. Låt oss nu göra lite grundläggande matematik:

[email protected][sbtest]#> select 3876500/38899.0;

+-----------------+

| 3876500/38899.0 |

+-----------------+

|         99.6555 |

+-----------------+

1 row in set (0.03 sec)

Jag tar ångraloggposterna från SHOW ENGINE INNODB STATUS\G-resultatet och delar sedan det totala antalet mysql.wsrep_streaming_log-poster. Som jag har ställt in det tidigare, definierade jag wsrep_trx_fragment_size=100. Resultatet kommer att visa dig hur mycket de totala replikerade loggarna för närvarande bearbetas av Galera.

Det är viktigt att notera vad Streaming Replication försöker uppnå... "noden bryter transaktionen i fragment, sedan certifierar och replikerar dem på slavarna medan transaktionen fortfarande är i framsteg. När det väl är certifierat kan fragmentet inte längre avbrytas av motstridiga transaktioner."

Fragmenten betraktas som transaktioner, som har skickats till de återstående noderna i klustret, som certifierar den fragmenterade transaktionen och sedan applicerar skrivuppsättningarna. Det betyder att när din stora transaktion har certifierats eller prioriterats, kommer alla inkommande anslutningar som kan ha ett dödläge att behöva vänta tills transaktionerna är klara.

Nu, domen att ta bort ett stort bord?

[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;

Query OK, 12034538 rows affected (30 min 36.96 sec)

Det slutförs utan några misslyckanden!

Hur ser det ut i de andra noderna? I testnod12,

[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 stannar vid totalt 120345 fragment, och om vi gör matematiken igen på de senast hämtade ångringsloggposterna (ångra loggarna är desamma från mastern också),

[email protected][sbtest]#> select 12154883/120345.0;                                                                                                                                                   +-------------------+

| 12154883/120345.0 |

+-------------------+

|          101.0003 |

+-------------------+

1 row in set (0.00 sec)

Så vi hade totalt 120345 transaktioner fragmenteras för att radera 12034538 rader.

När du är klar med att använda eller aktivera strömreplikering, glöm inte att inaktivera det eftersom det alltid kommer att logga enorma transaktioner och lägga till en hel del prestandakostnader till ditt kluster. För att inaktivera det, kör bara

[email protected][sbtest]#> set wsrep_trx_fragment_size=0;

Query OK, 0 rows affected (0.04 sec)

Slutsats

Med strömmande replikering aktiverad är det viktigt att du kan identifiera hur stor din fragmentstorlek kan vara och vilken enhet du måste välja (byte, rader, satser).

Det är också mycket viktigt att du behöver köra det på sessionsnivå och naturligtvis identifiera när du bara behöver använda Streaming Replication.

Medan du utförde dessa tester, har radering av ett stort antal rader i en enorm tabell med strömreplikering aktiverat märkbart orsakat en hög topp av diskanvändning och CPU-användning. RAM-minnet var mer stabilt, men detta kan på grund av uttalandet vi gjorde inte är särskilt minnespåstående.

Det är säkert att säga att strömmande replikering kan orsaka prestandaflaskhalsar när man hanterar stora poster, så användningen bör göras med rätt beslut och försiktighet.

Sistligen, om du använder strömmande replikering, glöm inte att alltid inaktivera detta när du gjort det på den aktuella sessionen för att undvika oönskade problem.


  1. Skapa en databas programmatiskt i SQL Server

  2. Funktion för att ta bort accenter i postgreSQL

  3. Varför gillar inte PostgreSQL tabellnamn med VERSALER?

  4. Vad är skillnaden mellan MySQL och SQL?