Mise en place d'une réplication PostgreSQL avec Slony I
Par Sébastien Le Ray le vendredi 19 juin 2009, 12:48 - Sysadmin - Lien permanent
Comment mettre en place une réplication maître/esclave sous PostgreSQL grâce à Slony I (oui oui c'est le billet annoncé il y a 2 mois).
Tout d'abord quelques notes sur le contexte. La réplication présentée n'est destinée qu'à synchroniser l'esclave avec le maître pour qu'il réponde à des requêtes en lecture (ici on a un serveur DNS sous vhffs qui lit ses enregistrements dans une base, on y ajoute des enregistrements qui doivent être dispatchés sur les NS secondaires).
Dans la suite de cet article, le maître s'appellera pg-master, l'esclave pg-slave (recherché hein).
Pré-requis
On commence par installer les paquets nécessaires :
sebastien@pg-master:~$ sudo aptitude install postgresql-8.3 postgresql-8.3-slony1 slony1-bin sebastien@pg-slave:~$ sudo aptitude install postgresql-8.3 postgresql-8.3-slony1 slony1-bin
On se crée ensuite les utilisateurs qui seront propriétaires de nos bases de test :
sebastien@pg-master:~$ sudo -u postgres createuser dummy -P (Saisir le MDP et répondre "n" à tout) sebastien@pg-slave:~$ sudo -u postgres createuser dummy -P (Saisir le MDP et répondre "n" à tout)
et lesdites bases :
sebastien@pg-master:~$ sudo -u postgres createdb testdb -O dummy sebastien@pg-slave:~$ sudo -u postgres createdb testdb -O dummy
Pour pouvoir se connecter tranquillement sur les bases en utilisant un mot de passe, il faut éditer le fichier pg_hba.conf sur le maitre et l'esclave et remplacer ident sameuser par 'md5'' sur la ligne local all all ou connectez vous avec psql -h 127.0.0.1.
On peut ensuite injecter la base :
sebastien@pg-master:~$ psql testdb dummy testdb=> \i unebasequelconque.sql
Si vous avez la flemme de vous faire un fichier de test, voici un exemple :
CREATE TABLE one( id SERIAL, name VARCHAR(100), CONSTRAINT PK_ONE_ID PRIMARY KEY (id) ); CREATE TABLE two( id SERIAL, name VARCHAR(100), one_id INTEGER, CONSTRAINT PK_TWO_ID PRIMARY KEY (id), CONSTRAINT FK_TWO_ONE FOREIGN KEY (one_id) REFERENCES one(id) );
Mise en place de la réplication
Notions
Tout d'abord, quelques concepts manipulés par Slony I :
- Cluster : ensemble d'instances participant à une réplication ;
- Node : une instance, elle aura un schema portant le nom du cluster ;
- Set : ensemble de tables dans un nœud ;
- Origine : Nœud de référence pour un autre nœud.
Et les programmes intervenant dans le processus :
- Slon : démon tournant sur chaque node pour gérer la réplication
- Slonik : interpréteur de script permettant de contrôler la réplication
Il doit y avoir un démon slon sur chaque serveur. Si plusieurs serveurs sont sur le même réseau **local** il est possible d'utiliser un slon sur un serveur central qui contrôlera les différents nœuds, mais surtout, il ne faut pas se reposer sur un démon slon communiquant avec son nœud au travers d'une liaison WAN.
Configuration
Dans notre cas, on répliquera une base entière, mais avec Slony, vous pouvez ne répliquer que certaines tables ou certaines séquences (voir plus bas).
On commence donc par créer l'utilisateur PostgreSQL qui se chargera de la réplication, un sur le maître et un sur l'esclave, Il doit être super utilisateur :
sebastien@pg-master:~$ sudo -u postgres createuser slony -P sebastien@pg-slave:~$ sudo -u postgres createuser slony -P (Répondre o à la question superuser)
Puis on ajoute le langage PL/PgSQL, il est utilisé dans les différents éléments réplication, sur le maître et l'esclave :
sebastien@pg-master:~$ sudo -u postgres createlang plpgsql testdb sebastien@pg-slave:~$ sudo -u postgres createlang plpgsql testdb
Pour nous simplifier la vie, on va utiliser les scripts altperl qui sont fournis avec slony. Une fois configurés, ils permettent d'effectuer un certain nombre de tâches simplement, sans toucher directement à Slony. Il n'est pas obligatoire de le faire sur tous les nœuds, juste sur celui à partir duquel vous effectuerez les tâches d'administration (slony dispatchera les instructions aux différents nœuds via les démons si nécessaire).
sebastien@pg-master:~$ slonik_build_env -node localhost:testdb:slony:slony -node pg-slave:testdb:slony:slony | sudo tee /etc/slony1/slon_tools.conf
Les options -node permettent de fournir la liste des nœuds participant à la réplication, pour chacun on indique l'hôte, la base sur laquelle on travaille, l'utilisateur de réplication et son mot de passe. En sortie, slonik_build_env fournit un script perl qui positionne un certain nombre de variables utilisées ensuite par les scripts dont le nom commence par slonik_ qui manipulent à leur tour Slony.
Le fichier slon_tools.conf que vous venons de générer n'est pas complet, il est nécessaire d'y ajouter quelques infos qui seront transmises à Slony si nécessaire (vous pouvez ajouter des commentaires en mettant un # devant, faire des print, vous êtes dans un fichier perl). Tout d'abord, on renseigne le nom du cluster, celui-ci est libre mais doit être un nom de schéma valide pour PostgreSQL (le schéma contiendra tout ce qui est nécessaire au fonctionnement de Slony sur la base). Ensuite, l'identifiant du nœud origine, slonik_build_env a créé un certain nombre d'appels à add_node en fonction des arguments que vous lui avez passer, vous devez reporter l'identifiant du nœud de référence pour votre cluster (paramètre node de la fonction add_node). Enfin, le dernier indique où Slony va enregistrer les informations relatives aux événements de réplication.
$CLUSTER_NAME = 'nomducluster'; $MASTERNODE = 1; $LOGDIR='/var/log/slony1/test_cluster';
Une fois ces paramètres correctement renseignés, la suite d'outils slonik devrait fonctionner. Nous allons donc pouvoir initialiser le cluster (créer toutes les structures de données nécessaires à Slony).
Initialisation du cluster
Tout d'abord, on autorise la connexion du maître sur l'esclave et vice versa. Cela se fait via le fichier pg_hba.conf au moyen d'une ligne du type :
host [nombase] [utilisateur_replication] [hôte]/32 md5
Vous pouvez mettre une ligne hostssl si vous préférez. N'oubliez pas le reload.
On peut initialiser le cluster, à partir du maître :
sebastien@pg-master:~$ slonik_init_cluster | slonik
Cela va créer un schéma du nom de votre cluster (vous pouvez regarder à quoi il ressemble si ça vous intéresse). On démarre ensuite les démons slon :
sebastien@pg-master:~$ slon_start 1 sebastien@pg-master:~$ slon_start 2
Attention, ces commandes démarrent les deux démons avec une supervision depuis le maître. Cela simplifie la mise en place des différents éléments. Comme nous l'avons dit dans l'introduction, en production il est préférable que les nœuds soient monitorés de façon plus proche (même machine ou machine sur le même réseau local).
Création des sets
Nous devons maintenant déclarer les ensembles de tables qui vont être répliquées. Dans notre cas, simple, il n'y en a qu'un qui contient toutes les tables, mais vous pouvez découper votre base en différents ensembles qui ne seront pas répliqués par les même nœuds (pour répartir les lectures par exemple).
slonik_build_env n'a pas généré la configuration nécessaire au paramétrage des sets (logique, il ne va pas décider pour nous). Il nous reste donc des choses à faire.
$SLONY_SETS = {
'main' => {
set_id => 1,
origin => 1,
table_id => 1,
sequence_id => 1,
pkeyedtables => \@KEYEDTABLES, # Tables ayant une clé primaire
sequences => \@SEQUENCES, # Séquences à répliquer
# keyedtables => { 'table' => 'index_unique' }, # tables sans pk mais avec une clé candidate
# serialtables => [] # tables sans pk ni candidat
}
};
Voyons un peu ce dont il est question. $SLONY_SETS contient la définition de tous les sets du cluster, c'est un hash nom_set => définition. La défintion du set contient les attributs suivants :
- set_id : identifiant du set, il servira dans les commandes pour s'y référer ;
- origin : identifiant du nœud de référence pour ce set (le même que dans
$ORIGINvu plus haut) ; - table_id : Slony fournit un id aux différentes tables d'un set pour s'y référer en interne, lorsque vous avez plusieurs sets, vous devez veiller à ce que ces identifiants ne se chevauchent pas en ajustant ce paramètre qui est l'identifiant de la première table du jeu ;
- sequence_id : Comme ci-dessus mais pour les séquences ;
- pkeyed_tables : Référence sur un tableau (donc sous la forme
element1, element2) contenant les tables à répliquer qui disposent d'une clé primaire. Ici dans la mesure où le set concerne toutes les tables, on passe directement une référence sur@KEYEDTABLESqui a été créé pour nous par slonik et les contient toutes ; - sequences : Liste des séquences à répliquer (comme ci-dessus, on passe un tableau qui les contient toutes) ;
- keyedtables : Hash de tables à répliquer disposant d'une clé candidate (un index unique not null) mais sans clé primaire, le hash est de la forme
table => index; - serialtables : Tables sans clé primaire, Slony en ajoutera une artificielle. Si vous utilisez ça vous avez vraissemblablement un problème de conception.
Une fois le set déclaré dans la configuration des outils perl, il suffit de le créer :
sebastien@pg-master:~$ slonik_create_set 1 | slonik
Le set est créé, il ne reste plus qu'à indiquer qui réplique quoi.
Lancement de la réplication
On indique simplement au second node (id 2 d'après le fichier de configuration généré) qu'il doit suivre les modifications du set numéro 1. Il n'y a pas besoin d'indiquer quel est le nœud maitre puisque c'est déjà fait dans la définition du nœud. Grâce aux scripts slonik, il suffit de lancer cette commande (attention, ne vous trompez pas dans l'ordre des paramètres, le set puis le nœud).
sebastien@pg-master:~$ slonik_subscribe_set 1 2 | slonik
Les modifications de données dans la base maître sont désormais répliquées sur la base esclave (qui n'est accessible qu'en lecture pour les tables appartenant au set répliqué).
Le démon slon de l'esclave
Comme nous l'avons évoqué au début et au cours de cet article, il est préférable que l'esclave ait son propre démon slon pour gérer sa réplication. Sa configuration n'est pas aussi complexe que celle du maître puisque les informations relatives à la réplication sont stockées dans la base (notamment les informations de connexion d'un nœud à l'autre).
Sous debian, il suffit de créer un fichier slon.conf dans /etc/slony1/nom_cluster contenant les informations de connexion au nœud contrôlé, le script init se chargera de démarrer le cluster :
cluster_name='nom_cluster' conn_info='dbname=db host=localhost user=user password=pass
Pour la machine sur laquelle vous avez créé un fichier slon_tools.conf, il vous suffit d'indiquer le numéro du nœud à démarrer dans /etc/default/slony (variable SLON_TOOLS_START_NODES), il sera démarré via slonik.
Si vous avez des infos pour le démarrage via d'autres distributions (basiquement il suffit d'invoquer slon_start nœud pour le nœud local et slon -f fichier_de_conf_du_cluster pour ceux ayant la configuration comme ci-dessus).