Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

MySQL InnoDB Cluster 8.0 - Panduan Operasi Lengkap:Bagian Kedua

Di bagian pertama blog ini, kami membahas panduan penerapan MySQL InnoDB Cluster dengan contoh bagaimana aplikasi dapat terhubung ke cluster melalui port baca/tulis khusus.

Dalam panduan operasi ini, kami akan menunjukkan contoh tentang cara memantau, mengelola, dan menskalakan Cluster InnoDB sebagai bagian dari operasi pemeliharaan cluster yang sedang berlangsung. Kami akan menggunakan cluster yang sama dengan yang kami terapkan di bagian pertama blog. Diagram berikut menunjukkan arsitektur kami:

Kami memiliki Replikasi Grup MySQL tiga simpul dan satu server aplikasi yang berjalan dengan Perute MySQL. Semua server berjalan di Ubuntu 18.04 Bionic.

Opsi Perintah Cluster InnoDB MySQL

Sebelum kita melangkah lebih jauh dengan beberapa contoh dan penjelasan, ada baiknya untuk mengetahui bahwa Anda bisa mendapatkan penjelasan masing-masing fungsi di cluster MySQL untuk komponen cluster dengan menggunakan fungsi help(), seperti yang ditunjukkan di bawah ini:

$ mysqlsh
MySQL|localhost:3306 ssl|JS> shell.connect("[email protected]:3306");
MySQL|db1:3306 ssl|JS> cluster = dba.getCluster();
<Cluster:my_innodb_cluster>
MySQL|db1:3306 ssl|JS> cluster.help()

Daftar berikut menunjukkan fungsi yang tersedia pada MySQL Shell 8.0.18, untuk MySQL Community Server 8.0.18:

  • addInstance(instance[, options])- Menambahkan Instance ke cluster.
  • checkInstanceState(instance)- Memverifikasi status gtid instance dalam kaitannya dengan cluster.
  • describe()- Jelaskan struktur cluster.
  • disconnect()- Memutuskan semua sesi internal yang digunakan oleh objek cluster.
  • dissolve([options])- Menonaktifkan replikasi dan membatalkan pendaftaran ReplicaSet dari cluster.
  • forceQuorumUsingPartitionOf(instance[, password])- Memulihkan cluster dari kehilangan kuorum.
  • getName()- Mengambil nama cluster.
  • help([member])- Memberikan bantuan tentang kelas ini dan anggotanya
  • options([options])- Mencantumkan opsi konfigurasi cluster.
  • rejoinInstance(instance[, options])- Menggabungkan kembali Instance ke cluster.
  • removeInstance(instance[, options])- Menghapus Instance dari cluster.
  • scan ulang([options])- Memindai ulang cluster.
  • resetRecoveryAccountsPassword(options)- Setel ulang sandi akun pemulihan cluster.
  • setInstanceOption(instance, option, value)- Mengubah nilai opsi konfigurasi di anggota Cluster.
  • setOption(option, value)- Mengubah nilai opsi konfigurasi untuk seluruh cluster.
  • setPrimaryInstance(instance)- Memilih anggota cluster tertentu sebagai primer baru.
  • status([options])- Jelaskan status cluster.
  • switchToMultiPrimaryMode()- Mengalihkan cluster ke mode multi-primer.
  • switchToSinglePrimaryMode([instance])- Mengalihkan cluster ke mode single-primary.

Kami akan melihat sebagian besar fungsi yang tersedia untuk membantu kami memantau, mengelola, dan menskalakan cluster.

Memantau Operasi Cluster MySQL InnoDB

Status Gugus

Untuk memeriksa status cluster, pertama-tama gunakan baris perintah shell MySQL lalu sambungkan sebagai [email protected]{one-of-the-db-nodes}:

$ mysqlsh
MySQL|localhost:3306 ssl|JS> shell.connect("[email protected]:3306");

Kemudian, buat objek bernama "cluster" dan nyatakan sebagai objek global "dba" yang menyediakan akses ke fungsi administrasi cluster InnoDB menggunakan AdminAPI (lihat dokumen MySQL Shell API):

