background success stories

Installation InnoDB Cluster 8.0

La version de MySQL 8.0 est sortie il y a déjà quelques jours. Nous avons eu l’occasion de monter un cluster InnoDB en version 8.0 Communautaire.
Nous verrons au long de cet article certains nouveaux aspects du cluster liés à cette version.

L’installation se fera sur la dernière version de Debian, la 9.
Les ports suivants doivent être ouverts entre les machines :
3306
33060
33061

Les noeuds utilisés pour l’article :
bdd_prod
monnoeud2
monnoeud3
app1 comme serveur applicatif

Nous allons essayer d’utiliser la commande SET PERSIST apparue dans cette nouvelle version et nous verrons quelques-unes de ces limitations. Pour rappel, elle est censée permettre de faire les changements sans problème de syntaxe et sans passer par le fichier my.cnf traditionnel.

Récupération des binaires :
Téléchargement du repository
setra-admin@bbd_prod:~$ wget https://dev.mysql.com/get/mysql-apt-config_0.8.10-1_all.deb
activation du package, une interface en ncurses va apparaître, allez sur ok et validez (spécificité Debian) :
setra-admin@bbd_prod:~$ sudo dpkg -i mysql-apt-config_0.8.10-1_all.deb
Mise à jour des repository :
setra-admin@mysql1_prod:~$ sudo apt-get update
Installation des différents packages ; une interface en ncurses va apparaître pour renseigner le mot de passe root (spécificité Debian) :
setra-admin@bbd_prod:~$ sudo apt-get install mysql-community-server mysql-community-client mysql-shell

Un minimum de configuration de base est nécessaire :
Un répertoire /var/lib/mysqltmp a été créé pour le tmpdir de MySQL à la place du /tmp
Un autre a été monté pour les binlogs/relay logs /var/lib/mysqlbinlog

Ces répertoires peuvent être des points de montage, ce qui est recommandé.

Modification du fichier de configuration :
Sur Debian et avec MySQL 8.0, le fichier de configuration à utiliser est le suivant : /etc/mysql/mysql.conf.d/mysqld.cnf

Voici le contenu minimal (que vous pouvez adapter au besoin) :
[mysqld]
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
datadir = /var/lib/mysql
log-error = /var/log/mysql/error.log
#to avoid limitation on /tmp
tmpdir = /var/log/mysqltmp
#to separate binlog/relaylog from data - best practices
log_bin = /var/log/mysqlbinlog/binlog
relay_log = /var/log/mysqlbinlog/relay_log
gtid_mode = ON
enforce_gtid_consistency = 1

Démarrage de l’instance (pour Debian le nom du service est mysql et non mysqld utilisé sur d’autres distributions) :
setra-admin@bbd_prod:~$ sudo systemctl start mysql

Connexion :
setra-admin@bbd_prod:~$ mysql -uroot -p

Positionnement de paramétrage via SET PERSIST :
SET PERSIST innodb_log_buffer_size = 128*1024*1024;

PERSIST_ONLY car cette variable ne peut se changer à chaud :
SET PERSIST_ONLY innodb_log_file_size = 1*1024*1024*1024;

 

Pour information, dans le shell les unités ne sont toujours pas supportées ce qui est dommage, donc pour avoir un fichier log innodb à 1Go, il faut multiplier par 1024 jusqu’à l’unité souhaitée, à savoir 1*1024*1024*1024 pour des Go, on passe d’un octet à 1ko puis 1Mo puis 1Go.
C’est une petite astuce qui évite de faire des conversions.

On redémarre le service pour la prise en compte :
sudo systemctl restart mysql

Une nouvelle option est apparue en 8.0, le innodb_dedicated_server qui va permettre d’auto-ajuster certains paramètres InnoDB comme le buffer pool, la taille des logs innodb etc.
Pour ce déploiement je n’ai pas utilisé cette option, car c’est encore une version RTM et qui part en production. J’ai donc préféré éviter de prendre des risques.

Connexion via MySQL Shell :

setra-admin@bbd_prod:~$ mysqlsh root@bdd_prod:3306
MySQL  localhost:33060+ ssl  SQL > dba.configureInstance('root@bdd_prod:3306', {clusterAdmin: 'clusteradmin',clusterAdminPassword: 'votremotdepasse'});
Some configuration options need to be fixed:
    +--------------------------+---------------+----------------+--------------------------------------------------+
    | Variable                 | Current Value | Required Value | Note                                             |
    +--------------------------+---------------+----------------+--------------------------------------------------+
    | binlog_checksum          | CRC32         | NONE           | Update the server variable                       |
    | server_id                | 1             |                | Update read-only variable and restart the server |
    +--------------------------+---------------+----------------+--------------------------------------------------+

    Do you want to perform the required configuration changes? [y/n]: y
    Do you want to restart the instance after configuring it? [y/n]: y

    Cluster admin user 'clusteradmin'@'%' created.
    Configuring instance...
    The instance 'localhost:3306' was configured for cluster usage.
    Restarting MySQL...
    MySQL server at localhost:3306 was restarted.

    MySQL  localhost:33060+ ssl  JS >

 

