Configurer ProxySQL pour MySQL Group Replication

janvier 11, 2017

Cet article s’inspire de HA with MySQL Group Replication and ProxySQL de Frédéric Descamps aka @lefred

 

Dans un précédent article je vous ai présenté comment déployer un cluster MySQL Group Replication, la nouvelle solution de haute disponibilité de MySQL.

Ce type d’architecture est souvent utilisé avec un composant qui se place entre l’application et le cluster,composant généralement appelé proxy (quelque chose) ou router quelque chose. Dans cet article, je vais vous présenter le meilleur (selon moi) proxy open source du moment : ProxySQL (1.3.2 : la version GA à la date d’écriture).

Le but de cet article est de créer un PoC Solution HA Base de Données Open Source : MySQL Group Replication et ProxySQL.

 

L’article étant suffisamment long, je ne vais couvrir ni l’installation des nœuds MySQL (5.7.17), ni le déploiement du cluster. Mais comme je suis sympa, voici les ressources nécessaires pour accomplir ces différentes tâches:

 

Avertissement!
Ce qui suit est effectué par un professionnel… sur son ordi portable 🙂 Toutes les instances sont en local, car je suis fainéant par commodité.
Attention, à ne pas reproduire tel quel en production. 

 

MySQL Group Replication

MySQL Group Replication se présente comme un plugin embarqué dans MySQL à partir de MySQL 5.7.17.

Caractéristiques

  • Version du serveur : 5.7.17
  • Version du plugin : 1.0
  • Nœud 1 : 127.0.0.1 : 14418
  • Nœud 2 : 127.0.0.1 : 14419
  • Nœud 3 : 127.0.0.1 : 14420

 

A partir d’ici, on a donc un cluster MySQL Group Replication de 3 nœuds, installé, déployé et qui fonctionne :

 

Le cluster est en mode single primary, c’est à dire qu’un seul nœud est disponible en écriture (à la fois).

 

Pour pouvoir automatiser le routage des requêtes, mais aussi permettre le failover avec ProxySQL nous allons enrichir le schéma sys de MySQL 5.7.17 avec le code ci-dessous (disponible ici également) :

Vous pouvez retrouver ce bout de code (version originale) et bien plus encore dans l’article du Product Manager de MySQL Group Replication, Matt Lord : MySQL Group Replication: A Quick Start Guide

Important
Dans la version originale du script il faut passer la commande SET GLOBAL log_bin_trust_function_creators=ON; sur TOUT les nœuds du cluster, avant de jouer le script qui contient le code ci-dessus :

 

 

ProxySQL

Caractéristiques

  • Version du proxy : 1.3.2.0

 

Dans le cadre de cet article je ne vais aborder que les fonctionnalités qui relative au routage et failover de ProxySQL. Je vous invite cependant à lire la documentation.

Les grandes étapes pour la préparation de notre environnement sont :

Téléchargement

Installation

Démarrage du service

 

Et voilà le travail!

ProxySQL est installé et fonctionnel :

 

Faisons un point. A ce stade on a :

  • déployé un cluster MySQL Group Replication de 3 nœuds
  • ajouté des fonctions et des vues dans sys schema (Group_Replication_helper_functions_and_views.sql)
  • installé ProxySQL

Il nous reste pas mal de choses intéressantes à voir. Cependant, avant de passer à la suite regardons à quoi ressemble notre architecture cible :

 

L’application se connecte à ProxySQL qui redirige les requêtes sur les bons nœuds. Les flèches rouges représentent les écritures et les vertes les lectures.

La suite ? on va donc maintenant rendre ProxySQL conscient de MySQL Group Replication.
Pour se faire on va se connecter à ProxySQL en mode administrateur (utilisateur admin) :

La syntaxe est celle de MySQL \o/

Un DBA se sent un peu comme à la maison et c’est plutôt agréable.

Voyons un peu ce qu’il y a sous la surface :

ProxySQL contient 4 schémas (base de données). En voici une description succincte:

  • main : la configuration courante
  • disk : configuration persistante (stockée sur le disque)
  • stats : statistiques liées à l’utilisation du proxy
  • monitor : données collectée en vue de la supervision

Succinct, comme convenu!
Suffisant néanmoins dans le cadre de cet article, car nous allons principalement utiliser les tables du schéma main. tu veux en savoir plus ? RTFM !

 

Configuration des groupes dans ProxySQL

ProxySQL utilise la notion de Hostgroup pour regrouper de manière logique des serveurs par type. Ils sont définit dans la table main.mysql_servers :

 

Comme vu sur le schéma, on va séparer les lectures des écritures. Pour se faire on va  donc créer 2 groupes, l’un dédié aux écritures et l’autres… aux lectures :

 

Supervision

ProxySQL comprend un module de supervision (monitoring) qui a pour utilisateur et mot de passe par défaut, respectivement monitor et monitor (oui 2 fois monitor). Cet utilisateur doit bien évidemment exister au niveau des membres du cluster et il n’a besoin que du privilège MySQL USAGE, afin de pinger et vérifier la variable read_only.
Le privilège REPLICATION CLIENT est cependant nécessaire s’il doit superviser aussi le retard de réplication.

 

Scheduler

Le scheduler permet d’exécuter des scripts externes à ProxySQL. Nous avons besoin d’un script pour superviser les membres du cluster pour le routage des requêtes et le failover. Ce script est disponible sur mon repo GitHub : proxysql_groupreplication_checker.sh et  doit être placé dans « /var/lib/proxysql/ »

Petit rappel: ce script n’est fournit que pour l’exemple. Il ne doit pas être utiliser tel quel en production.

 

Note
Ce script est légèrement modifié par rapport à la version originale que Lefred propose : https://github.com/lefred/proxysql_groupreplication_checker pour pouvoir fonctionner dans le cadre de ce PoC avec ProxySQL 1.3.2.

 