MySQL|db1:3306 ssl|JS> cluster = dba.getCluster();
<Cluster:my_innodb_cluster>

Kemudian, kita dapat menggunakan nama objek untuk memanggil fungsi API untuk objek "dba":

MySQL|db1:3306 ssl|JS> cluster.status()
{
    "clusterName": "my_innodb_cluster",
    "defaultReplicaSet": {
        "name": "default",
        "primary": "db1:3306",
        "ssl": "REQUIRED",
        "status": "OK",
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
        "topology": {
            "db1:3306": {
                "address": "db1:3306",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            },
            "db2:3306": {
                "address": "db2:3306",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": "00:00:09.061918",
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            },
            "db3:3306": {
                "address": "db3:3306",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": "00:00:09.447804",
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "db1:3306"
}

Outputnya cukup panjang tapi kita bisa menyaringnya dengan menggunakan struktur peta. Misalnya, jika kita ingin melihat jeda replikasi hanya untuk db3, kita dapat melakukan seperti berikut:

MySQL|db1:3306 ssl|JS> cluster.status().defaultReplicaSet.topology["db3:3306"].replicationLag
00:00:09.447804

Perhatikan bahwa jeda replikasi adalah sesuatu yang akan terjadi dalam replikasi grup, bergantung pada intensitas penulisan anggota utama dalam kumpulan replika dan variabel group_replication_flow_control_*. Kami tidak akan membahas topik ini secara rinci di sini. Lihat entri blog ini untuk memahami lebih lanjut tentang kinerja replikasi grup dan kontrol aliran.

Fungsi serupa lainnya adalah fungsi description() , tetapi yang ini sedikit lebih sederhana. Ini menjelaskan struktur cluster termasuk semua informasinya, ReplicaSets dan Instances:

MySQL|db1:3306 ssl|JS> cluster.describe()
{
    "clusterName": "my_innodb_cluster",
    "defaultReplicaSet": {
        "name": "default",
        "topology": [
            {
                "address": "db1:3306",
                "label": "db1:3306",
                "role": "HA"
            },
            {
                "address": "db2:3306",
                "label": "db2:3306",
                "role": "HA"
            },
            {
                "address": "db3:3306",
                "label": "db3:3306",
                "role": "HA"
            }
        ],
        "topologyMode": "Single-Primary"
    }
}

Demikian pula, kita dapat memfilter output JSON menggunakan struktur peta:

MySQL|db1:3306 ssl|JS> cluster.describe().defaultReplicaSet.topologyMode
Single-Primary

Ketika node utama turun (dalam hal ini, adalah db1), outputnya adalah sebagai berikut:

MySQL|db1:3306 ssl|JS> cluster.status()
{
    "clusterName": "my_innodb_cluster",
    "defaultReplicaSet": {
        "name": "default",
        "primary": "db2:3306",
        "ssl": "REQUIRED",
        "status": "OK_NO_TOLERANCE",
        "statusText": "Cluster is NOT tolerant to any failures. 1 member is not active",
        "topology": {
            "db1:3306": {
                "address": "db1:3306",
                "mode": "n/a",
                "readReplicas": {},
                "role": "HA",
                "shellConnectError": "MySQL Error 2013 (HY000): Lost connection to MySQL server at 'reading initial communication packet', system error: 104",
                "status": "(MISSING)"
            },
            "db2:3306": {
                "address": "db2:3306",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            },
            "db3:3306": {
                "address": "db3:3306",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "db2:3306"
}

Perhatikan status OK_NO_TOLERANCE, di mana cluster masih aktif dan berjalan tetapi tidak dapat mentolerir kegagalan lagi setelah satu dari tiga node tidak tersedia. Peran utama telah diambil alih oleh db2 secara otomatis, dan koneksi database dari aplikasi akan dialihkan ke node yang benar jika terhubung melalui MySQL Router. Setelah db1 kembali online, kita akan melihat status berikut:

MySQL|db1:3306 ssl|JS> cluster.status()
{
    "clusterName": "my_innodb_cluster",
    "defaultReplicaSet": {
        "name": "default",
        "primary": "db2:3306",
        "ssl": "REQUIRED",
        "status": "OK",
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
        "topology": {
            "db1:3306": {
                "address": "db1:3306",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            },
            "db2:3306": {
                "address": "db2:3306",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            },
            "db3:3306": {
                "address": "db3:3306",
                "mode": "R/O",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            }
        },
        "topologyMode": "Single-Primary"
    },
    "groupInformationSourceMember": "db2:3306"
}

Ini menunjukkan bahwa db1 sekarang tersedia tetapi berfungsi sebagai sekunder dengan hanya-baca diaktifkan. Peran utama masih ditetapkan ke db2 sampai terjadi kesalahan pada node, di mana ia akan secara otomatis gagal ke node berikutnya yang tersedia.

Periksa Status Instans

Kita dapat memeriksa status node MySQL sebelum berencana menambahkannya ke dalam cluster dengan menggunakan fungsi checkInstanceState(). Ini menganalisis GTID instance yang dieksekusi dengan GTID yang dieksekusi/dihapus pada cluster untuk menentukan apakah instance valid untuk cluster.

Berikut ini menunjukkan status instance db3 ketika berada dalam mode mandiri, sebelum bagian dari cluster:

MySQL|db1:3306 ssl|JS> cluster.checkInstanceState("db3:3306")
Cluster.checkInstanceState: The instance 'db3:3306' is a standalone instance but is part of a different InnoDB Cluster (metadata exists, instance does not belong to that metadata, and Group Replication is not active).

Jika node sudah menjadi bagian dari cluster, Anda harus mendapatkan yang berikut:

MySQL|db1:3306 ssl|JS> cluster.checkInstanceState("db3:3306")
Cluster.checkInstanceState: The instance 'db3:3306' already belongs to the ReplicaSet: 'default'.

Pantau Semua Status "Yang Dapat Diminta"

Dengan MySQL Shell, sekarang kita dapat menggunakan perintah \show dan \watch bawaan untuk memantau permintaan administratif apa pun secara real-time. Misalnya, kita bisa mendapatkan nilai real-time dari thread yang terhubung dengan menggunakan:

MySQL|db1:3306 ssl|JS> \show query SHOW STATUS LIKE '%thread%';

Atau dapatkan daftar proses MySQL saat ini:

MySQL|db1:3306 ssl|JS> \show query SHOW FULL PROCESSLIST

Kemudian kita dapat menggunakan perintah \watch untuk menjalankan laporan dengan cara yang sama seperti perintah \show, tetapi me-refresh hasil secara berkala sampai Anda membatalkan perintah menggunakan Ctrl + C. Seperti yang ditunjukkan pada contoh berikut:

MySQL|db1:3306 ssl|JS> \watch query SHOW STATUS LIKE '%thread%';
MySQL|db1:3306 ssl|JS> \watch query --interval=1 SHOW FULL PROCESSLIST

Interval penyegaran default adalah 2 detik. Anda dapat mengubah nilai dengan menggunakan tanda --interval dan menetapkan nilai dari 0,1 hingga 86400.

Operasi Manajemen Cluster MySQL InnoDB

Peralihan Utama

Instance primer adalah node yang dapat dianggap sebagai pemimpin dalam grup replikasi, yang memiliki kemampuan untuk melakukan operasi baca dan tulis. Hanya satu instance utama per cluster yang diizinkan dalam mode topologi primer tunggal. Topologi ini juga dikenal sebagai kumpulan replika dan merupakan mode topologi yang direkomendasikan untuk Replikasi Grup dengan perlindungan terhadap konflik penguncian.

Untuk melakukan peralihan instans utama, login ke salah satu node database sebagai pengguna clusteradmin dan tentukan node database yang ingin Anda promosikan dengan menggunakan fungsi setPrimaryInstance():

MySQL|db1:3306 ssl|JS> shell.connect("[email protected]:3306");
MySQL|db1:3306 ssl|JS> cluster.setPrimaryInstance("db1:3306");
Setting instance 'db1:3306' as the primary instance of cluster 'my_innodb_cluster'...

Instance 'db2:3306' was switched from PRIMARY to SECONDARY.
Instance 'db3:3306' remains SECONDARY.
Instance 'db1:3306' was switched from SECONDARY to PRIMARY.

WARNING: The cluster internal session is not the primary member anymore. For cluster management operations please obtain a fresh cluster handle using <Dba>.getCluster().

The instance 'db1:3306' was successfully elected as primary.

Kami baru saja mempromosikan db1 sebagai komponen utama baru, menggantikan db2 sementara db3 tetap sebagai simpul sekunder.

Mematikan Cluster

Cara terbaik untuk mematikan cluster secara anggun dengan menghentikan layanan MySQL Router terlebih dahulu (jika sedang berjalan) di server aplikasi:

$ myrouter/stop.sh

Langkah di atas memberikan perlindungan cluster terhadap penulisan yang tidak disengaja oleh aplikasi. Kemudian shutdown satu node database pada satu waktu menggunakan perintah stop MySQL standar, atau lakukan shutdown sistem sesuai keinginan:

$ systemctl stop mysql

Memulai Cluster Setelah Shutdown

Jika cluster Anda mengalami pemadaman total atau Anda ingin memulai cluster setelah shutdown bersih, Anda dapat memastikannya dikonfigurasi ulang dengan benar menggunakan fungsi dba.rebootClusterFromCompleteOutage(). Ini hanya membawa cluster kembali ONLINE ketika semua anggota OFFLINE. Jika cluster telah benar-benar berhenti, instance harus dimulai dan baru setelah itu cluster dapat dimulai.

Jadi, pastikan semua server MySQL dimulai dan dijalankan. Pada setiap node database, lihat apakah proses mysqld sedang berjalan:

$ ps -ef | grep -i mysql

Kemudian, pilih satu server database untuk menjadi node utama dan hubungkan melalui MySQL shell:

MySQL|JS> shell.connect("[email protected]:3306");

Jalankan perintah berikut dari host tersebut untuk memulainya:

MySQL|db1:3306 ssl|JS> cluster = dba.rebootClusterFromCompleteOutage()

Anda akan dihadapkan dengan pertanyaan-pertanyaan berikut:

Setelah hal di atas selesai, Anda dapat memverifikasi status cluster:

MySQL|db1:3306 ssl|JS> cluster.status()

Pada titik ini, db1 adalah simpul utama dan penulis. Sisanya akan menjadi anggota sekunder. Jika Anda ingin memulai cluster dengan db2 atau db3 sebagai yang utama, Anda dapat menggunakan fungsi shell.connect() untuk terhubung ke node yang sesuai dan melakukan rebootClusterFromCompleteOutage() dari node tertentu.

Anda kemudian dapat memulai layanan MySQL Router (jika belum dimulai) dan membiarkan aplikasi terhubung ke cluster lagi.

Mengatur Opsi Anggota dan Cluster

Untuk mendapatkan opsi di seluruh cluster, cukup jalankan:

MySQL|db1:3306 ssl|JS> cluster.options()

Di atas akan mencantumkan opsi global untuk kumpulan replika dan juga opsi individual per anggota dalam kluster. Fungsi ini mengubah opsi konfigurasi Cluster InnoDB di semua anggota cluster. Opsi yang didukung adalah:

  • clusterName:nilai string untuk menentukan nama cluster.
  • exitStateAction:nilai string yang menunjukkan tindakan status keluar replikasi grup.
  • memberWeight:nilai integer dengan bobot persentase untuk pemilihan primer otomatis saat failover.
  • failoverConsistency:nilai string yang menunjukkan jaminan konsistensi yang disediakan cluster.
  • consistency: nilai string yang menunjukkan jaminan konsistensi yang diberikan cluster.
  • expelTimeout:nilai integer untuk menentukan periode waktu dalam detik di mana anggota cluster harus menunggu anggota yang tidak merespons sebelum mengeluarkannya dari cluster.
  • autoRejoinTries:nilai integer untuk menentukan berapa kali sebuah instance akan mencoba bergabung kembali dengan cluster setelah dikeluarkan.
  • disableClone:​​nilai boolean yang digunakan untuk menonaktifkan penggunaan kloning pada cluster.

Serupa dengan fungsi lainnya, output dapat difilter dalam struktur peta. Perintah berikut hanya akan mencantumkan opsi untuk db2:

MySQL|db1:3306 ssl|JS> cluster.options().defaultReplicaSet.topology["db2:3306"]

Anda juga bisa mendapatkan daftar di atas dengan menggunakan fungsi help():

MySQL|db1:3306 ssl|JS> cluster.help("setOption")

Perintah berikut menunjukkan contoh untuk menyetel opsi yang disebut memberWeight ke 60 (dari 50) pada semua anggota:

MySQL|db1:3306 ssl|JS> cluster.setOption("memberWeight", 60)
Setting the value of 'memberWeight' to '60' in all ReplicaSet members ...

Successfully set the value of 'memberWeight' to '60' in the 'default' ReplicaSet.

Kami juga dapat melakukan manajemen konfigurasi secara otomatis melalui MySQL Shell dengan menggunakan fungsi setInstanceOption() dan meneruskan host database, nama opsi dan nilai yang sesuai:

MySQL|db1:3306 ssl|JS> cluster = dba.getCluster()
MySQL|db1:3306 ssl|JS> cluster.setInstanceOption("db1:3306", "memberWeight", 90)

Opsi yang didukung adalah:

  • exitStateAction: nilai string yang menunjukkan tindakan status keluar replikasi grup.
  • memberWeight:nilai integer dengan bobot persentase untuk pemilihan primer otomatis saat failover.
  • autoRejoinTries:nilai integer untuk menentukan berapa kali sebuah instance akan mencoba bergabung kembali dengan cluster setelah dikeluarkan.
  • memberi label pengidentifikasi string dari instance.

Beralih ke Mode Multi-Utama/Tunggal-Utama

Secara default, InnoDB Cluster dikonfigurasi dengan single-primary, hanya satu anggota yang mampu melakukan baca dan tulis pada satu waktu tertentu. Ini adalah cara paling aman dan direkomendasikan untuk menjalankan cluster dan cocok untuk sebagian besar beban kerja.

Namun, jika logika aplikasi dapat menangani penulisan terdistribusi, mungkin ide yang baik untuk beralih ke mode multi-primer, di mana semua anggota dalam cluster dapat memproses membaca dan menulis pada saat yang sama. Untuk beralih dari mode single-primary ke multi-primer, cukup gunakan fungsi switchToMultiPrimaryMode():

MySQL|db1:3306 ssl|JS> cluster.switchToMultiPrimaryMode()
Switching cluster 'my_innodb_cluster' to Multi-Primary mode...

Instance 'db2:3306' was switched from SECONDARY to PRIMARY.
Instance 'db3:3306' was switched from SECONDARY to PRIMARY.
Instance 'db1:3306' remains PRIMARY.

The cluster successfully switched to Multi-Primary mode.

Verifikasi dengan:

MySQL|db1:3306 ssl|JS> cluster.status()
{
    "clusterName": "my_innodb_cluster",
    "defaultReplicaSet": {
        "name": "default",
        "ssl": "REQUIRED",
        "status": "OK",
        "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
        "topology": {
            "db1:3306": {
                "address": "db1:3306",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            },
            "db2:3306": {
                "address": "db2:3306",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            },
            "db3:3306": {
                "address": "db3:3306",
                "mode": "R/W",
                "readReplicas": {},
                "replicationLag": null,
                "role": "HA",
                "status": "ONLINE",
                "version": "8.0.18"
            }
        },
        "topologyMode": "Multi-Primary"
    },
    "groupInformationSourceMember": "db1:3306"
}

Dalam mode multi-primer, semua node adalah primer dan dapat memproses baca dan tulis. Saat mengirim koneksi baru melalui MySQL Router pada port single-writer (6446), koneksi hanya akan dikirim ke satu node, seperti dalam contoh ini, db1:

(app-server)$ for i in {1..3}; do mysql -usbtest -p -h192.168.10.40 -P6446 -e 'select @@hostname, @@read_only, @@super_read_only'; done

+------------+-------------+-------------------+
| @@hostname | @@read_only | @@super_read_only |
+------------+-------------+-------------------+
| db1        | 0           | 0                 |
+------------+-------------+-------------------+

+------------+-------------+-------------------+
| @@hostname | @@read_only | @@super_read_only |
+------------+-------------+-------------------+
| db1        | 0           | 0                 |
+------------+-------------+-------------------+

+------------+-------------+-------------------+
| @@hostname | @@read_only | @@super_read_only |
+------------+-------------+-------------------+
| db1        | 0           | 0                 |
+------------+-------------+-------------------+

Jika aplikasi terhubung ke port multi-penulis (6447), koneksi akan diseimbangkan beban melalui algoritma round robin ke semua anggota:

(app-server)$ for i in {1..3}; do mysql -usbtest -ppassword -h192.168.10.40 -P6447 -e 'select @@hostname, @@read_only, @@super_read_only'; done

+------------+-------------+-------------------+
| @@hostname | @@read_only | @@super_read_only |
+------------+-------------+-------------------+
| db2        | 0           | 0                 |
+------------+-------------+-------------------+

+------------+-------------+-------------------+
| @@hostname | @@read_only | @@super_read_only |
+------------+-------------+-------------------+
| db3        | 0           | 0                 |
+------------+-------------+-------------------+

+------------+-------------+-------------------+
| @@hostname | @@read_only | @@super_read_only |
+------------+-------------+-------------------+
| db1        | 0           | 0                 |
+------------+-------------+-------------------+

Seperti yang Anda lihat dari output di atas, semua node mampu memproses membaca dan menulis dengan read_only =OFF. Anda dapat mendistribusikan penulisan aman ke semua anggota dengan menyambungkan ke port multi-penulis (6447), dan mengirim penulisan yang bentrok atau berat ke port penulis tunggal (6446).

Untuk beralih kembali ke mode single-primary, gunakan fungsi switchToSinglePrimaryMode() dan tentukan satu anggota sebagai node utama. Dalam contoh ini, kami memilih db1:

MySQL|db1:3306 ssl|JS> cluster.switchToSinglePrimaryMode("db1:3306");

Switching cluster 'my_innodb_cluster' to Single-Primary mode...

Instance 'db2:3306' was switched from PRIMARY to SECONDARY.
Instance 'db3:3306' was switched from PRIMARY to SECONDARY.
Instance 'db1:3306' remains PRIMARY.

WARNING: Existing connections that expected a R/W connection must be disconnected, i.e. instances that became SECONDARY.

The cluster successfully switched to Single-Primary mode.

Pada titik ini, db1 sekarang menjadi node utama yang dikonfigurasi dengan read-only dinonaktifkan dan sisanya akan dikonfigurasi sebagai sekunder dengan read-only diaktifkan.

Operasi Penskalaan Cluster InnoDB MySQL

Scaling Up (Menambahkan Node DB Baru)

Saat menambahkan instance baru, sebuah node harus disediakan terlebih dahulu sebelum diizinkan untuk berpartisipasi dengan grup replikasi. Proses penyediaan akan ditangani secara otomatis oleh MySQL. Selain itu, Anda juga dapat memeriksa status instance terlebih dahulu apakah node tersebut valid untuk bergabung dengan cluster dengan menggunakan fungsi checkInstanceState() seperti yang dijelaskan sebelumnya.

Untuk menambahkan node DB baru, gunakan fungsi addInstances() dan tentukan host:

MySQL|db1:3306 ssl|JS> cluster.addInstance("db3:3306")

Berikut ini yang akan Anda dapatkan saat menambahkan instance baru:

Verifikasi ukuran cluster baru dengan:

MySQL|db1:3306 ssl|JS> cluster.status() //or cluster.describe()

MySQL Router akan secara otomatis memasukkan node yang ditambahkan, db3 ke dalam set load balancing.

Menurunkan (Menghapus Node)

Untuk menghapus node, sambungkan ke salah satu node DB kecuali node yang akan kita hapus dan gunakan fungsi removeInstance() dengan nama instance database:

MySQL|db1:3306 ssl|JS> shell.connect("[email protected]:3306");
MySQL|db1:3306 ssl|JS> cluster = dba.getCluster()
MySQL|db1:3306 ssl|JS> cluster.removeInstance("db3:3306")

Berikut adalah apa yang akan Anda dapatkan saat menghapus sebuah instance:

Verifikasi ukuran cluster baru dengan:

MySQL|db1:3306 ssl|JS> cluster.status() //or cluster.describe()

MySQL Router akan secara otomatis mengecualikan node yang dihapus, db3 dari set load balancing.

Menambahkan Budak Replikasi Baru

Kami dapat menskalakan Cluster InnoDB dengan replikasi slave replikasi asinkron dari salah satu node cluster. Seorang budak secara longgar digabungkan ke cluster, dan akan mampu menangani beban berat tanpa mempengaruhi kinerja cluster. Slave juga dapat menjadi salinan langsung dari database untuk tujuan pemulihan bencana. Dalam mode multi-primer, Anda dapat menggunakan slave sebagai prosesor khusus baca-saja MySQL untuk mengurangi beban kerja pembacaan, melakukan operasi analitik, atau sebagai server pencadangan khusus.

Di server budak, unduh paket konfigurasi APT terbaru, instal (pilih MySQL 8.0 di wizard konfigurasi), instal kunci APT, perbarui repolist dan instal server MySQL.

$ wget https://repo.mysql.com/apt/ubuntu/pool/mysql-apt-config/m/mysql-apt-config/mysql-apt-config_0.8.14-1_all.deb
$ dpkg -i mysql-apt-config_0.8.14-1_all.deb
$ apt-key adv --recv-keys --keyserver ha.pool.sks-keyservers.net 5072E1F5
$ apt-get update
$ apt-get -y install mysql-server mysql-shell

Ubah file konfigurasi MySQL untuk mempersiapkan server untuk replikasi slave. Buka file konfigurasi melalui editor teks:

$ vim /etc/mysql/mysql.conf.d/mysqld.cnf

Dan tambahkan baris berikut:

server-id = 1044 # must be unique across all nodes
gtid-mode = ON
enforce-gtid-consistency = ON
log-slave-updates = OFF
read-only = ON
super-read-only = ON
expire-logs-days = 7

Mulai ulang server MySQL pada slave untuk menerapkan perubahan:

$ systemctl restart mysql

Di salah satu server InnoDB Cluster (kami memilih db3), buat pengguna slave replikasi dan diikuti dengan dump MySQL lengkap:

$ mysql -uroot -p
mysql> CREATE USER 'repl_user'@'192.168.0.44' IDENTIFIED BY 'password';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl_user'@'192.168.0.44';
mysql> exit
$ mysqldump -uroot -p --single-transaction --master-data=1 --all-databases --triggers --routines --events > dump.sql

Transfer file dump dari db3 ke slave:

$ scp dump.sql [email protected]:~

Dan lakukan pemulihan pada budak:

$ mysql -uroot -p < dump.sql

Dengan master-data=1, file dump MySQL kami akan secara otomatis mengonfigurasi nilai GTID yang dieksekusi dan dibersihkan. Kami dapat memverifikasinya dengan pernyataan berikut di server budak setelah pemulihan:

$ mysql -uroot -p
mysql> show global variables like '%gtid_%';
+----------------------------------+----------------------------------------------+
| Variable_name                    | Value                                        |
+----------------------------------+----------------------------------------------+
| binlog_gtid_simple_recovery      | ON                                           |
| enforce_gtid_consistency         | ON                                           |
| gtid_executed                    | d4790339-0694-11ea-8fd5-02f67042125d:1-45886 |
| gtid_executed_compression_period | 1000                                         |
| gtid_mode                        | ON                                           |
| gtid_owned                       |                                              |
| gtid_purged                      | d4790339-0694-11ea-8fd5-02f67042125d:1-45886 |
+----------------------------------+----------------------------------------------+

Kelihatan bagus. Kami kemudian dapat mengonfigurasi tautan replikasi dan memulai utas replikasi pada slave:

mysql> CHANGE MASTER TO MASTER_HOST = '192.168.10.43', MASTER_USER = 'repl_user', MASTER_PASSWORD = 'password', MASTER_AUTO_POSITION = 1;
mysql> START SLAVE;

Verifikasi status replikasi dan pastikan status berikut mengembalikan 'Ya':

mysql> show slave status\G
...
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
...

Pada titik ini, arsitektur kita sekarang terlihat seperti ini:

Masalah Umum dengan Cluster MySQL InnoDB

Kelelahan Memori

Saat menggunakan MySQL Shell dengan MySQL 8.0, kami terus-menerus mendapatkan kesalahan berikut saat instance dikonfigurasi dengan 1GB RAM:

Can't create a new thread (errno 11); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug (MySQL Error 1135)

Memutakhirkan RAM setiap host ke 2GB RAM memecahkan masalah. Rupanya, komponen MySQL 8.0 membutuhkan lebih banyak RAM untuk beroperasi secara efisien.

Hubungan Hilang ke Server MySQL

In case the primary node goes down, you would probably see the "lost connection to MySQL server error" when trying to query something on the current session:

MySQL|db1:3306 ssl|JS> cluster.status()
Cluster.status: Lost connection to MySQL server during query (MySQL Error 2013)

MySQL|db1:3306 ssl|JS> cluster.status()
Cluster.status: MySQL server has gone away (MySQL Error 2006)

The solution is to re-declare the object once more:

MySQL|db1:3306 ssl|JS> cluster = dba.getCluster()
<Cluster:my_innodb_cluster>
MySQL|db1:3306 ssl|JS> cluster.status()

At this point, it will connect to the newly promoted primary node to retrieve the cluster status.

Node Eviction and Expelled

In an event where communication between nodes is interrupted, the problematic node will be evicted from the cluster without any delay, which is not good if you are running on a non-stable network. This is what it looks like on db2 (the problematic node):

2019-11-14T07:07:59.344888Z 0 [ERROR] [MY-011505] [Repl] Plugin group_replication reported: 'Member was expelled from the group due to network failures, changing member status to ERROR.'
2019-11-14T07:07:59.371966Z 0 [ERROR] [MY-011712] [Repl] Plugin group_replication reported: 'The server was automatically set into read only mode after an error was detected.'

Meanwhile from db1, it saw db2 was offline:

2019-11-14T07:07:44.086021Z 0 [Warning] [MY-011493] [Repl] Plugin group_replication reported: 'Member with address db2:3306 has become unreachable.'
2019-11-14T07:07:46.087216Z 0 [Warning] [MY-011499] [Repl] Plugin group_replication reported: 'Members removed from the group: db2:3306'

To tolerate a bit of delay on node eviction, we can set a higher timeout value before a node is being expelled from the group. The default value is 0, which means expel immediately. Use the setOption() function to set the expelTimeout value:

Thanks to Frédéric Descamps from Oracle who pointed this out:

Instead of relying on expelTimeout, it's recommended to set the autoRejoinTries option instead. The value represents the number of times an instance will attempt to rejoin the cluster after being expelled. A good number to start is 3, which means, the expelled member will try to rejoin the cluster for 3 times, which after an unsuccessful auto-rejoin attempt, the member waits 5 minutes before the next try.

To set this value cluster-wide, we can use the setOption() function:

MySQL|db1:3306 ssl|JS> cluster.setOption("autoRejoinTries", 3)
WARNING: Each cluster member will only proceed according to its exitStateAction if auto-rejoin fails (i.e. all retry attempts are exhausted).

Setting the value of 'autoRejoinTries' to '3' in all ReplicaSet members ...

Successfully set the value of 'autoRejoinTries' to '3' in the 'default' ReplicaSet.

Kesimpulan

For MySQL InnoDB Cluster, most of the management and monitoring operations can be performed directly via MySQL Shell (only available from MySQL 5.7.21 and later).


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Cara Menemukan Nama Kendala di MySQL

  2. Upgrade Skema Online di MySQL Galera Cluster Menggunakan Metode RSU

  3. LAST_DAY() Contoh – MySQL

  4. Apa yang Harus Dipantau di MySQL 8.0

  5. JSON_UNQUOTE() – Hapus Kutipan dari Dokumen JSON di MySQL