AccueilTechniqueMaintenance → Instance PostgreSQL standby

    Instance PostgreSQL standby

    Ce guide pas-à-pas permet de configurer une instance PostgreSQL de type « standby » de zéro.

    Une instance standby sert à garder une copie « à chaud » l’intégralité de la base de données. En cas de corruption de l’instance primaire, un basculement immédiat vers l’instance standby est possible.

    Dans des usages avancés, une instance secondaire de PostgreSQL peut également répondre aux requêtes SQL en lecture seule ou encore, fonctionner en mode « multimaître » pour envisager des configurations où la base de données est servie en haute disponibilité.

    Créer une instance PostgreSQL standby🔗

    Prérequis🔗

    On part du principe que la réplication WAL est déjà activée et correctement configurée sur l’instance primaire :

    Fichier postgresql.conf de l’instance primaire

    wal_level = replica
    wal_log_hints = on
    max_wal_size = 1GB
    min_wal_size = 80MB
    max_wal_senders = 3
    

    Fichier pg_hba.conf de l’instance primaire

    host replication <USER> <IPv4>/32 scram-sha-256
    

    Quelques vérifications :

    • L’utilisateur doit avoir été créé pour la réplication sur l’instance primaire.
    • Les deux instances doivent être sur le même réseau.

    Configuration de l’instance standby🔗

    Notre installation doit être légèrement adaptée à cause des contraintes liées à l’utilisation de Docker :

    • On a besoin de travailler dans le dossier de PostgreSQL, /var/lib/postgresql/data/, sans que le logiciel soit en fonctionnement.
    • Le conteneur ne peut a priori pas fonctionner si le processus postgresql est à l’arrêt.
    • Les binaires avec lesquels nous souhaitons travailler sont dans l’image postgres, il nous faut donc démarrer un conteneur pour les utiliser.

    On va donc démarrer un conteneur PostgreSQL dans un dossier temporaire que l’on supprimera par la suite, et travailler avec les binaires fournis par l’image dans un autre dossier.

    1. Si l’on part d’une instance défectueuse : Arrêter le conteneur et supprimer puis recréer le volume Postgres de l’instance standby (NB: ne pas se tromper de serveur…).
    2. Pour que le conteneur démarre sur une installation vierge :
      • Monter le volume de Postgres dans un autre dossier (ex.: /var/lib/postgresql-pgbackup/data/). Postgres démarrera dans le dossier par défaut qui sera supprimé par la suite et nous pourrons travailler dans le dossier monté.
      • Ajouter une instruction env_file et utiliser runtime.env pour ajouter la variable POSTGRES_PASSWORD=<mot de passe>. Le mot de passe est temporaire et n’a pas d’importance.
      • Désactiver temporairement le mode read_only.
    3. Démarrer le conteneur.
    4. Exécuter une shell dans le conteneur en tant que l’utilisateur postgres.
      • Supprimer le contenu du volume
    5. Construire une sauvegarde de base dans le dossier du volume : pg_basebackup -R -U <USER> -h <IPv4> -p <PORT> -D /var/lib/postgresql-pgbackup/data
      • L’option -R va directement écrire les paramètres de configuration nécessaires pour la réplication.
    6. Commenter les valeurs suivantes dans postgresql.conf :
    #wal_level = replica
    #wal_log_hints = on
    #max_wal_size = 1GB
    #min_wal_size = 80MB
    #max_wal_senders = 3
    
    1. Remplacer la valeur de listen_addresses par la ou les adresses appropriées pour l’instance standby.
    2. Arrêter le conteneur.
    3. Supprimer runtime.env, supprimer l’instruction env_file, réactiver le mode read_only et remonter le volume dans le dossier par défaut : /var/lib/postgresql/data/.
    4. Démarrer le conteneur. Si tout s’est bien passé, le conteneur devrait indiquer entering standby mode dans ses journaux.

    Note: Penser à effacer les volumes sans nom créés par l’instruction VOLUME lors de la création du conteneur.

    Resynchroniser une instance PostgreSQL standby perdue🔗

    Il arrive que la synchronisation soit perdue entre l’instance primaire de postgresql (sur balearica) et l’instance standby (sur antigone).

    En effet, le streaming WAL semble consister à demander à l’instance primaire déposer des sortes de fichiers « diff » dans un dossier. Ces fichiers sont récupérés par l’instance standby et lui servent à se mettre à jour. Mais ces fichiers ne sont stockés que de manière temporaire par l’instance primaire − cela dépend de la valeur wal_keep_size, qui est fixée chez nous à 128 MB. Nous pourrions également pallier à ce problème avec des archives wal, mais nous n’utilisons pas cette fonctionnalité.

    Un possible palliatif efficace serait d’utiliser les slots de réplication, mais cela nécessiterait de surveiller attentivement l’espace disque occupé par l’instance primaire.

    Si l’instance postgres standby reste trop longtemps désynchronisée de l’instance primaire, l’erreur suivante va se produire :

    FATAL:  could not receive data from WAL stream: ERROR:  requested WAL segment XXXXXXXXXXXXXXXXX has already been removed
    

    Le seul moyen de rétablir la synchronisation avec l’instance primaire est de reconstruire une sauvegarde de base du cluster. Il peut être envisageable d’utiliser les slots de réplication pour éviter que le problème ne se reproduise.

    Reconstruire l’instance standby avec une sauvegarde de base🔗

    Pour reconstruire de zéro une instance secondaire, il est nécessaire de partir d’une configuration vierge et d’utiliser la commande pg_basebackup.