Les jobs à exécuter sont stockés dans la table scheduler du schema main :

Quelques infos pour la route :

  • arg1 identifiant d’hostgroup pour les écritures
  • arg2 identifiant d’hostgroup pour les lectures
  • arg3 nombre d’écrivain actif simultanément
  • arg4 booléen qui permet de choisir si le membre actif pour les écritures est aussi candidat pour les lectures
  • arg5 fichier de log

 

Paramétrons le scheduler :

Et on peut constater que le script à modifié le statut des membres du cluster :

En clair, du point de vue de l’application, qui se connecte au proxy :

  • 14418 aka node 1 (primaire) : accessible en écriture / inaccessible en lecture
  • 14419 aka node 2 (secondaire) : inaccessible en écriture / accessible en lecture
  • 14420 aka node 3 (secondaire) : inaccessible en écriture / accessible en lecture

On est bien !

 

Test du failover

A ce stade on a tout ce qu’il faut pour tester le comportement du proxy en cas de perte du primaire. Chiche?

Vérification du statut des membres à l’aide de la supervision ProxySQL (perspective du proxy) :

Vérification de l’identité du nœud primaire (perspective du cluster) :

Vérification du statut des membres en contactant les nœuds directement (perspective client) :

Il y a manifestement un consensus pour dire que :

  • Membre 1, port 11418 est le nœud primaire, en mode lecture/écriture (mais lecture seule pour ProxySQL)
  • Membre 2 (port 14419) & 3 (port 14420) sont des nœuds secondaires, en mode lecture seule.

Note
En fonction de votre configuration un utilisateur et un mot de passe peuvent être requis

 

La première action de notre test consiste en l’ arrêt du nœud primaire (node 1, port 14418) :

MySQL Group Replication va donc élire un nouveau membre primaire :

Le nœud 2 (port 14419) est donc le nouveau membre primaire du cluster.

Une autre vue de ce nouveau statut :

En ce qui concerne la vision ProxySQL :

Confirmation, avec ce nouvel état :

  • 14418 aka node 1 (down) : inaccessible
  • 14419 aka node 2 (primaire) : accessible en écriture / inaccessible en lecture
  • 14420 aka node 3 (secondaire) : inaccessible en écriture / accessible en lecture

Que c’est beau l’informatique… quand ça fonctionne.

Que se passe t’il si le membre 1 revient ?

Le proxy nous montre un nouvel état, une fois le nœud 1 de retour dans le cluster :

  • 14418 aka node 1 (secondaire) : inaccessible en écriture / accessible en lecture
  • 14419 aka node 2 (primaire) : accessible en écriture / inaccessible en lecture
  • 14420 aka node 3 (secondaire) : inaccessible en écriture / accessible en lecture

Pour la suite de l’artcile, le membre 1 (14418) est à nouveau le nœud primaire.

 

Ci dessous extraits de quelques états du proxy durant la phase de failover :

## few seconds…

## few seconds…

 

Règles de routage

La table mysql_query_rules du schema main va contenir les règles de routages. C’est donc là que nous allons pouvoir séparer les requêtes d’écriture des requêtes de lecture :

Pour ce PoC nos règles seront simples et définies à base de regex :

  • Groupe lecture : requêtes commençant par le mot clé SELECT (^SELECT) vont dans le hostgroup 2.
  • Groupe écriture : toutes les autres requêtes (DDL, DML,…), ainsi que les SELECT contenant la clause FOR UPDATE (^SELECT.*FOR UPDATE$) vont dans le hostgroup 1.

Si une requête ne correspond à aucune des règles, elle sera dirigée vers le hostgroup par défaut (champ default_hostgroup de la table mysql_users) de l’utilisateur qui exécute la requête.

Regardons la structure de la table mysql_users :

 

Créons l’utilisateur MySQL utilisé pour se connecter au backend (app_user / app_pwd) :

Maintenant nous pouvons renseigner la table mysql_query_rules avec nos 2 règles de routages (écriture et lecture) :

Et voilà!

Il est temps de passer aux choses sérieuses.

 

Playtime

Toutes les briques de notre archi sont assemblées et configurées, c’est donc l’heure du test final.

Notre appli, simulée par un script bash, va se connecter au proxy (ProxySQL) pour interroger la base de données distribuée (MySQL Group Replication).

Au fait on fait comment pour se connecter au proxy ?

Pour se connecter à la base de données, par l’intermédiaire du proxy, l’application peut soit utiliser le port 6033, soit le socket /tmp/proxysql.sock :

Comme prévu, les requêtes de lecture se connectent sur l’un des 2 nœuds secondaires (node 2 : port 14419 || node 3: port 14420).

Allons plus loin dans le test et créons la table test.poc :

 

L’application test jouera les 2 requêtes suivante :

  • INSERT INTO test.poc (port) VALUES (@@port);
  • SELECT * FROM test.poc;

 

Grâce à ces 2 requêtes et le petit scripts ci-dessous, on va être en mesure de suivre les processus de routage et de failover.
En clair :

  • écriture sur le primaire
  • lectures sur le(s) secondaire(s)
  • crash du master
  • failover automatique et transparent

Revoyons la scène au ralenti…

  • Row 1 : Ecriture sur 14418, Lecture sur 14419
  • Row 2 : Ecriture sur 14418, Lecture sur 14419
  • Row 3 : Ecriture sur 14418, Lecture sur 14420
  • Row 4 : Ecriture sur 14419, Lecture sur 14420
    • Le membre 14418 est stoppé, failover automatique de MySQL Group Replication et ProxySQL redirige les écritures sur 14419
  • Row 5 : Ecriture sur 14419, Lecture sur 14420

 

Trop cool !

 

Le mot de la fin

