MariaDB
 sql >> Datenbank >  >> RDS >> MariaDB

Ein Leitfaden zur Cluster-Streaming-Replikation von MySQL Galera:Teil Zwei

Im ersten Teil dieses Blogs haben wir einen Überblick über die neue Streaming-Replikationsfunktion in MySQL Galera Cluster gegeben. In diesem Blog zeigen wir Ihnen, wie Sie es aktivieren und werfen einen Blick auf die Ergebnisse.

Streaming-Replikation aktivieren

Es wird dringend empfohlen, die Streaming-Replikation auf Sitzungsebene für die spezifischen Transaktionen zu aktivieren, die mit Ihrer Anwendung/Ihrem Client interagieren.

Wie im vorherigen Blog erwähnt, protokolliert Galera seine Write-Sets in der Tabelle wsrep_streaming_log in der MySQL-Datenbank. Dies kann zu einem Leistungsengpass führen, insbesondere wenn ein Rollback erforderlich ist. Das bedeutet nicht, dass Sie die Streaming-Replikation nicht verwenden können, es bedeutet lediglich, dass Sie Ihren Anwendungsclient effizient gestalten müssen, wenn Sie die Streaming-Replikation verwenden, damit Sie eine bessere Leistung erzielen. Dennoch ist es am besten, die Streaming-Replikation zu haben, um große Transaktionen zu bewältigen und zu reduzieren.

Um die Streaming-Replikation zu aktivieren, müssen Sie die Replikationseinheit und die Anzahl der Einheiten definieren, die zum Bilden der Transaktionsfragmente verwendet werden sollen. Zwei Parameter steuern diese Variablen:wsrep_trx_fragment_unit und wsrep_trx_fragment_size.

Unten ist ein Beispiel dafür, wie diese beiden Parameter gesetzt werden:

SET SESSION wsrep_trx_fragment_unit='statements';

SET SESSION wsrep_trx_fragment_size=3;

In diesem Beispiel ist das Fragment auf drei Anweisungen festgelegt. Für jeweils drei Anweisungen einer Transaktion generiert, repliziert und zertifiziert der Knoten ein Fragment.

Sie können beim Bilden von Fragmenten zwischen einigen Replikationseinheiten wählen:

  • Byte - Dies definiert die Fragmentgröße in Bytes.
  • Zeilen - Dies definiert die Fragmentgröße als die Anzahl der Zeilen, die das Fragment aktualisiert.
  • Aussagen - Dies definiert die Fragmentgröße als die Anzahl der Anweisungen in einem Fragment.

Wählen Sie die Replikationseinheit und die Fragmentgröße, die am besten zu der spezifischen Operation passt, die Sie ausführen möchten.

Streaming-Replikation in Aktion

Wie in unserem anderen Blog über den Umgang mit großen Transaktionen in Mariadb 10.4 besprochen, haben wir durchgeführt und getestet, wie die Streaming-Replikation funktioniert, wenn sie basierend auf diesen Kriterien aktiviert ist...

  1. Baseline, global wsrep_trx_fragment_size=0 setzen;
  2. global festlegen wsrep_trx_fragment_unit='rows'; setze global wsrep_trx_fragment_size=1;
  3. global setzen wsrep_trx_fragment_unit='statements'; setze global wsrep_trx_fragment_size=1;
  4. global setzen wsrep_trx_fragment_unit='statements'; setze global wsrep_trx_fragment_size=5;

Und Ergebnisse sind

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

Für dieses Beispiel verwenden wir Percona XtraDB Cluster 8.0.15 direkt aus ihrem Testing-Zweig unter Verwendung von Percona-XtraDB-Cluster_8.0.15.5-27dev.4.2_Linux.x86_64.ssl102.tar.gz bauen.

Wir haben dann einen 3-Knoten-Galera-Cluster mit folgenden Hostinformationen ausprobiert:

testnode11 = 192.168.10.110

testnode12 = 192.168.10.120

testnode13 = 192.168.10.130

Wir haben eine Tabelle aus meiner Sysbench-Datenbank vorbelegt und versucht, sehr große Zeilen zu löschen.

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

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

| count(*) |

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

| 12608218 |

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

1 row in set (25.55 sec)

Am Anfang ohne Streaming-Replikation,

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

Dann lauf,

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

Allerdings haben wir am Ende ein Rollback bekommen...

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

Die Verwendung von ClusterControl-Dashboards, um einen Überblick über alle Hinweise auf die Flusskontrolle zu erhalten, da die Transaktion bis zur Commit-Zeit ausschließlich auf dem Master-Knoten (aktiver Schreiber) ausgeführt wird, gibt es keinen Hinweis auf eine Aktivität für die Flusskontrolle:

Falls Sie sich fragen, die aktuelle Version von ClusterControl noch nicht haben direkte Unterstützung für PXC 8.0 mit Galera Cluster 4 (da es noch experimentell ist). Sie können jedoch versuchen, es zu importieren ... aber es sind geringfügige Änderungen erforderlich, damit Ihre Dashboards ordnungsgemäß funktionieren.

Zurück zum Abfrageprozess. Es ist beim Zurücksetzen fehlgeschlagen!

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

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

unabhängig von wsrep_max_ws_rows oder 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)

Es hat schließlich die Schwelle erreicht.

