Il cluster MySQL InnoDB è costituito da 3 componenti:
- MySQL Group Replication (un gruppo di server di database che si replicano tra loro con tolleranza agli errori).
- Router MySQL (interroga il router sui nodi del database integri)
- Shell MySQL (helper, client, strumento di configurazione)
Nella prima parte di questa procedura dettagliata, implementeremo un cluster MySQL InnoDB. Sono disponibili numerosi tutorial pratici online, ma questa procedura dettagliata copre tutti i passaggi/comandi necessari per installare ed eseguire il cluster in un'unica posizione. Nella seconda parte di questo post del blog tratteremo le operazioni di monitoraggio, gestione e ridimensionamento, nonché alcuni trucchi quando si tratta di MySQL InnoDB Cluster.
Il diagramma seguente illustra la nostra architettura post-distribuzione:
Distribuiremo un totale di 4 nodi; Una replica del gruppo MySQL a tre nodi e un nodo router MySQL si trovano insieme all'interno del server delle applicazioni. Tutti i server funzionano su Ubuntu 18.04 Bionic.
Installazione di MySQL
I seguenti passaggi devono essere eseguiti su tutti i nodi del database db1, db2 e db3.
In primo luogo, dobbiamo fare un po' di mappatura dell'host. Questo è fondamentale se si desidera utilizzare hostname come identificatore host in InnoDB Cluster e questo è il modo consigliato per farlo. Mappa tutti gli host come segue all'interno di /etc/hosts:
$ vi /etc/hosts
192.168.10.40 router apps
192.168.10.41 db1 db1.local
192.168.10.42 db2 db2.local
192.168.10.43 db3 db3.local
127.0.0.1 localhost localhost.localdomain
Arresta e disabilita AppArmor:
$ service apparmor stop
$ service apparmor teardown
$ systemctl disable apparmor
Scarica l'ultimo repository di configurazione APT dal sito Web del repository di MySQL Ubuntu all'indirizzo https://repo.mysql.com/apt/ubuntu/pool/mysql-apt-config/m/mysql-apt-config/ . Al momento in cui scrivo, l'ultimo è datato 15-Oct-2019 che è mysql-apt-config_0.8.14-1_all.deb:
$ wget https://repo.mysql.com/apt/ubuntu/pool/mysql-apt-config/m/mysql-apt-config/mysql-apt-config_0.8.14-1_all.deb
Installa il pacchetto e configuralo per "mysql-8.0":
$ dpkg -i mysql-apt-config_0.8.14-1_all.deb
Installa la chiave GPG:
$ apt-key adv --recv-keys --keyserver ha.pool.sks-keyservers.net 5072E1F5
Aggiorna il riposizionamento:
$ apt-get update
Installa Python e segui il server MySQL e la shell MySQL:
$ apt-get -y install mysql-server mysql-shell
Ti verranno presentate le seguenti procedure guidate di configurazione:
- Imposta una password di root:specifica una password complessa per l'utente root di MySQL.
- Imposta il metodo di autenticazione:scegli "Usa metodo di autenticazione legacy (mantieni la compatibilità con MySQL 5.x)"
MySQL dovrebbe essere stato installato a questo punto. Verifica con:
$ systemctl status mysql
Assicurati di ottenere uno stato "attivo (in esecuzione)".
Preparazione del server per il cluster InnoDB
I seguenti passaggi devono essere eseguiti su tutti i nodi del database db1, db2 e db3.
Configura il server MySQL per supportare la replica di gruppo. Il modo più semplice e consigliato per farlo è utilizzare la nuova MySQL Shell:
$ mysqlsh
Autenticarsi come utente root locale e seguire la procedura guidata di configurazione di conseguenza, come mostrato nell'esempio seguente:
MySQL JS > dba.configureLocalInstance("[email protected]:3306");
Una volta autenticato, dovresti ricevere una serie di domande come le seguenti:
Risposte a queste domande con le seguenti risposte:
- Scelta 2:crea un nuovo account amministratore per il cluster InnoDB con sovvenzioni minime richieste
- Nome account:[email protected]%
- Password:mys3cret&&
- Conferma password:mys3cret&&
- Vuoi eseguire le modifiche alla configurazione richieste?:y
- Vuoi riavviare l'istanza dopo averla configurata?:y
Non dimenticare di ripetere quanto sopra su tutti i nodi del database. A questo punto, il demone MySQL dovrebbe essere in ascolto di tutti gli indirizzi IP e la replica di gruppo è abilitata. Possiamo ora procedere alla creazione del cluster.
Creazione del cluster
Ora siamo pronti per creare un cluster. Su db1, connettiti come amministratore del cluster da MySQL Shell:
MySQL|JS> shell.connect('[email protected]:3306');
Creating a session to '[email protected]:3306'
Please provide the password for '[email protected]:3306': ***********
Save password for '[email protected]:3306'? [Y]es/[N]o/Ne[v]er (default No): Y
Fetching schema names for autocompletion... Press ^C to stop.
Your MySQL connection id is 9
Server version: 8.0.18 MySQL Community Server - GPL
No default schema selected; type \use <schema> to set one.
<ClassicSession:[email protected]:3306>
Dovresti essere connesso come [email protected] (puoi dirlo guardando la stringa del prompt prima di '>'). Ora possiamo creare un nuovo cluster:
MySQL|db1:3306 ssl|JS> cluster = dba.createCluster('my_innodb_cluster');
Controlla lo stato del cluster:
MySQL|db1:3306 ssl|JS> cluster.status()
{
"clusterName": "my_innodb_cluster",
"defaultReplicaSet": {
"name": "default",
"primary": "db1:3306",
"ssl": "REQUIRED",
"status": "OK_NO_TOLERANCE",
"statusText": "Cluster is NOT tolerant to any failures.",
"topology": {
"db1:3306": {
"address": "db1:3306",
"mode": "R/W",
"readReplicas": {},
"replicationLag": null,
"role": "HA",
"status": "ONLINE",
"version": "8.0.18"
}
},
"topologyMode": "Single-Primary"
},
"groupInformationSourceMember": "db1:3306"
}
A questo punto, solo db1 fa parte del cluster. La modalità di topologia predefinita è Single-Primary, simile a un concetto di set di repliche in cui un solo nodo alla volta è un writer. I nodi rimanenti nel cluster saranno lettori.
Prestare attenzione allo stato del cluster che dice OK_NO_TOLERANCE e ulteriori spiegazioni nella chiave statusText. In un concetto di set di repliche, un nodo non fornirà alcuna tolleranza agli errori. È necessario un minimo di 3 nodi per automatizzare il failover del nodo primario. Lo esamineremo più avanti.
Ora aggiungi il secondo nodo, db2 e accetta il metodo di ripristino predefinito, "Clone":
MySQL|db1:3306 ssl|JS> cluster.addInstance('[email protected]:3306');
Lo screenshot seguente mostra l'avanzamento dell'inizializzazione di db2 dopo aver eseguito il comando precedente. L'operazione di sincronizzazione viene eseguita automaticamente da MySQL:
Controlla lo stato del cluster e del db2:
MySQL|db1:3306 ssl|JS> cluster.status()
{
"clusterName": "my_innodb_cluster",
"defaultReplicaSet": {
"name": "default",
"primary": "db1:3306",
"ssl": "REQUIRED",
"status": "OK_NO_TOLERANCE",
"statusText": "Cluster is NOT tolerant to any failures.",
"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": null,
"role": "HA",
"status": "ONLINE",
"version": "8.0.18"
}
},
"topologyMode": "Single-Primary"
},
"groupInformationSourceMember": "db1:3306"
}
A questo punto, abbiamo due nodi nel cluster, db1 e db2. Lo stato mostra ancora OK_NO_TOLERANCE con ulteriori spiegazioni sotto il valore statusText. Come indicato sopra, MySQL Group Replication richiede almeno 3 nodi in un cluster per la tolleranza agli errori. Ecco perché dobbiamo aggiungere il terzo nodo come mostrato di seguito.
Aggiungi l'ultimo nodo, db3 e accetta il metodo di ripristino predefinito, "Clone" simile a db2:
MySQL|db1:3306 ssl|JS> cluster.addInstance('[email protected]:3306');
Lo screenshot seguente mostra l'avanzamento dell'inizializzazione di db3 dopo aver eseguito il comando precedente. L'operazione di sincronizzazione viene eseguita automaticamente da MySQL:
Controlla lo stato del cluster e del db3:
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": 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": "db1:3306"
}
Ora il cluster ha un bell'aspetto, lo stato è OK e il cluster può tollerare fino a un nodo di errore alla volta. Il nodo primario è db1 dove mostra "primary":"db1:3306" e "mode":"R/W", mentre gli altri nodi sono nello stato "R/O". Se controlli i valori read_only e super_read_only sui nodi RO, entrambi vengono visualizzati come true.
La nostra distribuzione di MySQL Group Replication è ora completa e sincronizzata.
Distribuzione del router
Sul server dell'app su cui eseguiremo la nostra applicazione, assicurati che la mappatura dell'host sia corretta:
$ vim /etc/hosts
192.168.10.40 router apps
192.168.10.41 db1 db1.local
192.168.10.42 db2 db2.local
192.168.10.43 db3 db3.local
127.0.0.1 localhost localhost.localdomain
Arresta e disabilita AppArmor:
$ service apparmor stop
$ service apparmor teardown
$ systemctl disable apparmor
Quindi installa il pacchetto del repository MySQL, in modo simile a quello che abbiamo fatto durante l'installazione del database:
$ 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
Aggiungi chiave GPG:
$ apt-key adv --recv-keys --keyserver ha.pool.sks-keyservers.net 5072E1F5
Aggiorna l'elenco dei repository:
$ apt-get update
Installa router e client MySQL:
$ apt-get -y install mysql-router mysql-client
MySQL Router è ora installato in /usr/bin/mysqlrouter. Il router MySQL fornisce un flag di bootstrap per configurare automaticamente il funzionamento del router con un cluster MySQL InnoDB. Quello che dobbiamo fare è specificare l'URI della stringa in uno dei nodi del database come utente amministratore del cluster InnoDB (clusteradmin).
Per semplificare la configurazione, eseguiremo il processo mysqlrouter come utente root:
$ mysqlrouter --bootstrap [email protected]:3306 --directory myrouter --user=root
Ecco cosa dovremmo ottenere dopo aver specificato la password per l'utente clusteradmin:
Il comando bootstrap ci aiuterà a generare il file di configurazione del router in /root/myrouter/mysqlrouter.conf. Ora possiamo avviare il demone mysqlrouter con il seguente comando dalla directory corrente:
$ myrouter/start.sh
Verifica se le porte previste sono in ascolto correttamente:
$ netstat -tulpn | grep mysql
tcp 0 0 0.0.0.0:6446 0.0.0.0:* LISTEN 14726/mysqlrouter
tcp 0 0 0.0.0.0:6447 0.0.0.0:* LISTEN 14726/mysqlrouter
tcp 0 0 0.0.0.0:64470 0.0.0.0:* LISTEN 14726/mysqlrouter
tcp 0 0 0.0.0.0:64460 0.0.0.0:* LISTEN 14726/mysqlrouter
Ora la nostra applicazione può utilizzare la porta 6446 per la lettura/scrittura e la 6447 per le connessioni MySQL di sola lettura.
Connessione al Cluster
Creiamo un utente del database sul nodo master. Su db1, connettiti al server MySQL tramite la shell MySQL:
$ mysqlsh [email protected]:3306
Passa dalla modalità Javascript alla modalità SQL:
MySQL|localhost:3306 ssl|JS> \sql
Switching to SQL mode... Commands end with ;
Crea un database:
MySQL|localhost:3306 ssl|SQL> CREATE DATABASE sbtest;
Crea un utente del database:
MySQL|localhost:3306 ssl|SQL> CREATE USER [email protected]'%' IDENTIFIED BY 'password';
Concedi all'utente il database:
MySQL|localhost:3306 ssl|SQL> GRANT ALL PRIVILEGES ON sbtest.* TO [email protected]'%';
Ora il nostro database e l'utente sono pronti. Installiamo sysbench per generare alcuni dati di test. Sul server dell'app, fai:
$ apt -y install sysbench mysql-client
Ora possiamo testare sul server dell'app per connetterci al server MySQL tramite il router MySQL. Per la connessione in scrittura, collegarsi alla porta 6446 dell'host router:
$ mysql -usbtest -p -h192.168.10.40 -P6446 -e 'select user(), @@hostname, @@read_only, @@super_read_only'
+---------------+------------+-------------+-------------------+
| user() | @@hostname | @@read_only | @@super_read_only |
+---------------+------------+-------------+-------------------+
| [email protected] | db1 | 0 | 0 |
+---------------+------------+-------------+-------------------+
Per una connessione di sola lettura, connettiti alla porta 6447 dell'host router:
$ mysql -usbtest -p -h192.168.10.40 -P6447 -e 'select user(), @@hostname, @@read_only, @@super_read_only'
+---------------+------------+-------------+-------------------+
| user() | @@hostname | @@read_only | @@super_read_only |
+---------------+------------+-------------+-------------------+
| [email protected] | db3 | 1 | 1 |
+---------------+------------+-------------+-------------------+
Sembra buono. Ora possiamo generare alcuni dati di test con sysbench. Sul server delle app, genera 20 tabelle con 100.000 righe per tabella collegandoti alla porta 6446 del server delle app:
$ sysbench \
/usr/share/sysbench/oltp_common.lua \
--db-driver=mysql \
--mysql-user=sbtest \
--mysql-db=sbtest \
--mysql-password=password \
--mysql-port=6446 \
--mysql-host=192.168.10.40 \
--tables=20 \
--table-size=100000 \
prepare
Per eseguire un semplice test di lettura-scrittura sulla porta 6446 per 300 secondi, esegui:
$ sysbench \
/usr/share/sysbench/oltp_read_write.lua \
--report-interval=2 \
--threads=8 \
--time=300 \
--db-driver=mysql \
--mysql-host=192.168.10.40 \
--mysql-port=6446 \
--mysql-user=sbtest \
--mysql-db=sbtest \
--mysql-password=password \
--tables=20 \
--table-size=100000 \
run
Per carichi di lavoro di sola lettura, possiamo inviare la connessione MySQL alla porta 6447:
$ sysbench \
/usr/share/sysbench/oltp_read_only.lua \
--report-interval=2 \
--threads=1 \
--time=300 \
--db-driver=mysql \
--mysql-host=192.168.10.40 \
--mysql-port=6447 \
--mysql-user=sbtest \
--mysql-db=sbtest \
--mysql-password=password \
--tables=20 \
--table-size=100000 \
run
Conclusione
Ecco fatto. La nostra configurazione del cluster MySQL InnoDB è ora completa con tutti i suoi componenti in esecuzione e testati. Nella seconda parte, esamineremo le operazioni di gestione, monitoraggio e ridimensionamento del cluster, nonché le soluzioni a una serie di problemi comuni quando si ha a che fare con MySQL InnoDB Cluster. Resta sintonizzato!