Récapitulons: pour ce PoC,  une architecture ProxySQL 1.3 avec MySQL Group Replication s’est montée en plusieurs étapes :

  1. Déployement d’un cluster MySQL Group Replication (3 ou 5 nœuds en général)
  2. Enrichissement de sys schema afin gérer le routage et le failover
  3. Installation et paramétrage de ProxySQL
  4. Ajout du job de routage et de failover

L’étape 2 ne sera plus nécessaire à terme, sys schema sera nativement compatible avec Goup Replication dans une prochaine version de MySQL.

En ce qui concerne les étapes 3 et 4, elles vont être simplifiées car ProxySQL 1.4 qui est en cours de développement, est nativement compatible Group Replication.

Et surtout n’oubliez pas que MySQL InnoDB Cluster est la solution maison tout en un, qui simplifie grandement le déploiement de ce type d’architecture. Pour rappel InnoDB Cluster c’est :

Vous pouvez d’ores et déjà tester la dernière pré-version (labs preview) de MySQL InnoDB Cluster: MySQL InnoDB Cluster 5.7.17 Preview 2
C’est inutile mais je vais le rappeler quand même : il n’est pas recommandé d’utiliser les binaires du Labs en production.

 

Références

MySQL Group Replication

 

ProxySQL

 

MySQL InnoDB Cluster

 

Thanks for using MySQL!

 

0

Retour sur le MySQL Day Paris 2016

novembre 24, 2016

Oracle MySQL Day Paris

Chose promise, chose due 🙂

Voici les présentations de l’Oracle MySQL Day Paris du 22 novembre 2016.

State Of The Dolphin

MySQL Day Paris 2016 – State Of The Dolphin from Olivier DASINI

 

MySQL High Availability  – InnoDB Cluster and NDB Cluster

MySQL Day Paris 2016 – MySQL HA: InnoDB Cluster and NDB Cluster from Olivier DASINI

 

MySQL as a Document Store

MySQL Day Paris 2016 – MySQL as a Document Store from Olivier DASINI

 

Introducing Oracle MySQL Cloud Service

MySQL Day Paris 2016 – Introducing Oracle MySQL Cloud Service from Olivier DASINI

 

MySQL Enterprise Edition – Achieve the Highest Levels of Security

MySQL Day Paris 2016 – MySQL Enterprise Edition from Olivier DASINI

 

MySQL Day Paris
Thanks for using MySQL!

 

0

Déployer un cluster MySQL Group Replication

novembre 8, 2016

Mise-à-jour: 13 janvier 2017

Historiquement, les solutions de haute disponibilité (HA) avec MySQL tournent autour de la fonctionnalité native MySQL Replication: replication asynchrone ou semi-synchrone. Ces modes de  replication sont très largement utilisés pour le besoins critiques d’enterprises « at scale » comme Facebook, Twitter, Booking.com, Uber

Aujourd’hui MySQL propose une nouvelle fonctionnalité native de haute disponibilité :

MySQL Group Replication.

MySQL Group Replication

MySQL Group Replication est un plugin pour MySQL 5.7+ qui fournit nativement de la réplication virtuellement synchrone avec détection/résolution de conflit et cohérence garantie. Ce plugin est disponible sur tous les systèmes d’exploitation supportés par MySQL (Linux, Windows, Solaris, OSX, …)

C’est la fonctionnalité idéale pour les architectures multi-maîtres. Il n’est alors plus nécessaire de gérer le failover de la base de données (à l’aide d’outils comme: mysqlfailover; mysqlrpladmin; MHA).

A noter que le plugin MySQL Group replication est en ce moment en Release Candidate (RC) ce qui veut dire qu’il n’est pas encore conseillé pour la production.  C’est néanmoins le bon moment pour le tester (binaires téléchargeable ici). Le statut RC est la dernière étape avant la GA, et selon mon petit doigt ce n’est plus qu’une question de semaines avant la sortie officielle en GA (qui a dit MySQL 5.7.17 ???).

Le plugin MySQL Group Replication est GA et embarqué dans MySQL à partir de la version 5.7.17. Pour télécharger MySQL rendez-vous sur la page : http://www.mysql.com/downloads/ 

 

Déployer un cluster de 3 nœuds

La version du plugin lors de l’écriture de cet article est 0.9 disponible avec MySQL 5.7.15 dans le lab de MySQL : http://labs.mysql.com/
Cette article présume que MySQL 5.7.15 est déja installé (installer MySQL).

Article mis-à-jour avec la version 1.0 du plugin, qui est la version GA embarquée dans MySQL 5.7.17.

Cette article présume qu’une version de MySQL égale ou supérieure à 5.7.17 est déja installé (installer MySQL).

Caractéristiques

  • Version du serveur : 5.7.17
  • Version du plugin : 1.0
  • Nœud 1 : 192.168.1.11 : 14115
  • Nœud 2 : 192.168.1.9 : 3301
  • Nœud 3 : 192.168.1.48 : 5709

 

Configurer les instances MySQL

Comme toutes technologies, il y a des contraintes et quelques limitations. MySQL Group Replication nécessite :

  • MySQL 5.7
  • Tables avec le moteur de stockage InnoDB
  • Tables avec une clé primaire
  • Seul le protocole IPV4 est supporté
  • Les DDL en parallèle de DDL/DML exécutés par différents nœuds sur le même objet sont proscrits.

Liste complète : Requirements and Limitations

 

Au niveau configuration des serveurs il faut:

 

 

Il faut également avoir une valeur de la variable server_id différente pour chacun des 3 nœuds:

  • Nœud 1 : server_id=11
  • Nœud 2 : server_id=9
  • Nœud 3 : server_id=48

 

Pour synthétiser, dans le fichiers de configuration (my.cnf / my.ini) du nœud 1, il faut avoir (en plus des infos classiques):

Pareil pour les 2 autres, à la valeur de server_id près.

Configuration spécifique à MySQL Group Replication

