2

Migration PostgreSQL via SLONY-I ou comment réduire le temps de coupure

twitterlinkedinmail

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 :

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();
    • Configuration de slony-I, sur les deux machines :
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
  • Mise en place de la réplication :
    • Initialisation du cluster, sur le nœud fournisseur
    • slonik_init_cluster --config /etc/slony1/slon_tools.conf | /usr/pgsql-9.3/bin/slonik
    • Création du ou des set(s), sur le nœud fournisseur
    • slonik_create_set set_pagila --config /etc/slony1/slon_tools.conf | /usr/pgsql-9.3/bin/slonik
    • Démarrage du processus slon, sur les deux nœuds
    • slon_start --config /etc/slony1/slon_tools.conf
      slon_status --config /etc/slony1/slon_tools.conf
    • Abonnement du noeud souscripteur aux sets concernés
    • slonik_subscribe_set --config /etc/slony1/slon_tools.conf set_pagila node_id | slonik
    • Le temps de la première réplication dépendra de la volumétrie des bases
  • Arrêt des applications
  • Mise à jour des séquences
  • Bascules (bascule base par base):
  • slonik_move_set --config /etc/slony1/slon_tools.conf set_pagila &lt;node_id ancien fournisseur&gt; &lt;node_id ancien souscripteur&gt; | 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 :

twitterlinkedinmail

Capdata team

2 commentaires

  1. 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).

  2. 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.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.