Récemment j’ai eu à faire l’upgrade d’un cluster physique PostgreSQL 9.3 vers 11.
Contexte :
Pour cette migration, il y avait plusieurs contraintes:
- Applications critiques, ce qui impose de réduire au maximum la coupure de service.
- Serveurs physiques avec des disques locaux uniquement
- Réutilisation des mêmes serveurs
- Changement de version majeure de l’OS
Dans cet exemple je ferais abstraction de la partie cluster, ce qui ne change rien au principe expliquer dans cet article.
Attention ! Avant de réaliser une telle migration en production, il faut bien entendu avoir testé la migration mais aussi le fonctionnement des applications en recette !! De plus, cela permet de tester la procédure sur son contexte, différent de celui des autres, et de se préparer à la migration de la base de production. |
Pour réaliser un upgrade d’instance PostgreSQL, il existe plusieurs méthodes :
- pg_upgrade : nécessite un dossier source et un cible
- pg_dump/pg_restore : durée de coupure de service importante
- réplication logique
Nos contraintes nous imposaient d’utiliser la réplication logique.
Pas de disque disponible pour contenir à la fois les données sources et cibles, et l’export/import pend beaucoup de temps.
Il existe plusieurs outils de réplication logique :
- la méthode native, intégrée depuis la version 10
- pglogical, développé par 2ndquadrant, mais compatible uniquement à partir de la version 9.4
- SLONY-I, dont la version 2 est compatible depuis la version 8.3 (la version 1 est compatible avec les versions 7.3 à 9.1)
Notre cas nous imposait d’utiliser SLONY-I pour réaliser cette migration.
Présentation de SLONY-I :
Slony est un outil de réplication asynchrone pour une source vers plusieurs destinations. Une destination pouvant aussi être une source.
La réplication fonctionne à l’aide de triggers ajoutés au niveau des tables à répliquer. La réplication peut donc se paramétrer individuellement pour chaque table et est asynchrone
(lors d’une modification sur le provider, le changement est effectué dans un second temps sur le subscriber).
Slony ne rejoue pas la requête entière sur le souscripteur, il se contente de copier les nouvelles valeurs.
Prérequis :
- une PK sur chaque table, si besoin, on en rajoute une aux tables concernées
- lister les séquences (car non répliquées) (et préparer leur recréation manuelle)
Limitations :
- pas de réplication des champs BLOB
- pas de réplication des modifications de schéma
Avantages majeurs :
- simple à mettre en place, mais un peu complexe à appréhender/maîtriser
- très grande granularité (choix table par table) : dans notre cas, on les prend toutes
- les souscripteurs en lecture seule (au niveau des tables et non de la base)
- mise à jour de PostgreSQL rapide et avec le moins possible d’arrêt de production (une coupure : arrêt des applis, modification des séquences, redémarrage des applis sur la nouvelle instance)
Inconvénients majeurs :
- pas de réplication automatique des objets (les objets doivent être créés avant de lancer la réplication)
- pas de réplication du TRUNCATE avant la 8.4 (peu utile dans notre cas)
- une documentation qui, bien que complète, laisse à désirer
- une réplication à créer par base
Planification:
- Installation de l’OS sur le nœud 2
- Installation de postgres, création de l’instance et configuration de celle-ci
- Recréation des tablespaces/users/bases et leurs structures (tables, index, …) : (via export/import)
- Mise en place de la réplication via Slony-I
- Arrêt des applications
- Mise à jour des séquences sur le nœud secondaire
- Bascule du rôle de provider
- Redémarrage des applications
- Installation de l’OS sur le nœud 1
- Installation de postgres, création de l’instance et configuration de celle-ci pour remettre en place le cluster (streaming replication)
Procédure :
- Installation de slony-1, sur les deux machines. Il existe deux solutions :
- via le gestionnaire de paquet : yum install slony1-11.x86_64
- en téléchargeant les sources, puis en les compilant :
bunzip2 slony1-2.2.8.tar.bz2 tar xvf slony1-2.2.8.tar cd slony1-2.2.8 ./configure --with-perltools --with-pgconfigdir=/usr/pgsql-9.3/bin gmake all gmake install
- Configuration de slony-1, sur les deux machines :
- Création du user slony :
CREATE ROLE slony WITH SUPERUSER LOGIN REPLICATION ENCRYPTED PASSWORD 'SLONY_PASSWORD'; ALTER ROLE slony SET statement_timeout TO 0;
- Ajouter le user slony dans le pg_hba.conf sur les deux nœuds
host all slony 192.168.220.0/24 md5 select pg_reload_conf();
mkdir /etc/slony1/ mkdir /var/log/slony1/ vi /etc/slony1/slon_tools.conf < < EOF if ($ENV{"SLONYNODES"}) { require $ENV{"SLONYNODES"}; } else { $CLUSTER_NAME = 'slony_replication'; $LOGDIR = '/var/log/slony1'; $MASTERNODE = 1; $DEBUGLEVEL = 2; ## Liste des noeuds ## Un noeud = une instance et une base ## 2 noeuds pour une base, 4 noeuds pour 2 bases, ... # noeud 1 add_node(host => 'OLD_HOST', dbname => 'pagila', port =>5432, user=>'slony', password=>'SLONY_PASSWORD', node=>1); # noeud 2 add_node(host => 'NEW_HOST', dbname => 'pagila', port =>5432, user=>'slony', password=>'SLONY_PASSWORD', node=>2 ); # noeud 3 # ... } $SLONY_SETS = { # un set par base "set_pagila" => { "set_id" => 1, "table_id" => 1, "sequence_id" => 1, "pkeyedtables" => [ # liste des tables a repliquer "public.actor", "public.address", "public.category", "public.city", "public.country", "public.customer", "public.film", "public.film_actor", "public.film_category", "public.inventory", "public.language", "public.payment", "public.rental", "public.staff", "public.store", ], }, # set 2 # ... }; if ($ENV{"SLONYSET"}) { require $ENV{"SLONYSET"}; } # Please do not add or change anything below this point. 1; EOF
- Lister les tables : (à adapter à votre cas)
sudo -u postgres psql -d pagila -c "select concat('\"', schemaname, '.', tablename, '\",') from pg_catalog.pg_tables where schemaname = 'public' and tableowner = 'pagila' order by tablename asc;" -t
- Initialisation du cluster, sur le nœud fournisseur
slonik_init_cluster --config /etc/slony1/slon_tools.conf | /usr/pgsql-9.3/bin/slonik
slonik_create_set set_pagila --config /etc/slony1/slon_tools.conf | /usr/pgsql-9.3/bin/slonik
slon_start --config /etc/slony1/slon_tools.conf slon_status --config /etc/slony1/slon_tools.conf
slonik_subscribe_set --config /etc/slony1/slon_tools.conf set_pagila node_id | slonik
slonik_move_set --config /etc/slony1/slon_tools.conf set_pagila <node_id ancien fournisseur> <node_id ancien souscripteur> | slonik
- Redémarrage des applications
Conclusion :
Slony-I nous a permis de répliquer les bases d’une instance en 9.3 vers une instance en 11. Ce qui a fortement réduit la durée de coupure de service de cette migration. La réplication se gère au niveau base, il est totalement possible de basculer le rôle de povider base par base. Notamment dans le cas où toutes les applications ne peuvent pas être coupées au même moment.
Continuez votre lecture sur le blog :
- Migrer d’un cluster Galera MariaDB 10.3 vers MariaDB 10.5 avec la réplication logique (David Baffaleuf) [ContainerMySQLNon classé]
- Réplication logique avec PostgreSQL (Capdata team) [PostgreSQL]
- Comparatif des gestionnaires de VIP dans un cluster Patroni : épisode 1 (KEEPALIVED) (David Baffaleuf) [ContainerPostgreSQL]
- Création et utilisation d’OCFS2 (Capdata team) [OracleVintage]
- [sqsrvres] OnlineThread: SQL Cluster shared data upgrade failed (David Baffaleuf) [SQL Server]
Bonjour,
Dans les concepts de Slony, il n’est pas fait mention de Maître-esclave.
Pas uniquement pour ce que le terme esclave peut représenter.
Mais surtout parce que ces termes ne s’appliquent pas dans le contexte de Slony où tous les noeuds peuvent prendre le statut de fournisseur ou de souscripteur.
On parle plutôt de réseau de réplication, avec des nœuds, dont le rôle peut être à la fois fournisseur et souscripteur (provider et subscriber dans la documentation officielle).
Bonjour Stéphane,
En effet. Je parlais de maître/esclave dans le cadre d’une migration.
Je corrige pour rendre ce passage plus clair.