Le cluster doit avoir un identifiant unique au format UUID:

  • le UUID doit être valide
  • il doit être définit sur chacune des machines du groupe

La fonction MySQL UUID() permet de générer un… uuid:

 

 

Note.

Pour avoir une architecture multi-master ie pouvoir écrire sur toutes les intances à la fois il faut group_replication_single_primary_mode = OFF sur tous les nœuds

 

Activation du plugin MySQL Group Replication

A partir de la version 5.7.17,  MySQL embarque le plugin Group Replication qui se nomme : group_replication.so.

Le plugin n’est évidemment pas activé par défaut, cependant vous avez 2 solutions pour l’activer :

  • dans le fichier de configuration comme indiqué précédemment (nécessite un redémarrage de l’instance MySQL)

  • à la volée, avec la commande INSTALL PLUGIN si l’instance est correctement configurée

Un fois activé, les informations relatives au plugin sont disponible avec (à faire sur tout les nœuds) :

Le fichier group_replication.so se trouve dans le répertoire à plugin – plugin_dir:

/usr/local/mysql/lib/plugin/ pour ma configuration.

 

Synthétisons encore!

Dans le fichiers de configuration (my.cnf / my.ini) du nœud 1, il faut ajouter:

 

Et donc pour les 2 nœuds restant, il faut ajuster:

Nœud 2 :

 

Nœud 3 :

 

Note.

Mon environnement étant « exotique » j’ai du configurer les 2 variables qui suivent, pour que le process de restauration fonctionne. 

  • Nœud 1 : report_port = 14115 / report_host = « 192.168.1.11 »
  • Nœud 2 : report_port = 3301 / report_host = « 192.168.1.9 »
  • Nœud 3 : report_port = 5709 / report_host = « 192.168.1.48 »

Cependant il est plus que recommandé de configurer correctement nom d’hôte (/etc/hosts; /etc/hostname;)  et DNS.

 

 

Optionnel : Pour empêcher l’utilisation (malencontreuse) d’autres moteurs de stockage autre qu’InnoDB (non-transactionnel donc), il peut être utile d’ajouter à la conf:

 

Le fichier de configuration étant modifié, il faut redémarrer les instances MySQL pour que la nouvelle configuration prenne effet.

A noter quand même que la plupart des variables relatives à Group Replication  sont changeable à chaud avec la commande SET GLOBAL <commande>.

 

Utilisateur de restauration

Cet utilisateur est nécessaire pour le processus de récupération automatique (recovery) lorsqu’un serveur (r)entre dans le groupe.

A créer et à configurer sur tout les nœuds du groupe. Il permettra d’établir une connexion replica/source entre les membres du groupe en cas de process de recovery.

 

On est pas mal là!

Avant d’aller plus loin, une bonne habitude est de vérifier que les serveurs sont correctement configurés.

 

Vérification de la configuration

Configuration serveur

La commande SHOW GLOBAL VARIABLES permet de voir la valeur des variables serveur.

 

Configuration restauration

 

Configuration Group Replication

Cela correspond à ce qui a été renseigné un peu plus haut.

Je vous conseille de toujours vérifier les configurations, sur tout les nœuds. Ca permet de gagner du temps et de sauvegarder l’énergie par la suite… « Certified wise DBA »

 

 

Déployer le cluster

Le moment tant attendu arrive…

Pour la suite de cet article, je présume que les instances ont les mêmes données, donc le cas présent, pas de données.

Dans le cas contraire il suffit simplement de faire une sauvegarde complète d’une des instances et de la restaurer sur les 2 autres (Backup and Recovery).

 

Amorcer le cluster

L’amorçage (bootstrap) consiste à créer un groupe d’un seul nœud (faut bien commencer !). Ce dernier va par la suite être en mesure de recevoir d’autres membres. La procédure de bootstrap ne doit donc se faire que sur un seul membre, le tout premier nœud du groupe.

Le nœud 1 est donc désigné volontaire pour l’amorçage.

Revoyons la scène au ralenti…

  • j’initie : group_replication_bootstrap_group = ON
  • je démarre : START GROUP_REPLICATION
  • je termine l’initialisation : group_replication_bootstrap_group = OFF

 

C’est vraiment important d’exécuter group_replication_bootstrap_group = ON seulement sur le 1er nœud du cluster, sous peine de se retrouver avec des groupes indépendant (split-brain artificiel).

 

Récupérer des infos sur le cluster c’est facile, avec les tables:

  • performance_schema.replication_group_members
  • performance_schema.replication_connection_status

 

 

Le groupe contient bien un seul membre, 192.168.1.11 aka nœud 1 et il est ONLINE.

Jusqu’ici tout va bien!

 

Ajouter des nœuds

Un cluster composé d’un seul membre, c’est un bon début. Mais ce n’est évidemment pas suffisant pour avoir de la haute disponibilité avec notre base de données MySQL

Ajout du nœud 2

Trop facile !!!

La supervision montre que le cluster est donc maintenant composé de 2 membres, ONLINE!

 

On ne vas pas s’arrêter en si bon chemin

 

Ajout du nœud 3

Cap ou pas cap ?

Le process est évidemment le même.

 

Les 3 nœuds sont bien actifs et fonctionnels.

 

Alors ? Heureux ?

Il est possible d’avoir jusqu’à 9 membres, donc tu peux y aller Marcel!!!

 

Identifier le nœud primaire

Rapide récap

Je viens de créer un cluster de 3 nœuds en utilisant le plugin HA natif MySQL Group Replication.

Sur ces 3 nœuds, 2 sont en mode lecture seule (mode: super_read_only) et le troisième en mode lecture/écriture, c’est le nœud primaire.

Un intérêt de cette architecture HA est qu’elle est finalement très proche d’une architecture de réplication classique master/slaves. La grosse différence, et c’est ce qui fait sa puissance, est qu’avec MySQL Group Replication, il n’est plus utile de gérer le failover base de données. Est ça, ce n’est pas rien !

 