Während dieser Zeit ist die Systemtabelle mysql.wsrep_streaming_log leer, was darauf hinweist, dass die Streaming-Replikation nicht stattfindet oder aktiviert ist,

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

und das wird auf den anderen 2 Knoten (testnode12 und testnode13) verifiziert.

Lassen Sie uns jetzt versuchen, es mit Streaming-Replikation zu aktivieren,

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

Was ist zu erwarten, wenn die Galera-Cluster-Streaming-Replikation aktiviert ist?

Wenn die Abfrage in testnode11 durchgeführt wurde,

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

Was passiert ist, dass die Transaktion Stück für Stück fragmentiert wird, abhängig vom eingestellten Wert der Variablen wsrep_trx_fragment_size. Lassen Sie uns dies in den anderen Knoten überprüfen:

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

Testknoten13 hosten

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

Bemerkenswerterweise hat die Flusskontrolle einfach eingesetzt!

Und WSREP-Warteschlangen zum Senden/Empfangen wurden ebenfalls hochgefahren:

Host testnode12 (192.168.10.120)  Host testnode13 (192.168.10.130)

Lassen Sie uns nun das Ergebnis näher erläutern aus der mysql.wsrep_streaming_log-Tabelle,

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

dann das Ergebnis von nehmen,

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

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

| count(*) |

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

|    38899 |

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

1 row in set (0.40 sec)

Er gibt an, wie viele Fragmente mit der Streaming-Replikation repliziert wurden. Lassen Sie uns nun ein paar grundlegende Berechnungen anstellen:

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

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

| 3876500/38899.0 |

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

|         99.6555 |

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

1 row in set (0.03 sec)

Ich nehme die Undo-Log-Einträge aus dem SHOW ENGINE INNODB STATUS\G-Ergebnis und teile dann die Gesamtzahl der mysql.wsrep_streaming_log-Einträge. Wie ich es früher gesetzt habe, habe ich wsrep_trx_fragment_size=100 definiert. Das Ergebnis zeigt Ihnen, wie viel die gesamten replizierten Protokolle derzeit von Galera verarbeitet werden.

Es ist wichtig zu beachten, was die Streaming-Replikation zu erreichen versucht... "der Knoten zerlegt die Transaktion in Fragmente, zertifiziert und repliziert sie dann auf den Slaves, während die Transaktion noch läuft Fortschritt. Nach der Zertifizierung kann das Fragment nicht mehr durch widersprüchliche Transaktionen abgebrochen werden."

Die Fragmente werden als Transaktionen betrachtet, die an die verbleibenden Knoten innerhalb des Clusters weitergegeben wurden, die fragmentierte Transaktion zertifizieren und dann die Write-Sets anwenden. Das bedeutet, dass, sobald Ihre große Transaktion zertifiziert oder priorisiert wurde, alle eingehenden Verbindungen, die möglicherweise einen Deadlock haben könnten, warten müssen, bis die Transaktionen abgeschlossen sind.

Nun, das Urteil über das Löschen einer riesigen Tabelle?

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

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

Es wird ohne Fehler erfolgreich beendet!

Wie sieht es in den anderen Knoten aus? In 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)

Es stoppt bei einer Gesamtzahl von 120345 Fragmenten, und wenn wir die letzten erfassten Undo-Log-Einträge noch einmal nachrechnen (die Undo-Logs sind auch die gleichen vom Master),

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

| 12154883/120345.0 |

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

|          101.0003 |

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

1 row in set (0.00 sec)

Also hatten wir insgesamt 120345 Transaktionen werden fragmentiert, um 12034538 zu löschen Zeilen.

Wenn Sie mit der Verwendung oder Aktivierung der Stream-Replikation fertig sind, vergessen Sie nicht, sie zu deaktivieren, da sie immer große Transaktionen protokolliert und Ihrem Cluster eine Menge Mehrleistung hinzufügt. Um es zu deaktivieren, führen Sie einfach

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

Query OK, 0 rows affected (0.04 sec)

Fazit

Bei aktivierter Streaming-Replikation ist es wichtig, dass Sie erkennen können, wie groß Ihre Fragmentgröße sein kann und welche Einheit Sie wählen müssen (Bytes, Zeilen, Anweisungen).

Es ist auch sehr wichtig, dass Sie es auf Sitzungsebene ausführen und natürlich angeben müssen, wann Sie nur die Streaming-Replikation verwenden müssen.

Während der Durchführung dieser Tests hat das Löschen einer großen Anzahl von Zeilen in einer riesigen Tabelle mit aktivierter Streaming-Replikation merklich zu einer hohen Spitzenauslastung der Festplatte und der CPU geführt. Der Arbeitsspeicher war stabiler, was aber aufgrund der von uns durchgeführten Aussage nicht hochgradig ein Speicherkonflikt sein könnte.

Man kann mit Sicherheit sagen, dass die Streaming-Replikation beim Umgang mit großen Datensätzen Leistungsengpässe verursachen kann, daher sollte ihre Verwendung mit der richtigen Entscheidung und Sorgfalt erfolgen.

Zu guter Letzt, wenn Sie die Streaming-Replikation verwenden, vergessen Sie nicht, dies immer zu deaktivieren, wenn Sie dies in der aktuellen Sitzung getan haben, um unerwünschte Probleme zu vermeiden.