Pada bagian pertama blog ini kami memberikan gambaran umum tentang fitur Replikasi Streaming baru di MySQL Galera Cluster. Di blog ini kami akan menunjukkan cara mengaktifkannya dan melihat hasilnya.
Mengaktifkan Replikasi Streaming
Sangat disarankan agar Anda mengaktifkan Replikasi Streaming pada tingkat sesi untuk transaksi tertentu yang berinteraksi dengan aplikasi/klien Anda.
Seperti yang dinyatakan di blog sebelumnya, Galera mencatat set penulisannya ke tabel wsrep_streaming_log di database MySQL. Hal ini berpotensi menciptakan hambatan kinerja, terutama saat diperlukan rollback. Ini tidak berarti bahwa Anda tidak dapat menggunakan Replikasi Streaming, itu hanya berarti Anda perlu merancang klien aplikasi Anda secara efisien saat menggunakan Replikasi Streaming sehingga Anda akan mendapatkan kinerja yang lebih baik. Namun, yang terbaik adalah memiliki Replikasi Streaming untuk menangani dan mengurangi transaksi besar.
Mengaktifkan Replikasi Streaming mengharuskan Anda menentukan unit replikasi dan jumlah unit yang akan digunakan dalam membentuk fragmen transaksi. Dua parameter mengontrol variabel ini:wsrep_trx_fragment_unit dan wsrep_trx_fragment_size.
Di bawah ini adalah contoh cara menyetel kedua parameter ini:
SET SESSION wsrep_trx_fragment_unit='statements';
SET SESSION wsrep_trx_fragment_size=3;
Dalam contoh ini, fragmen disetel ke tiga pernyataan. Untuk setiap tiga pernyataan dari sebuah transaksi, node akan menghasilkan, mereplikasi, dan mengesahkan sebuah fragmen.
Anda dapat memilih di antara beberapa unit replikasi saat membentuk fragmen:
- byte - Ini menentukan ukuran fragmen dalam byte.
- baris - Ini mendefinisikan ukuran fragmen sebagai jumlah baris yang diperbarui oleh fragmen.
- pernyataan - Ini mendefinisikan ukuran fragmen sebagai jumlah pernyataan dalam sebuah fragmen.
Pilih unit replikasi dan ukuran fragmen yang paling sesuai dengan operasi spesifik yang ingin Anda jalankan.
Melakukan Streaming Replikasi
Seperti yang dibahas di blog kami yang lain tentang penanganan transaksi besar di Mariadb 10.4, kami melakukan dan menguji bagaimana Replikasi Streaming dilakukan saat diaktifkan berdasarkan kriteria ini...
- Baseline, atur wsrep_trx_fragment_size=0 global;
- setel wsrep_trx_fragment_unit='baris' global; setel global wsrep_trx_fragment_size=1;
- mengatur wsrep_trx_fragment_unit='pernyataan' global; setel global wsrep_trx_fragment_size=1;
- mengatur wsrep_trx_fragment_unit='pernyataan' global; atur wsrep_trx_fragment_size=5 global;
Dan hasilnya
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%)
Untuk contoh ini kami menggunakan Percona XtraDB Cluster 8.0.15 langsung dari cabang pengujian mereka menggunakan Percona-XtraDB-Cluster_8.0.15.5-27dev.4.2_Linux.x86_64.ssl102.tar.gz membangun.
Kami kemudian mencoba cluster Galera 3-node dengan info host di bawah ini:
testnode11 = 192.168.10.110
testnode12 = 192.168.10.120
testnode13 = 192.168.10.130
Kami mengisi tabel sebelumnya dari database sysbench saya dan mencoba menghapus baris yang sangat besar.
[email protected][sbtest]#> select count(*) from sbtest1;
+----------+
| count(*) |
+----------+
| 12608218 |
+----------+
1 row in set (25.55 sec)
Pada awalnya, berjalan tanpa Replikasi Streaming,
[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)
Lalu jalankan,
[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;
Namun, kami akhirnya mendapatkan pengembalian...
---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
Menggunakan Dasbor ClusterControl untuk mengumpulkan gambaran umum tentang indikasi kontrol aliran, karena transaksi hanya berjalan pada node master (penulis aktif) hingga waktu komit, tidak ada indikasi aktivitas untuk kontrol aliran:
Jika Anda bertanya-tanya, versi ClusterControl saat ini belum memiliki dukungan langsung untuk PXC 8.0 dengan Galera Cluster 4 (karena masih eksperimental). Namun, Anda dapat mencoba mengimpornya... tetapi perlu sedikit penyesuaian agar Dasbor Anda berfungsi dengan benar.
Kembali ke proses query. Gagal saat diputar kembali!
[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;
ERROR 1180 (HY000): Got error 5 - 'Transaction size exceed set threshold' during COMMIT
terlepas dari wsrep_max_ws_rows atau 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)
Akhirnya, mencapai ambang batas.
Selama ini tabel sistem mysql.wsrep_streaming_log kosong, yang menunjukkan bahwa Replikasi Streaming tidak terjadi atau diaktifkan,
[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)
dan itu diverifikasi pada 2 node lainnya (testnode12 dan testnode13).
Sekarang, mari kita coba mengaktifkannya dengan Replikasi Streaming,
[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)
Apa yang Diharapkan Saat Replikasi Streaming Cluster Galera Diaktifkan?
Ketika kueri telah dilakukan di testnode11,
[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;
Apa yang terjadi adalah ia memecah transaksi sepotong demi sepotong tergantung pada nilai yang ditetapkan dari variabel wsrep_trx_fragment_size. Mari kita periksa ini di node lain:
Host 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)
Host 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)
Sepertinya, kontrol aliran baru saja dimulai!
Dan antrian pengiriman/penerimaan WSREP juga mulai meningkat:
Host testnode12 (192.168.10.120) Host testnode13 (192.168.10.130)Sekarang, mari kita uraikan lebih lanjut hasilnya dari tabel 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)
lalu ambil hasil dari,
[email protected][sbtest]#> select count(*) from mysql.wsrep_streaming_log;
+----------+
| count(*) |
+----------+
| 38899 |
+----------+
1 row in set (0.40 sec)
Ini memberi tahu berapa banyak fragmen yang telah direplikasi menggunakan Replikasi Streaming. Sekarang, mari kita lakukan beberapa matematika dasar:
[email protected][sbtest]#> select 3876500/38899.0;
+-----------------+
| 3876500/38899.0 |
+-----------------+
| 99.6555 |
+-----------------+
1 row in set (0.03 sec)
Saya mengambil entri log undo dari hasil SHOW ENGINE INNODB STATUS\G dan kemudian membagi jumlah total catatan mysql.wsrep_streaming_log. Seperti yang telah saya atur sebelumnya, saya mendefinisikan wsrep_trx_fragment_size=100. Hasilnya akan menunjukkan kepada Anda berapa banyak total log yang direplikasi saat ini sedang diproses oleh Galera.
Penting untuk memperhatikan apa yang ingin dicapai oleh Replikasi Streaming... "node memecah transaksi menjadi beberapa bagian, lalu mengesahkan dan mereplikasinya pada slave saat transaksi masih berlangsung kemajuan. Setelah disertifikasi, fragmen tidak dapat lagi dibatalkan oleh transaksi yang bentrok."
Fragmen dianggap sebagai transaksi, yang telah diteruskan ke node yang tersisa di dalam kluster, mengesahkan transaksi yang terfragmentasi, kemudian menerapkan set tulis. Artinya, setelah transaksi besar Anda disertifikasi atau diprioritaskan, semua koneksi masuk yang mungkin menemui jalan buntu harus menunggu hingga transaksi selesai.
Sekarang, keputusan menghapus tabel besar?
[email protected][sbtest]#> delete from sbtest1 where id >= 2000000;
Query OK, 12034538 rows affected (30 min 36.96 sec)
Selesai dengan sukses tanpa gagal!
Bagaimana tampilannya di node lain? Di 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)
Berhenti dengan total 120345 fragmen, dan jika kita menghitung lagi pada entri log undo yang terakhir ditangkap (log undo juga sama dari master),
[email protected][sbtest]#> select 12154883/120345.0; +-------------------+
| 12154883/120345.0 |
+-------------------+
| 101.0003 |
+-------------------+
1 row in set (0.00 sec)
Jadi kami memiliki total 120345 transaksi sedang terfragmentasi untuk dihapus 12034538 baris.
Setelah Anda selesai menggunakan atau mengaktifkan Stream Replication, jangan lupa untuk menonaktifkannya karena akan selalu mencatat transaksi besar dan menambahkan banyak overhead kinerja ke cluster Anda. Untuk menonaktifkannya, jalankan saja
[email protected][sbtest]#> set wsrep_trx_fragment_size=0;
Query OK, 0 rows affected (0.04 sec)
Kesimpulan
Dengan Replikasi Streaming diaktifkan, penting bagi Anda untuk dapat mengidentifikasi seberapa besar ukuran fragmen Anda dan unit apa yang harus Anda pilih (byte, baris, pernyataan).
Juga sangat penting bahwa Anda perlu menjalankannya di tingkat sesi dan tentu saja mengidentifikasi kapan Anda hanya perlu menggunakan Replikasi Streaming.
Saat melakukan pengujian ini, menghapus sejumlah besar baris ke tabel besar dengan Replikasi Streaming yang diaktifkan secara nyata menyebabkan puncak penggunaan disk dan penggunaan CPU yang tinggi. RAM lebih stabil, tetapi ini bisa karena pernyataan yang kami lakukan tidak terlalu merupakan pertengkaran memori.
Dapat dikatakan bahwa Replikasi Streaming dapat menyebabkan kemacetan kinerja saat menangani catatan besar, jadi menggunakannya harus dilakukan dengan keputusan dan perhatian yang tepat.
Terakhir, jika Anda menggunakan Replikasi Streaming, jangan lupa untuk selalu menonaktifkan ini setelah selesai pada sesi saat ini untuk menghindari masalah yang tidak diinginkan.