L’information qui permet de savoir quel nœud est primaire est disponible dans la table performance_schema.global_status :

 

En la joignant avec la table performance_schema.replication_group_members ont obtient un peu plus d’infos:

Dons cette architecture, le nœud 00014115-1111-1111-1111-111111111111 aka 192.168.1.11 aka nœud 1 est le primaire.

 

Note.

En mode multi-maître, ils sont tous primaire

 

Le corollaire immédiat de cette information est que dans cette configuration un seul nœud accepte les écritures. Cependant il est possible de lire sur tous les nœuds.
Sur le nœud 2 -nœud NON primaire

Comme prévu les écritures sont impossibles.

 

 

Sur le nœud 1 – le nœud primaire

Le schéma (database) gr_test est créé sur le nœud 1. La transaction est répliquée automatiquement sur les autres nœuds.

 

 

Arrêt du nœud primaire

Si le nœud primaire n’est plus en ligne (arrêt du serveur pour cause de maintenance ou crash) l’un des 2 autres nœuds devient alors primaire.

 

Les autres membres du cluster sont au courant de la disparition de leur pote.

Le groupe ne se compose alors plus que de 2 membres : 192.168.1.9 & 192.168.1.48

Et l’un des deux devient primaire.

 

Le nœud 2 est passé primaire (automatic database failover)
Je peux donc écrire sur le nœud 2 :

 

Mais pas sur le nœud 3 (pas une surprise):

Ayant fini la tâche de maintenance sur le nœud 1 je le remet dans le cluster.

 

Note.

Si la durée d’indisponibilité est longue, il peut être judicieux de restaurer une sauvegarde fraîche sur le serveur avant de le remettre dans le cluster. C’est le même principe qu’avec une architecture de réplication, en utilisant : 

 

 

Faire revenir un nœud dans le cluster

 

La variable group_replication_start_on_boot étant à OFF, je dois rajouter le nœud au cluster de manière explicite:

 

Après s’être enregistré, le « nouveau » membre va se connecter à un autre pour mettre à jour ses données (recovery mode).
Puis finalement participer à nouveau à la vie du cluster:

 

A noter que le nœud 1 ne redevient pas primaire (no failback).

Le nœud 2 (d0853b8c-8d92-11e6-875b-0800273276e6 ou 192.168.1.9) est donc bien resté primaire

 

 

Note.
Pour avoir une vraie configuration multi-maître il faut modifier la variable group_replication_single_primary_mode sur tout les nœuds du cluster.
Cette manipulation ne peut se faire que cluster arrêté.

 

Bien bien bien!

Je propose de s’arrêter là même si j’ai encore des choses à raconter. Mais je ne souhaite pas trop rallonger ce long billet.

En guise de conclusion, j’évoquerai simplement les solutions disponibles en frontal, pour que l’application se connecte au cluster.

 

Router, proxy and Co

  • mysqlrouter : Outil développé par MySQL Oracle, il est donc préconisé pour MySQL Group Replication.
    La version 2.1 (GA prévue pour cette fin d’année 2017) est intrinsèquement lié à MySQL Group Replication. C’est donc son compagnon naturel. Il faut juste patienter un peu 🙂

La GA actuelle (2.0) peut dépanner mais elle n’est pas suffisamment intégrée (intelligent) avec MySQL Group replication.

A noter que MySQL Group Replication + mysqlrouter 2.1 + MySQL Shell nous donne MySQL InnoDB Cluster.
J’y reviendrai plus en détails dans un prochain article.

OK tu es un impatient, je le sens 🙂

Jette un coup d’œil ici, tu trouveras des liens intéressants

 

  • HA proxy : certainement le plus connu des 3.
  • Si vous êtes familiers avec les connecteurs MySQL, cela peut sans doutes être une solution.

Petite précision pas anodine, tous ces outils sont en GPL.

 

Aller! Cette fois ci je conclus pour de vrai.

La gestion de la Haute Disponibilité avec MySQL se fait traditionnellement avec :

Le plugin MySQL Group Replication apporte une nouvelle solution de HA native et permet également d’avoir une vraie solution multi-maître native et open-source.

Que du bon 🙂

 

Thanks for using MySQL!

1

MySQL à Oracle OpenWorld 2016

octobre 5, 2016

Du 18 au 22 septembre 2016 c’est déroulé l’Oracle OpenWorld, un ensemble de conférences parlant des technologies Oracle.

Bien entendu, MySQL était au programme, voici un petit résumé des annonces.

MySQL dans le cloud

MySQL, la base de données open source la plus populaire au monde a enfin son cloud officiel avec Oracle MySQL Cloud Service.

Parmi les principaux points :

  • Dernière version GA de MySQL (5.7) en version Enterprise.
  • Support technique réalisé par les équipes d’Oracle MySQL (en lien direct avec les devs)

Pour l’essayer : https://cloud.oracle.com/mysql

Plus d’infos:

MySQL Cloud Service Deep Dive from Morgan Tocker

 

MySQL HA

MySQL Group Replication est en RC, en clair la prochaine version sera la première GA.

MySQL Group Replication est la solution native MySQL pour faire de la haute disponibilité. C’est un plugin pour MySQL qui permet un mode de réplication virtuellement synchrone, avec detection et résolution des transactions (éventuellement) en conflit pour des architectures multi-master.

Plus d’infos:

 

 

Cependant, la grosse sensation a été l’annonce de la version Release Candidate de MySQL InnoDB Cluster !

 

MySQL InnoDB Cluster permet de faciliter le déploiement de solutions de haute disponibilité basées sur MySQL Group Replication.

Concrètement, avec l’aide du MySQL Shell il devient alors possible de mettre en oeuvre facilement un cluster MySQL Group Replication avec des instances de  MySQL Router en frontal.

Pour avoir une explication encore plus simple, regardez la demo de Fred et un tutorial.