Cette commande va configurer l’instance et créer un utilisateur pour l’administration du cluster qui s’appellera clusteradmin avec le mot de passe de votre choix.
Nous pouvons voir aussi qu’il peut positionner des variables (via le SET PERSIST je suppose) et propose de relancer l’instance pour la prise en compte.

Répétez ces actions à l’identique sur chaque de noeud du cluster.

Sur un noeud (qui deviendra primaire par la suite) lancez la commande suivante :
MySQL localhost:33060+ ssl JS > var cluster = dba.createCluster('moncluster')
Nommez votre cluster comme vous le souhaitez.

Ajout des autres noeuds au cluster :
MySQL localhost:33060+ ssl JS > cluster.addInstance('clusteradmin@monnoeud2:3306');
MySQL localhost:33060+ ssl JS > cluster.addInstance('clusteradmin@monnoeud3:3306');

Vérification :

MySQL  localhost:33060+ ssl  JS > cluster.status()
{
        "clusterName": "myCluster",
        "defaultReplicaSet": {
            "name": "default",
            "primary": "bdd_prod:3306",
            "ssl": "REQUIRED",
            "status": "OK",
            "statusText": "Cluster is ONLINE and can tolerate up to ONE failure.",
            "topology": {
                "bdd_prod:3306": {
                    "address": "bdd_prod:3306",
                    "mode": "R/W",
                    "readReplicas": {},
                    "role": "HA",
                    "status": "ONLINE"
                },
                "mysql1_prod:3306": {
                    "address": "monnoeud2:3306",
                    "mode": "R/O",
                    "readReplicas": {},
                    "role": "HA",
                    "status": "ONLINE"
                },
                "mysql2_prod:3306": {
                    "address": "monoeud3:3306",
                    "mode": "R/O",
                    "readReplicas": {},
                    "role": "HA",
                    "status": "ONLINE"
                }
            }
        },
        "groupInformationSourceMember": "mysql://clusteradmin@bdd_prod:3306"
    }

 

Configuration des routeurs :
Pour chaque serveur applicatif qui utilisera le cluster, il est conseillé d’installer un MySQL Router

Récupération des binaires :
Téléchargement du repository :
setra-admin@app1:~$ wget https://dev.mysql.com/get/mysql-apt-config_0.8.10-1_all.deb
Activation du package, une interface en ncurses va apparaître, allez sur ok et validez (spécificité Debian) :
setra-admin@app1:~$ sudo dpkg -i mysql-apt-config_0.8.10-1_all.deb
Mise à jour des repository :
setra-admin@app1:~$ sudo apt-get update
Installation des différents packages ; une interface en ncurses va apparaître pour renseigner le mot de passe root (spécificité Debian) :
setra-admin@app1:~$ sudo apt-get install mysql-router

La configuration se fait automatiquement en connectant le router à un des noeuds :
setra-admin@app1:~$ mysqlrouter --bootstrap cluster@bdd_prod:3306 --user=mysqlrouter

Nul besoin de changer la valeur de –user car c’est l’utilisateur système qui est concerné, ce dernier est créé lors de l’installation du package mysql router.

Faites une relance du service pour la prise en compte
setra-admin@app1:~$ sudo systemctl restart mysqlrouter

Pour rappel, mysqlrouter écoute localement sur le port 6446 qui enverra toujours sur le noeud maître, le port 6447 sert à répartir les requêtes en lecture si vous le souhaitez.

Le cluster est maintenant Up & Running
MySQL 5.7 posait plusieurs problèmes notamment à cause de l’absence du SET PERSIST ; aujourd’hui sur la version 8, l’installation est simplifiée, elle peut aussi être automatisée plus facilement.

Petite astuce pour l’administration : n’hésitez pas à utiliser l’option redirect-primary en vous connectant au shell et potentiellement –cluster
La première vous connecte toujours au primaire, peu importe le noeud que vous précisez à la connexion il va se connecter au bon.
La deuxième permet de positionner la variable cluster directement, pour éviter l’opération var cluster = dba.getCluster();

setra-admin@bbd_prod:~$ mysqlsh --cluster --redirect-primary clusteradmin@mysql1_prod
Creating a session to 'clusteradmin@mysql1_prod'
Enter password: ************
Fetching schema names for autocompletion... Press ^C to stop.
Your MySQL connection id is 34 (X protocol)
Server version: 8.0.11 MySQL Community Server - GPL
No default schema selected; type \use to set one.
Reconnecting to PRIMARY instance of the InnoDB cluster (mysqlx://bdd_prod:33060)...
Creating an X protocol session to 'clusteradmin@bdd_prod:33060'

On peut voir ici le changement de connexion vers le primaire.