Budak MySQL mungkin menjadi tidak konsisten. Anda dapat mencoba menghindarinya, tetapi itu sangat sulit. Menyetel super_read_only dan menggunakan replikasi berbasis baris dapat banyak membantu, tetapi apa pun yang Anda lakukan, mungkin saja slave Anda akan menjadi tidak konsisten.
Apa yang dapat dilakukan untuk membangun kembali budak MySQL yang tidak konsisten? Dalam posting blog ini kita akan melihat masalah ini.
Pertama, mari kita bahas apa yang harus terjadi untuk membangun kembali seorang budak. Untuk membawa sebuah node ke dalam Replikasi MySQL, node tersebut harus dilengkapi dengan data dari salah satu node dalam topologi replikasi. Data ini harus konsisten pada saat dikumpulkan. Anda tidak dapat mengambilnya berdasarkan tabel per tabel atau skema berdasarkan skema, karena ini akan membuat node yang disediakan tidak konsisten secara internal. Artinya beberapa data akan lebih tua dari beberapa bagian lain dari kumpulan data.
Selain konsistensi data, informasi tentang hubungan antara data dan status replikasi juga dapat dikumpulkan. Anda ingin memiliki posisi log biner di mana data yang dikumpulkan konsisten atau ID Transaksi Global dari transaksi yang terakhir dieksekusi pada node yang merupakan sumber data.
Ini membawa kita pada pertimbangan berikut. Anda dapat membangun kembali slave menggunakan alat pencadangan apa pun selama alat ini dapat menghasilkan pencadangan yang konsisten dan mencakup koordinat replikasi untuk titik waktu di mana pencadangan konsisten. Ini memungkinkan kita untuk memilih dari beberapa opsi.
Menggunakan Mysqldump untuk Membangun Kembali Budak MySQL yang Tidak Konsisten
Mysqldump adalah alat paling dasar yang kita miliki untuk mencapai ini. Ini memungkinkan kita untuk membuat cadangan logis, antara lain, dalam bentuk pernyataan SQL. Yang penting, walaupun basic, masih memungkinkan kita untuk mengambil backup yang konsisten:dapat menggunakan transaksi untuk memastikan bahwa data konsisten di awal transaksi. Itu juga dapat menuliskan koordinat replikasi untuk titik itu, bahkan seluruh pernyataan CHANGE MASTER, sehingga mudah untuk memulai replikasi menggunakan cadangan.
Menggunakan Mydumper untuk Membangun Kembali Budak MySQL yang Tidak Konsisten
Pilihan lain adalah menggunakan mydumper - alat ini, seperti halnya mysqldump, menghasilkan cadangan logis dan, seperti halnya mysqldump, dapat digunakan untuk membuat cadangan database yang konsisten. Perbedaan utama antara mydumper dan mysqldump adalah bahwa mydumper, ketika dipasangkan dengan myloader, dapat membuang dan memulihkan data secara paralel, meningkatkan dump dan, terutama, waktu pemulihan.
Menggunakan Snapshot untuk Membangun Kembali MySQL Slave yang Tidak Konsisten
Bagi mereka yang menggunakan penyedia cloud, kemungkinan adalah mengambil snapshot dari penyimpanan blok yang mendasarinya. Snapshot menghasilkan tampilan data yang tepat waktu. Proses ini cukup rumit, karena konsistensi data dan kemampuan untuk memulihkannya sebagian besar bergantung pada konfigurasi MySQL.
Anda harus memastikan bahwa database bekerja dalam mode tahan lama (dikonfigurasi sedemikian rupa sehingga crash MySQL tidak akan mengakibatkan hilangnya data). Ini karena (dari sudut pandang MySQL) mengambil snapshot volume dan kemudian memulai instance MySQL lain dari data yang tersimpan di dalamnya, pada dasarnya, proses yang sama seperti jika Anda akan membunuh -9 mysqld dan kemudian memulainya lagi. Pemulihan InnoDB harus terjadi, memutar ulang transaksi yang telah disimpan dalam log biner, mengembalikan transaksi yang belum selesai sebelum crash dan sebagainya.
Kelemahan dari proses pembangunan kembali berbasis snapshot adalah sangat terikat dengan vendor saat ini. Anda tidak dapat dengan mudah menyalin data snapshot dari satu penyedia cloud ke penyedia cloud lainnya. Anda mungkin dapat memindahkannya antar wilayah yang berbeda, tetapi penyedianya akan tetap sama.
Menggunakan Xtrabackup atau Mariabackup untuk Membangun Kembali Budak MySQL yang Tidak Konsisten
Akhirnya, xtrabackup/mariabackup - ini adalah alat yang ditulis oleh Percona dan bercabang oleh MariaDB yang memungkinkan untuk menghasilkan cadangan fisik. Ini jauh lebih cepat daripada pencadangan logis - sebagian besar dibatasi oleh kinerja perangkat keras - disk atau jaringan menjadi hambatan yang paling mungkin terjadi. Sebagian besar beban kerja terkait dengan menyalin file dari direktori data MySQL ke lokasi lain (pada host yang sama atau melalui jaringan).
Meskipun tidak secepat snapshot penyimpanan blok, xtrabackup jauh lebih fleksibel dan dapat digunakan di lingkungan apa pun. Cadangan yang dihasilkannya terdiri dari file, oleh karena itu sangat mungkin untuk menyalin cadangan ke lokasi mana pun yang Anda suka. Penyedia cloud lain, pusat data lokal Anda, tidak masalah selama Anda dapat mentransfer file dari lokasi Anda saat ini.
Bahkan tidak harus memiliki konektivitas jaringan - Anda juga dapat menyalin cadangan ke beberapa perangkat "yang dapat ditransfer" seperti USB SSD atau bahkan stik USB, selama dapat berisi semua data dan simpan di saku Anda saat Anda berpindah dari satu pusat data ke pusat data lainnya.
Bagaimana Cara Membangun Kembali Budak MySQL Menggunakan Xtrabackup?
Kami memutuskan untuk fokus pada xtrabackup, mengingat fleksibilitas dan kemampuannya untuk bekerja di sebagian besar lingkungan tempat MySQL dapat eksis. Bagaimana Anda membangun kembali budak Anda menggunakan xtrabackup? Mari kita lihat.
Awalnya, kami memiliki master dan slave, yang mengalami beberapa masalah replikasi:
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.141
Master_User: rpl_user
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: binlog.000004
Read_Master_Log_Pos: 386
Relay_Log_File: relay-bin.000008
Relay_Log_Pos: 363
Relay_Master_Log_File: binlog.000004
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1007
Last_Error: Error 'Can't create database 'mytest'; database exists' on query. Default database: 'mytest'. Query: 'create database mytest'
Skip_Counter: 0
Exec_Master_Log_Pos: 195
Relay_Log_Space: 756
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 1007
Last_SQL_Error: Error 'Can't create database 'mytest'; database exists' on query. Default database: 'mytest'. Query: 'create database mytest'
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1001
Master_UUID: 53d96192-53f7-11ea-9c3c-080027c5bc64
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State:
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp: 200306 11:47:42
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 53d96192-53f7-11ea-9c3c-080027c5bc64:9
Executed_Gtid_Set: 53d96192-53f7-11ea-9c3c-080027c5bc64:1-8,
ce7d0c38-53f7-11ea-9f16-080027c5bc64:1-3
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set (0.00 sec)
Seperti yang Anda lihat, ada masalah dengan salah satu skema. Mari kita asumsikan kita harus membangun kembali simpul ini untuk membawanya kembali ke replikasi. Berikut adalah langkah-langkah yang harus kita lakukan.
Pertama, kita harus memastikan xtrabackup terinstal. Dalam kasus kami, kami menggunakan MySQL 8.0 oleh karena itu kami harus menggunakan xtrabackup di versi 8 untuk memastikan kompatibilitas:
[email protected]:~# apt install percona-xtrabackup-80
Reading package lists... Done
Building dependency tree
Reading state information... Done
percona-xtrabackup-80 is already the newest version (8.0.9-1.bionic).
0 upgraded, 0 newly installed, 0 to remove and 143 not upgraded.
Xtrabackup disediakan oleh repositori Percona dan panduan untuk menginstalnya dapat ditemukan di sini:
https://www.percona.com/doc/percona-xtrabackup/8.0/installation/apt_repo.html
Alat harus diinstal pada master dan slave yang ingin kita buat kembali.
Sebagai langkah selanjutnya kami akan menghapus semua data dari slave yang “rusak”:
[email protected]:~# service mysql stop
[email protected]:~# rm -rf /var/lib/mysql/*
Selanjutnya, kita akan mengambil backup pada master dan mengalirkannya ke slave. Harap diingat bahwa one-liner khusus ini memerlukan konektivitas root SSH tanpa kata sandi dari master ke slave:
[email protected]:~# xtrabackup --backup --compress --stream=xbstream --target-dir=./ | ssh [email protected] "xbstream -x --decompress -C /var/lib/mysql/"
Pada akhirnya Anda akan melihat baris penting:
200306 12:10:40 completed OK!
Ini adalah indikator bahwa pencadangan selesai dengan baik. Beberapa hal mungkin masih salah, tetapi setidaknya kami mendapatkan data yang benar. Selanjutnya pada slave, kita harus menyiapkan backupnya.
[email protected]:~# xtrabackup --prepare --target-dir=/var/lib/mysql/
.
.
.
200306 12:16:07 completed OK!
Anda akan melihat, sekali lagi, bahwa proses selesai dengan baik. Anda mungkin ingin menyalin data kembali ke direktori data MySQL. Kami tidak perlu melakukan itu karena kami menyimpan cadangan streaming langsung di /var/lib/mysql. Namun, yang ingin kami lakukan adalah memastikan kepemilikan file yang benar:
[email protected]:~# chown -R mysql.mysql /var/lib/mysql
Sekarang, mari kita periksa koordinat GTID cadangan. Kami akan menggunakannya nanti saat menyiapkan replikasi.
[email protected]:~# cat /var/lib/mysql/xtrabackup_binlog_info
binlog.000007 195 53d96192-53f7-11ea-9c3c-080027c5bc64:1-9
Ok, semuanya tampak baik-baik saja, mari kita mulai MySQL dan lanjutkan dengan mengkonfigurasi replikasi:
[email protected]:~# service mysql start
[email protected]:~# mysql -ppass
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.18-9 Percona Server (GPL), Release '9', Revision '53e606f'
Copyright (c) 2009-2019 Percona LLC and/or its affiliates
Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
Sekarang kita harus menyetel gtid_purged ke set GTID yang kita temukan di cadangan. Itu adalah GTID yang telah "di-cover" oleh backup kami. Hanya GTID baru yang boleh meniru dari master.
mysql> SET GLOBAL gtid_purged='53d96192-53f7-11ea-9c3c-080027c5bc64:1-9';
Query OK, 0 rows affected (0.00 sec)
Now we can start the replication:
mysql> CHANGE MASTER TO MASTER_HOST='10.0.0.141', MASTER_USER='rpl_user', MASTER_PASSWORD='yIPpgNE4KE', MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> START SLAVE;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.0.0.141
Master_User: rpl_user
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000007
Read_Master_Log_Pos: 380
Relay_Log_File: relay-bin.000002
Relay_Log_Pos: 548
Relay_Master_Log_File: binlog.000007
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 380
Relay_Log_Space: 750
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1001
Master_UUID: 53d96192-53f7-11ea-9c3c-080027c5bc64
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 53d96192-53f7-11ea-9c3c-080027c5bc64:10
Executed_Gtid_Set: 53d96192-53f7-11ea-9c3c-080027c5bc64:1-10
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set (0.00 sec)
Seperti yang Anda lihat, budak kami mereplikasi dari tuannya.
Bagaimana Cara Membangun Kembali Budak MySQL Menggunakan ClusterControl?
Jika Anda adalah pengguna ClusterControl, alih-alih melalui proses ini, Anda dapat membangun kembali slave hanya dalam beberapa klik. Awalnya kami memiliki masalah yang jelas dengan replikasi:
Budak kami tidak mereplikasi dengan benar karena kesalahan.
Yang harus kita lakukan adalah menjalankan tugas “Rebuild Replication Slave” .
Anda akan disajikan dengan dialog di mana Anda harus memilih node master untuk budak yang ingin Anda bangun kembali. Kemudian, klik Lanjutkan dan Anda sudah siap. ClusterControl akan membangun kembali slave dan menyiapkan replikasi untuk Anda.
Secara singkat, berdasarkan ukuran kumpulan data, Anda akan melihat budak yang berfungsi:
Seperti yang Anda lihat, hanya dengan beberapa klik, ClusterControl menyelesaikan tugas membangun kembali slave replikasi yang tidak konsisten.