Plus d’infos:

MySQL High Availability — InnoDB Clusters from Matt Lord

 

MySQL 8.0.0. DMR

La prochaine GA de MySQL sera la 8.

On passe donc de 5 (5.7) à 8… pourquoi ? Tout simplement parce que MySQL 6 a déjà existé (en 2007 puis abandonné).

Et pas 7 non plus car MySQL Cluster est en version 7 (7.4) actuellement. Du coup le premier chiffre de libre pour unifier les 2 solutions est le… 8 !  CQFD 🙂

MySQL 8.0.0 est une DMR, c’est donc la branche de développement. En clair à ne pas utiliser en production. Par contre je vous encourage à la télécharger (code source dispo également sur GitHub ou si vous préférez une image Docker ) et à tester les nouvelles fonctionnalités.

Au programme de cette version 8:

  • Common Table Expressions  (CTE) une sorte de table temporaire associée à une requête qui permet à l’aide de la commande WITH d’exprimer la récursivité (mais pas seulement). A noter qu’il est cependant possible d’émuler WITH RECURSIVE avec MySQL et ce sans attendre la 8, lire cet article de Guilhem.
  • Invisible indexes : index maintenu par l’optimiseur mais pas utilisé. Permet de tester le comportement du serveur lors de l’évaluation de la pertinence ou non d’un index.
  • Persisting configuration variables, la possibilité de rendre persistant les changements de configuration serveur fait en ligne.
  • Les roles : faciliter la gestion des utilisateurs
  • La base de données est en UTF-8 par défaut
  • et plein d’autres choses…

Plus d’infos:

Autres annonces

La version 3.3 de MySQL Enterprise Monitor (MEM) : outil de gestion et de supervision des bases MySQL. Cette version intègre un tout nouveau tableau de bord dédié à la sauvegarde. MEM 3.3 permet donc un intégration très fine avec MySQL Enterprise Backup notre outil de sauvegarde physique à chaud.
Group Backup Overview

 

MySQL Cluster 7.5 notre base de données distribuée en mémoire est en RC.

 

Videos

 

Présentations

Les présentations sont disponibles sur le site d’OOW.

 

Thank you for using MySQL!

0

Retour sur le meetup – MySQL Group Replication & MySQL as a Document Store

septembre 7, 2016

Ce mardi 6 septembre, un superbe meetup MySQL  c’est déroulé à Paris dans les locaux d’ Executive MBA Epitech  à Paris. Organisé et sponsorisé par  Oracle MySQL et Openska.

Un grand merci à tous les participants, aux organisateurs et au sponsor (Oracle).

Merci également à Frédéric (EMEA MySQL Community Manager) et à Dimitri (MySQL Performance Architect).

Les présentations de la soirée:

MySQL Group Replication – Haute Disponibilité avec Multi-Masters

de Frédéric Descamps

 

MySQL 5.7 & JSON – Nouvelles Opportunités pour les Développeurs

de Frédéric Descamps

 

Vous pouvez également les récupérer le blog de Frédéric.

 

Pour aller plus loin

MySQL Group Replication

 

MySQL as a Document Store

 

Et encore beaucoup de bonnes choses à venir 🙂 alors restez à l’écoute !

 

En bonus quelques photos:

https://plus.google.com/photos/114583255370443901762/albums/6327640843829307985

 

Thank you for using MySQL!

 

 

1

Meetup – MySQL Group Replication & MySQL as a Document Store

août 29, 2016

Oracle MySQL, Openska et Executive MBA Epitech ont le plaisir de vous inviter le mardi 6 septembre pour le premier meetup MySQL de la rentrée.

Au programme… du lourd, rien que du lourd 🙂

 

MySQL Group Replication: Haute Disponibilité avec Multi-Masters

Vous souhaitez avoir une architecture de base de données distribuée et hautement disponible ?
MySQL Group Replication est un plugin pour MySQL 5.7 qui fournit de la réplication (virtuellement) synchrone avec detection et gestion de conflits intégré. Ce plugin permet de passer facilement d’une architecture mono-serveur à une architecture distribuée multi-maîtres hautement disponible.

Venez découvrir les concepts ainsi que la meilleure façon de déployer une telle architecture.
http://mysqlhighavailability.com/mysql-group-replication-a-quick-start-guide/

 

Using MySQL as a Document Store: JSON Datatype & NoSQL

Faire du SQL et du NoSQL avec la même base de données est-ce possible ?
La réponse est oui avec MySQL!!!
A partir de MySQL 5.7.12, vous pouvez utiliser MySQL comme un « Document Store » (Un document est un ensemble de paires (clé/valeur) stocké par MySQL dans un format JSON binaire). Et cerise sur le gateau, les attributs du document JSON peuvent être indexés.
De plus, en utilisant le tout nouveau X DevAPI, il est également possible de gérer ces documents via une interface CRUD ou un interface SQL traditionnelle.
https://dev.mysql.com/doc/refman/5.7/en/document-store.html

 

Intervenants:

Frederic Descamps : EMEA MySQL Community Manager

Olivier Dasini : MySQL Principal Solutions Architect EMEA

 

Informations et inscription:
http://www.meetup.com/OpenTech/events/232136370/

 

Update {7 septembre 2016}

Présentation et autres infos

1

Oracle MySQL Tech Tour mai 2016

avril 27, 2016

Le 10 Mai 2016, l’Oracle MySQL Tech Tour passe par Paris !
Venez rencontrer l’équipe MySQL France et discuter des nouveautés de MySQL 5.7 comme :

et bien d’autres choses.

 

Pour vous inscrire et connaitre le programme complet Cliquer sur le lien ci-dessous :

https://eventreg.oracle.com/profile/web/index.cfm?PKWebId=0x3469984798

 

Oracle MySQL Tech Tour

Date : mardi 10 mai 2016

