MySQL InnoDB Cluster består af 3 komponenter:
- MySQL Group Replication (en gruppe af databaseservere, som replikerer til hinanden med fejltolerance).
- MySQL-router (forespørgselsrouter til de sunde databasenoder)
- MySQL Shell (hjælper, klient, konfigurationsværktøj)
I den første del af denne gennemgang skal vi implementere en MySQL InnoDB-klynge. Der er en række praktiske selvstudier tilgængelige online, men denne gennemgang dækker alle de nødvendige trin/kommandoer til at installere og køre klyngen på ét sted. Vi vil dække overvågning, styring og skaleringsoperationer samt nogle gotchas, når vi beskæftiger os med MySQL InnoDB Cluster i anden del af dette blogindlæg.
Følgende diagram illustrerer vores post-deployment-arkitektur:
Vi vil implementere i alt 4 noder; En MySQL-gruppereplikering med tre knudepunkter og en MySQL-routerknude, der er placeret i applikationsserveren. Alle servere kører på Ubuntu 18.04 Bionic.
Installation af MySQL
Følgende trin skal udføres på alle databasenoder db1, db2 og db3.
For det første skal vi lave nogle værtsmapping. Dette er afgørende, hvis du vil bruge værtsnavnet som værtsidentifikator i InnoDB Cluster, og dette er den anbefalede måde at gøre det på. Kortlæg alle værter som følgende inde i /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
Stop og deaktiver AppArmor:
$ service apparmor stop
$ service apparmor teardown
$ systemctl disable apparmor
Download det seneste APT config repository fra MySQL Ubuntu repository-webstedet på https://repo.mysql.com/apt/ubuntu/pool/mysql-apt-config/m/mysql-apt-config/ . I skrivende stund er den seneste dateret 15. oktober 2019, som er 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
Installer pakken og konfigurer den til "mysql-8.0":
$ dpkg -i mysql-apt-config_0.8.14-1_all.deb
Installer GPG-nøglen:
$ apt-key adv --recv-keys --keyserver ha.pool.sks-keyservers.net 5072E1F5
Opdater repolisten:
$ apt-get update
Installer Python og efterfulgt af MySQL-server og MySQL-shell:
$ apt-get -y install mysql-server mysql-shell
Du vil blive præsenteret for følgende konfigurationsguider:
- Indstil en root-adgangskode - Angiv en stærk adgangskode for MySQL-root-brugeren.
- Indstil godkendelsesmetoden - Vælg "Brug ældre godkendelsesmetode (bevar MySQL 5.x-kompatibilitet)"
MySQL skulle have været installeret på dette tidspunkt. Bekræft med:
$ systemctl status mysql
Sørg for, at du får en "aktiv (kører)"-tilstand.
Forberedelse af serveren til InnoDB Cluster
Følgende trin skal udføres på alle databasenoder db1, db2 og db3.
Konfigurer MySQL-serveren til at understøtte gruppereplikering. Den nemmeste og anbefalede måde at gøre dette på er at bruge den nye MySQL Shell:
$ mysqlsh
Autentificer som den lokale root-bruger og følg konfigurationsguiden i overensstemmelse hermed som vist i eksemplet nedenfor:
MySQL JS > dba.configureLocalInstance("[email protected]:3306");
Når du er blevet godkendt, bør du få en række spørgsmål som følgende:
Svar på disse spørgsmål med følgende svar:
- Vælg 2 - Opret en ny administratorkonto til InnoDB-klyngen med minimale nødvendige tilskud
- Kontonavn:[email protected]%
- Adgangskode:mys3cret&&
- Bekræft adgangskode:mys3cret&&
- Vil du udføre de nødvendige konfigurationsændringer?:y
- Vil du genstarte forekomsten efter at have konfigureret den?:y
Glem ikke at gentage ovenstående på alle databasenoder. På dette tidspunkt bør MySQL-dæmonen lytte til alle IP-adresser, og gruppereplikering er aktiveret. Vi kan nu fortsætte med at oprette klyngen.
Oprettelse af klyngen
Nu er vi klar til at skabe en klynge. På db1 skal du oprette forbindelse som klyngeadministrator fra 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>
Du skal være forbundet som [email protected] (du kan se det ved at se på promptstrengen før '>'). Vi kan nu oprette en ny klynge:
MySQL|db1:3306 ssl|JS> cluster = dba.createCluster('my_innodb_cluster');
Tjek klyngestatus:
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"
}
På dette tidspunkt er kun db1 en del af klyngen. Standardtopologitilstanden er Single-Primary, svarende til et replikasæt-koncept, hvor kun én node er en forfatter ad gangen. De resterende noder i klyngen vil være læsere.
Vær opmærksom på klyngestatus, som siger OK_NO_TOLERANCE, og yderligere forklaring under statusText-tasten. I et replikasæt-koncept vil én node ikke give nogen fejltolerance. Minimum 3 noder er påkrævet for at automatisere den primære node failover. Vi skal se nærmere på dette senere.
Tilføj nu den anden node, db2, og accepter standardgendannelsesmetoden, "Klon":
MySQL|db1:3306 ssl|JS> cluster.addInstance('[email protected]:3306');
Følgende skærmbillede viser initialiseringsforløbet for db2, efter at vi udførte kommandoen ovenfor. Synkroniseringsoperationen udføres automatisk af MySQL:
Tjek klyngen og db2-status:
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"
}
På dette tidspunkt har vi to noder i klyngen, db1 og db2. Status viser stadig OK_NO_TOLERANCE med yderligere forklaring under statusTekst-værdi. Som nævnt ovenfor kræver MySQL Group Replication mindst 3 noder i en klynge for fejltolerance. Det er derfor, vi skal tilføje den tredje node som vist næste.
Tilføj den sidste node, db3, og accepter standardgendannelsesmetoden, "Klon" svarende til db2:
MySQL|db1:3306 ssl|JS> cluster.addInstance('[email protected]:3306');
Følgende skærmbillede viser initialiseringsforløbet for db3, efter at vi udførte kommandoen ovenfor. Synkroniseringsoperationen udføres automatisk af MySQL:
Tjek klyngen og db3-status:
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"
}
Nu ser klyngen godt ud, hvor status er OK, og klyngen kan tolerere op til en fejlknude ad gangen. Den primære node er db1, hvor den viser "primary":"db1:3306" og "mode":"R/W", mens andre noder er i "R/O"-tilstand. Hvis du tjekker read_only og super_read_only værdierne på RO noder, vises begge som sande.
Vores MySQL Group Replication-implementering er nu færdig og synkroniseret.
Installation af routeren
På den app-server, som vi skal køre vores applikation, skal du sørge for, at værtsmappingen er korrekt:
$ 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
Stop og deaktiver AppArmor:
$ service apparmor stop
$ service apparmor teardown
$ systemctl disable apparmor
Installer derefter MySQL repository-pakken, svarende til hvad vi har gjort, da vi udførte databaseinstallation:
$ 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
Tilføj GPG-nøgle:
$ apt-key adv --recv-keys --keyserver ha.pool.sks-keyservers.net 5072E1F5
Opdater repo-listen:
$ apt-get update
Installer MySQL-router og klient:
$ apt-get -y install mysql-router mysql-client
MySQL Router er nu installeret under /usr/bin/mysqlrouter. MySQL-router giver et bootstrap-flag til automatisk at konfigurere routerdriften med en MySQL InnoDB-klynge. Det, vi skal gøre, er at specificere streng-URI'en til en af databaseknuderne som InnoDB cluster admin-brugeren (clusteradmin).
For at forenkle konfigurationen kører vi mysqlrouter-processen som root-bruger:
$ mysqlrouter --bootstrap [email protected]:3306 --directory myrouter --user=root
Her er, hvad vi skal få efter at have angivet adgangskoden til clusteradmin-brugeren:
Bootstrap-kommandoen vil hjælpe os med at generere routerkonfigurationsfilen på /root/myrouter/mysqlrouter.conf. Nu kan vi starte mysqlrouter-dæmonen med følgende kommando fra den aktuelle mappe:
$ myrouter/start.sh
Bekræft, om de forventede porte lytter korrekt:
$ 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
Nu kan vores applikation bruge port 6446 til læse/skrive og 6447 til skrivebeskyttede MySQL-forbindelser.
Opretter forbindelse til klyngen
Lad os oprette en databasebruger på masterknuden. På db1 skal du oprette forbindelse til MySQL-serveren via MySQL-shell:
$ mysqlsh [email protected]:3306
Skift fra Javascript-tilstand til SQL-tilstand:
MySQL|localhost:3306 ssl|JS> \sql
Switching to SQL mode... Commands end with ;
Opret en database:
MySQL|localhost:3306 ssl|SQL> CREATE DATABASE sbtest;
Opret en databasebruger:
MySQL|localhost:3306 ssl|SQL> CREATE USER [email protected]'%' IDENTIFIED BY 'password';
Giv brugeren til databasen:
MySQL|localhost:3306 ssl|SQL> GRANT ALL PRIVILEGES ON sbtest.* TO [email protected]'%';
Nu er vores database og bruger klar. Lad os installere sysbench for at generere nogle testdata. På appserveren skal du gøre:
$ apt -y install sysbench mysql-client
Nu kan vi teste på app-serveren for at oprette forbindelse til MySQL-serveren via MySQL-router. For skriveforbindelse skal du oprette forbindelse til port 6446 på routerværten:
$ 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 |
+---------------+------------+-------------+-------------------+
For skrivebeskyttet forbindelse skal du oprette forbindelse til port 6447 på routerværten:
$ 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 |
+---------------+------------+-------------+-------------------+
Ser godt ud. Vi kan nu generere nogle testdata med sysbench. På app-serveren skal du generere 20 tabeller med 100.000 rækker pr. tabel ved at oprette forbindelse til port 6446 på app-serveren:
$ 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
For at udføre en simpel læse-skrivetest på port 6446 i 300 sekunder, kør:
$ 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
For skrivebeskyttede arbejdsbelastninger kan vi sende MySQL-forbindelsen til port 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
Konklusion
Det var det. Vores MySQL InnoDB Cluster-opsætning er nu komplet med alle dets komponenter kørende og testet. I den anden del skal vi se på styring, overvågning og skaleringsoperationer af klyngen samt løsninger på en række almindelige problemer, når vi håndterer MySQL InnoDB Cluster. Hold dig opdateret!