Lieu : Remix Coworking – 24 cour des Petites Ecuries 75010

Horaire : 14:00 – 17:15

Entrée libre

 

0

MySQL en tant que Document Store

avril 21, 2016
Tags: , ,

A partir de MySQL 5.7.12, la nouvelle version de la base de données la plus populaire permet aux devs et aux DBAs de déployer des bases MySQL qui implémentent un modèle document store, relationnel ou hybride (document ET relationnel) !
Plus d’info: http://dev.mysql.com/doc/refman/5.7/en/document-store.html

0

30 mins avec MySQL Query Rewriter

mars 2, 2016

Read this post in English

TL;TR

Parfois des requêtes problématiques tournent sur le serveur, mais il n’est pas possible de régler le problème à la source (requêtes venant d’un ORM par example )

MySQL 5.7 fournit :

  • Une API pre et post parse query rewrite
    • Les utilisateurs peuvent écrire leurs propre plugins
    • Permet d’éliminer le besoin d’un proxy
  • Avec le post-parse query plugin, il est possible :
    • De réécrire une requête problématique sans faire de changement au niveau de l’application
    • Ajouter des hints pour les index ou pour l’optimiseur
    • Modifier l’ordre des jointures

 

API du Plugin Query Rewrite

Pour citer cet article du MySQL Server Blog :

 »

MySQL now offer two APIs for writing query rewrite plugins.

Pre-parse rewrite plugin API,  is for when you know exactly – as in character-by-character exactly – what the offending queries look like. This one has a hook to intercept the query string right before it’s parsed.

Post-parse rewrite plugin API, comes in right after parsing and acts on the parse tree. It offers the basic functionality to walk over the parsed query, which is a lot more efficient than dealing with a string.

 »

Cet article traite du sujet Rewriter plugin, un post-parse query rewrite plugin, inclus dans la distribution MySQL 5.7 (à partir de la version MySQL 5.7.6).

 

Le plugin Rewriter

Installation et vérifications

La simplicité fait partie de la philosophie MySQL, l’installation du plugin n’y déroge pas.

Pour installer le plugin Rewriter, il faut lancer le script install_rewriter.sql localisé dans le répertoire share de votre installation MySQL.

Pour vérifier:

De nouveaux objets ont été créés

La table rewrite_rules du schéma query_rewrite fournie un stockage persistent des règles que le plugin Rewriter utilise pour décider quelles requêtes réécrire.

Le plugin peut être activé ou désactivé à chaud :

Il est également possible de l’activer par l’intermédiaire du fichier de configuration (my.cnf | my.ini)

 

Réécrire une requête

Le plugin post-parse rewrite ne fonctionne qu’avec les requêtes SELECT.

Toutes requêtes autres que SELECT génèrent lors du flush des règles, dans la colonne de la table rewrite_rules.message le message d’erreur suivant:

 

Le plugin Rewriter est facile à utiliser. Commençons par un exemple simple (voir simpliste) histoire de se faire la main. Transformons un SELECT n en un SELECT n+1 (n étant un entier).

Patterns

 -> SELECT 1      # Input

 <= SELECT 2    # Output

Ajouter la règle de réécriture

Pour ajouter une règle dans le plugin Rewriter, il faut ajouter des enregistrements dans la table rewrite_rules.

Le contenu de la table rewrite_rules est:

Les stats du Rewriter montrent:

 

Flusher la règle de réécriture

Ensuite il faut appeler la procédure stockée flush_rewrite_rules() pour charger les règles dans le plugin.

Lorsque le plugin charge les règles, il génère, entre autres, une forme normalisée de la requête ainsi qu’une valeur hash:

Le ? agit comme un ‘marqueur’ qui correspond aux données de la requête. Il ne peut être utilisé que pour les données, pas pour les mots clés SQL, ni les identifieurs,…  De plus le ? ne doit pas être entre guillemets ou apostrophes.

Si le parsing de la requête échoue, la procédure stockée va générée une erreur:

Vous trouverez plus de détails dans la colonne query_rewrite.rewrite_rules.message.

Exemple

Les stats du Rewriter montrent:

 

Requête réécrite

Petit état des lieux. Nous avons, ajouté, puis flushé la règle.  On peut donc maintenant exécuter une requête qui correspond au pattern et voir le résultat…

Magique !!!

La requête à été réécrite « à la volée ». Cependant, quelques détails intéressants sont cachés dans le warning.

 

Les stats du Rewriter ont été mis à jour en conséquence:

Pour désactiver une règle existante, il suffit de modifier la colonne enabled et recharger la table dans le plugin:

En passant il est possible de supprimer les enregistrements de la table:

OK!  maintenant que le concept est compris, voyons des exemples plus pertinents.

 

Exemples de réécritures avec Rewriter

Ex 1

Réécrire un jointure en sous-requête; Pour des raisons de performance, la requête doit être réécrite mais vous n’avez pas accès au coté applicatif.

Patterns

 -> SELECT count(distinct emp_no) FROM employees.employees INNER JOIN employees.salaries USING(emp_no) WHERE DATEDIFF(to_date, from_date) < {integer};

 <= SELECT count(emp_no) FROM employees.employees WHERE emp_no IN ( SELECT emp_no FROM employees.salaries WHERE DATEDIFF(to_date, from_date) < {integer});

Sans la règle

Ajout de la règle de réécriture

Avec la règle

Le temps d’exécution de la requête est passé de 12.93 à 3.77 secondes

Remarque

Il y a quelques années, j’ai écris cet article Jointure vs sous-requête où je compare les temps d’exécution d’un jointure et de son équivalent en sous-requête. L’optimiseur s’est bien amélioré depuis la version 5.5.

 

Ex 2

Borner le temps d’exécution maximum d’une requête; ie ajouter le hint MySQL 5.7  /*+ MAX_EXECUTION_TIME(X)*/ c’est à dire que le temps d’exécution de la requête ne pourra exeder X millisecondes.

Patterns

 -> SELECT count(distinct emp_no) FROM employees.employees INNER JOIN employees.salaries USING(emp_no) WHERE salary = {integer};

 <= SELECT /*+ MAX_EXECUTION_TIME(10000)*/ count(distinct emp_no) FROM employees.employees INNER JOIN employees.salaries USING(emp_no) WHERE salary = {integer};

Sans la règle

Ajout de la règle de réécriture

Avec la règle

 

Ex 3

Evolution du schema de la base après une MEP; ie Une colonne est ajoutée (ou supprimée) mais vous ne pouvez pas modifier la/les requête(s) qui utilise(nt) cette table.

Patterns

 -> SELECT first_name, last_name FROM employees.employees WHERE year(hire_date) = 2000;

 <= SELECT first_name, last_name, birth_date FROM employees.employees WHERE year(hire_date) = 2000;

Sans la règle

Ajout de la règle de réécriture

Avec la règle

 

D’autres idées ?

– Index hints : l’optimiseur n’utilisant pas le bon index, vous pouvez réécrire la requête en ajoutant les mots clés [USE | FORCE | IGNORE] INDEX

– Limiter la taille du résultat d’un SELECT, vous pouvez réécrire la requête en ajoutant la clause LIMIT 1000 (ou plus, ou moins).

En fait cela simule l’option –safe-update du client text mysql

Sky is the limit 🙂 donc à vous de jouer maintenant !

A noter que le plugin Rewriter ne remplace pas un code optimal et des requêtes correctement optimisées à la source…

Cependant, ce plugin peut vraiment être utile lorsque l’accès à la source est compliqué voir impossible.

Il est disponible dans MySQL 5.7 qui est vraiment une superbe version ! Essayer le plugin Rewriter il mérite définitivement plus de 30 minutes.

 

 

Pour aller plus loin

Post-parse query rewrite plugin

Pre-parse query rewrite plugin

 

Thank you for using MySQL!

 

 

0

JSON et colonnes générées avec MySQL

novembre 30, 2015

JSON

Le 24 novembre dernier, lors du Forum PHP, Tomas Ulin (Oracle’s MySQL VP of Engineering) a parlé de l’utilisation de JSON dans MySQL « MySQL 5.7 & JSON: New opportunities for developers« .

 

Voici les réponses à quelques questions qui m’ont été posées:

  • Comment se comporte mysqldump avec les colonnes générées ?
  • Comment utiliser la commande LOAD DATA INFILE avec des colonnes générées ?
  • JSON est il sensible à la casse dans MySQL ?

 

Le contexte, une table InnoDB catalog qui contient un champs doc de type JSON ainsi que des colonnes générées virtuelles isbn & publisher:

Quelques documents JSON :

à insérer dans la table catalog:

La table catalog contient donc 3 enregistrements:

 

Sauvegarder et restaurer une table contenant  des colonnes générées

Q: Comment se comporte mysqldump avec les colonnes générées ?

 

Faire une sauvegardes des données avec mysqldump, le résultat étant redirigé vers le fichier test.catalog.sql :

En visualisant le dump on s’appercoit que:

  • Les colonnes générées sont bien présentent dans la structure de la table.
  • La commande INSERT ne renseigne que les colonnes « classiques » id et doc

Avant de restaurer le dump dans la table, je vais la vider:

La table ne contient plus de donnée:

Chargement des données dans la table:

Ta damm!!!
La table a bien été restaurée, les colonnes générées virtuelles sont, comme convenu, recalculées à la volée.

 

Importer un fichier texte dans une table avec des colonnes générées

Q: Comment utiliser la commande LOAD DATA INFILE avec des colonnes générées ?

L’export des données se fait avec SELECT … INTO OUTFILE:

Avant d’importer le fichier texte dans la table, je vais la vider:

Import des données dans la table:

L’import de fichiers, avec la commande LOAD DATA INFILE, dans une table qui contient des colonnes générées ne diffère en rien de l’import dans une table sans colonne générée.

 

Sensibilité à la casse du contenu JSON

Q: JSON est il sensible à la casse dans MySQL ?

 

Rechercher tous les documents où l’éditeur est ENI (en majuscule):

Rechercher tous les documents où l’éditeur est eni (en minuscule):

Les documents JSON sont donc sensible à la casse.

 

Il est évidemment possible d’utiliser une fonction pour modifier la casse:

Cependant 2 contraintes:
– Si la colonne est indexée ce dernier ne pourra pas être utilisé.
– Ça fonctionne si et seulement si le mot est écrit dans la base entièrement en majuscule.

Une meilleure solution consiste à créer et a indexer une colonne générée qui contient les données en minuscule.

La colonne générée contient les directives suivantes:

  • LOWER : transformer en minuscules les chaines de caractères
  • JSON_UNQUOTE : supprimer les guillemets
  • VIRTUAL : la colonne générée est virtuelle. Les données ne sont pas stockées mais calculées à la volée.

 

La structure de la tables est maintenant:

La colonne publisher_lower contient la version tout en minuscule des données de la colonne publisher.

Ajout de l’index:

Nouvelle structure de table:

Maintenant les données étant stockées dans une collation non sensible à la casse (utf8_general_ci) la requête n’est plus sensible à la casse:

La commande EXPLAIN confirme que l’index est vu et utilisé:

En fait on vient d’implémenter un index sur une fonction (functional index).

Vous voulez en savoir plus sur MySQL 5.7 ?
Rejoignez nous sur l’Oracle MySQL Tech Tour Paris le 8 décember 2015.

Infos & inscriptions

Note: cet article vient en complément de l’article 30 mins avec JSON en MySQL

Je vous invite également à consulter:

BGOUG15: JSON support in MySQL 5.7 from Georgi Kodinov

 

 

 

1