PostgreSQL Sauvegardes et Réplication

Formation DBA3

Dalibo SCOP

24.09

29 août 2024

Sur ce document

Formation Formation DBA3
Titre PostgreSQL Sauvegardes et Réplication
Révision 24.09
ISBN N/A
PDF https://dali.bo/dba3_pdf
EPUB https://dali.bo/dba3_epub
HTML https://dali.bo/dba3_html
Slides https://dali.bo/dba3_slides

Licence Creative Commons CC-BY-NC-SA

Cette formation est sous licence CC-BY-NC-SA. Vous êtes libre de la redistribuer et/ou modifier aux conditions suivantes :

  • Paternité
  • Pas d’utilisation commerciale
  • Partage des conditions initiales à l’identique

Marques déposées

PostgreSQL® Postgres® et le logo Slonik sont des marques déposées par PostgreSQL Community Association of Canada.

Versions de PostgreSQL couvertes

Ce document ne couvre que les versions supportées de PostgreSQL au moment de sa rédaction, soit les versions 12 à 16.

PostgreSQL : Politique de sauvegarde

Datacenter victime d’un incendie, Strasbourg, mars 2021 (image ITBR67)

Introduction

  • Le pire peut arriver
  • Politique de sauvegarde

Au menu

  • Objectifs
  • Approche
  • Points d’attention

Définir une politique de sauvegarde

  • Pourquoi établir une politique ?
  • Que sauvegarder ?
  • À quelle fréquence sauvegarder les données ?
  • Quels supports ?
  • Quels outils ?
  • Vérifier la restauration des sauvegardes

Objectifs

  • Sécuriser les données
  • Mettre à jour le moteur de données
  • Dupliquer une base de données de production
  • Archiver les données

Différentes approches

  • Sauvegarde à froid des fichiers (ou physique)
  • Sauvegarde à chaud en SQL (ou logique)
  • Sauvegarde à chaud des fichiers (PITR)

RTO/RPO

La politique de sauvegarde découle du :

  • RPO (Recovery Point Objective) : Perte de Données Maximale Admissible
    • faible ou importante ?
  • RTO (Recovery Time Objective) : Durée Maximale d’Interruption Admissible
    • courte ou longue ?
RTO et RPO

Industrialisation

  • Évaluer les coûts humains et matériels
  • Intégrer les méthodes de sauvegardes avec le reste du SI
    • sauvegarde sur bande centrale
    • supervision
    • plan de continuité et de reprise d’activité

Documentation

  • Documenter les éléments clés de la politique :
    • perte de données
    • rétention
    • temps de référence
  • Documenter les processus de sauvegarde et restauration
  • Imposer des révisions régulières des procédures

Règle 3-2-1

  • 3 exemplaires des données
  • 2 sur différents médias
  • 1 hors site (et hors ligne)
  • Un RAID n’est pas une sauvegarde !
  • Le cloud n’est pas une solution magique !

Autres points d’attention

  • Sauvegarder les fichiers de configuration
  • Tester la restauration
    • De nombreuses catastrophes auraient pu être évitées avec un test
    • Estimation de la durée

Conclusion

  • Les techniques de sauvegarde de PostgreSQL sont :
    • complémentaires
    • automatisables
  • La maîtrise de ces techniques est indispensable pour assurer un service fiable.
  • Testez vos sauvegardes !

Quiz

Sauvegarde physique à chaud et PITR

PostgreSQL

Introduction

  • Sauvegarde traditionnelle
    • sauvegarde pg_dump à chaud
    • sauvegarde des fichiers à froid
  • Insuffisant pour les grosses bases
    • long à sauvegarder
    • encore plus long à restaurer
  • Perte de données potentiellement importante
    • car impossible de réaliser fréquemment une sauvegarde
  • Une solution : la sauvegarde PITR

Au menu

  • Mettre en place la sauvegarde PITR
    • sauvegarde : manuelle, ou avec pg_basebackup
    • archivage : manuel, ou avec pg_receivewal
  • Restaurer une sauvegarde PITR
  • Des outils

PITR

  • Point In Time Recovery
  • À chaud
  • En continu
  • Cohérente

Principes

  • Les journaux de transactions contiennent toutes les modifications
  • Il faut les archiver
    • …et avoir une image des fichiers à un instant t
  • La restauration se fait en restaurant cette image
    • …et en rejouant les journaux
    • dans l’ordre
    • entièrement
    • ou partiellement (ie jusqu’à un certain moment)

Avantages

  • Sauvegarde à chaud
  • Rejeu d’un grand nombre de journaux
  • Moins de perte de données

Inconvénients

  • Sauvegarde de l’instance complète
  • Nécessite un grand espace de stockage (données + journaux)
  • Risque d’accumulation des journaux
    • dans pg_wal en cas d’échec d’archivage… avec arrêt si il est plein !
    • dans le dépôt d’archivage si échec des sauvegardes
  • Restauration de l’instance complète
  • Impossible de changer d’architecture (même OS conseillé)
  • Plus complexe

Copie physique à chaud ponctuelle avec pg_basebackup

  • Réalise les différentes étapes d’une sauvegarde
    • via 1 ou 2 connexions de réplication + slots de réplication
    • base backup + journaux nécessaires
  • Copie intégrale,
    • image de la base à la fin du backup
  • Pas de copie incrémentale
  • Configuration : streaming (rôle, droits, slots)
$ pg_basebackup --format=tar --wal-method=stream \
 --checkpoint=fast --progress -h 127.0.0.1 -U sauve \
 -D /var/lib/postgresql/backups/

Sauvegarde PITR

2 étapes :

  • Archivage des journaux de transactions
    • archivage interne
    • ou outil pg_receivewal
  • Sauvegarde des fichiers
    • pg_basebackup
    • ou manuellement (outils de copie classiques)

Méthodes d’archivage

  • Deux méthodes :
    • processus interne archiver
    • outil pg_receivewal (flux de réplication)

Choix du répertoire d’archivage

  • À faire quelle que soit la méthode d’archivage
  • Attention aux droits d’écriture dans le répertoire
    • la commande configurée pour la copie doit pouvoir écrire dedans
    • et potentiellement y lire

Processus archiver : configuration

  • configuration (postgresql.conf)
    • wal_level = replica
    • archive_mode = on (ou always)
    • archive_command = '… une commande …'
    • ou : archive_library = '… une bibliothèque …' (v15+)
    • archive_timeout = '… min'
  • Ne pas oublier de forcer l’écriture de l’archive sur disque
  • Code retour de l’archivage entre 0 (ok) et 125

Processus archiver : lancement

  • Redémarrage de PostgreSQL
    • si modification de wal_level et/ou archive_mode
  • ou rechargement de la configuration

Processus archiver : supervision

  • Vue pg_stat_archiver
  • pg_wal/archive_status/
  • Taille de pg_wal
    • si saturation : Arrêt !
  • Traces

pg_receivewal

  • Archivage via le protocole de réplication
  • Enregistre en local les journaux de transactions
  • Permet de faire de l’archivage PITR
    • toujours au plus près du primaire
  • Slots de réplication obligatoires

pg_receivewal - configuration serveur

  • postgresql.conf :
# configuration  par défaut
max_wal_senders = 10
max_replication_slots = 10
  • pg_hba.conf :
host  replication  repli_user  192.168.0.0/24  scram-sha-256
  • Utilisateur de réplication :
CREATE ROLE repli_user LOGIN REPLICATION PASSWORD 'supersecret'

pg_receivewal - redémarrage du serveur

  • Redémarrage de PostgreSQL
  • Slot de réplication
SELECT pg_create_physical_replication_slot('archivage');

pg_receivewal - lancement de l’outil

  • Exemple de lancement
pg_receivewal -D /data/archives -S archivage
  • Journaux créés en temps réel dans le répertoire de stockage
  • Mise en place d’un script de démarrage
  • S’il n’arrive pas à joindre le serveur primaire
    • Au démarrage de l’outil : pg_receivewal s’arrête
    • En cours d’exécution : pg_receivewal tente de se reconnecter
  • Nombreuses options

Avantages et inconvénients

  • Méthode archiver
    • simple à mettre en place
    • perte au maximum d’un journal de transactions
  • Méthode pg_receivewal
    • mise en place plus complexe
    • perte minimale voire nulle

Sauvegarde PITR manuelle

  • 3 étapes :
    • fonction de démarrage
    • copie des fichiers par outil externe
    • fonction d’arrêt
  • Exclusive : simple… & obsolète ! (< v15)
  • Concurrente : plus complexe à scripter
  • Aucun impact pour les utilisateurs ; pas de verrou
  • Préférer des outils dédiés qu’un script maison

Sauvegarde manuelle - 1/3 : pg_backup_start

SELECT pg_backup_start (

  • un_label : texte
  • fast : forcer un checkpoint ?

)

Sauvegarde manuelle - 2/3 : copie des fichiers

  • Cas courant : snapshot
    • cohérence ? redondance ?
  • Sauvegarde des fichiers à chaud
    • répertoire principal des données
    • tablespaces
  • Copie forcément incohérente (la restauration des journaux corrigera)
  • rsync et autres outils
  • Ignorer :
    • postmaster.pid, log, pg_wal, pg_replslot et quelques autres
  • Ne pas oublier : configuration !

Sauvegarde manuelle - 3/3 : pg_backup_stop

Ne pas oublier !!

SELECT * FROM pg_backup_stop (

  • true : attente de l’archivage

)

Sauvegarde de base à chaud : pg_basebackup

Outil de sauvegarde pouvant aussi servir au sauvegarde basique

  • Backup de base ici sans les journaux :
$ pg_basebackup --format=tar --wal-method=none \
 --checkpoint=fast --progress -h 127.0.0.1 -U sauve \
 -D /var/lib/postgresql/backups/

Fréquence de la sauvegarde de base

  • Dépend des besoins
  • De tous les jours à tous les mois
  • Plus elles sont espacées, plus la restauration est longue
    • et plus le risque d’un journal corrompu ou absent est important

Suivi de la sauvegarde de base

  • Vue pg_stat_progress_basebackup
    • à partir de la v13

Restaurer une sauvegarde PITR

  • Une procédure relativement simple
  • Mais qui doit être effectuée rigoureusement

Restaurer une sauvegarde PITR (1/5)

  • S’il s’agit du même serveur
    • arrêter PostgreSQL
    • supprimer le répertoire des données
    • supprimer les tablespaces

Restaurer une sauvegarde PITR (2/5)

  • Restaurer les fichiers de la sauvegarde
  • Supprimer les fichiers compris dans le répertoire pg_wal restauré
    • ou mieux, ne pas les avoir inclus dans la sauvegarde initialement
  • Restaurer le dernier journal de transactions connu (si disponible)

Restaurer une sauvegarde PITR (3/5)

  • Indiquer qu’on est en restauration

  • Commande de restauration

    • restore_command = '… une commande …'
    • dans postgresql.[auto.]conf

Restaurer une sauvegarde PITR (4/5)

  • Jusqu’où restaurer :
    • recovery_target_name, recovery_target_time
    • recovery_target_xid, recovery_target_lsn
    • recovery_target_inclusive
  • Le backup de base doit être antérieur !
  • Suivi de timeline :
    • recovery_target_timeline : latest ?
  • Et on fait quoi ?
    • recovery_target_action : pause
    • pg_wal_replay_resume pour ouvrir immédiatement
    • ou modifier & redémarrer

Restaurer une sauvegarde PITR (5/5)

  • Démarrer PostgreSQL
  • Rejeu des journaux
  • Vérifier que le point de cohérence est atteint !

Restauration PITR : durée

  • Durée dépendante du nombre de journaux
    • rejeu séquentiel des WAL
  • Accéléré en version 15 (prefetch)

Restauration PITR : différentes timelines

  • Fin de recovery => changement de timeline :
    • l’historique des données prend une autre voie
    • le nom des WAL change
    • fichiers .history
  • Permet plusieurs restaurations PITR à partir du même basebackup
  • Choix :recovery_target_timeline
    • défaut : latest

Restauration PITR : illustration des timelines

Les timelines

Après la restauration

  • Bien vérifier que l’archivage a repris
    • et que les archives des journaux sont complètes
  • Ne pas hésiter à reprendre une sauvegarde complète
  • Bien vérifier que les secondaires ont suivi

Pour aller plus loin

  • Limiter la volumétrie des journaux sauvegardés
  • Quels sont les outils PITR ?

Réduire le nombre de journaux sauvegardés

Volumétrie archivée en fonction de checkpoint_timeout

  • Monter
    • checkpoint_timeout
    • max_wal_size

Compresser les journaux de transactions

  • wal_compression
    • moins de journaux
    • un peu plus de CPU
    • à activer
  • Outils de compression standards : gzip, bzip2, lzma
    • attention à ne pas ralentir l’archivage

Outils de sauvegarde PITR dédiés

  • Se faciliter la vie avec différents outils
    • pgBackRest
    • barman
    • pitrery (< v15, déprécié)
  • Fournissent :
    • un outil pour les backups, les purges…
    • une commande pour l’archivage

pgBackRest

  • Gère la sauvegarde et la restauration
    • pull ou push, multidépôts
    • mono- ou multiserveur
  • Indépendant des commandes système
    • protocole dédié
  • Sauvegardes complètes, différentielles ou incrémentales
  • Multithread, sauvegarde depuis un secondaire, archivage asynchrone…
  • Projet mature

barman

  • Gère la sauvegarde et la restauration
    • mode pull
    • multiserveurs
  • Une seule commande (barman)
  • Et de nombreuses actions
    • list-server, backup, list-backup, recover
  • Spécificité : gestion de pg_receivewal

pitrery

  • Projet en fin de vie, non compatible v15+
  • Gère la sauvegarde et la restauration
    • mode push
    • mono-serveur
  • Multi-commandes
    • archive_wal
    • pitrery
    • restore_wal

Conclusion

  • Une sauvegarde
    • fiable
    • éprouvée
    • rapide
    • continue
  • Mais
    • plus complexe à mettre en place que pg_dump
    • qui restaure toute l’instance

Questions

N’hésitez pas, c’est le moment !

Quiz

Installation de PostgreSQL depuis les paquets communautaires

Introduction à pgbench

Travaux pratiques

pg_basebackup : sauvegarde ponctuelle & restauration

pg_basebackup : sauvegarde ponctuelle & restauration des journaux suivants

Travaux pratiques (solutions)

PostgreSQL : Outils de sauvegarde physique

PostgreSQL

Introduction

  • 2 mécanismes de sauvegarde natifs et robustes
  • Industrialisation fastidieuse
  • Des outils existent !!

Au menu

  • Présentation:
    • pg_basebackup
    • pgBackRest
    • Barman
  • Comment choisir ?

Préalable : définir les besoins

  • Sauvegarde locale (ex. NFS) ?
  • Copie vers un serveur tiers (push) ?
  • Sauvegarde distante initiée depuis un serveur tiers (pull) ?
  • Ressources à disposition ?
  • Accès SSH ?
  • OS ?
  • Sauvegardes physiques ? Logiques ?
  • Version de PostgreSQL ?
  • Politique de rétention ?

pg_basebackup

pg_basebackup - Présentation

  • Outil intégré à PostgreSQL
  • Prévu pour créer une instance secondaire
  • Pour sauvegarde ponctuelle
    • PITR avec outils complémentaires

pg_basebackup - Formats de sauvegarde

  • --format plain
    • arborescence identique à l’instance sauvegardée
  • --format tar
    • archive
    • compression : -z, -Z (0..9)

pg_basebackup - Avantages

  • Transfert des WAL pendant la sauvegarde
  • Slot de réplication automatique (temporaire voire permanent)
  • Limitation du débit
  • Relocalisation des tablespaces
  • Fichier manifeste (v13+)
  • Vérification des checksums
  • Sauvegarde possible à partir d’un secondaire
  • Compression côté serveur ou client (v15+)
  • Emplacement de la sauvegarde (client/server/blackhole) (v15+)
  • Suivi : pg_stat_progress_basebackup (v13+)

pg_basebackup - Limitations

  • Configuration streaming nécessaire
  • Pas de configuration de l’archivage
  • Pas d’association WAL archivés / sauvegarde
  • Pas de politique de rétention
    • sauvegarde ponctuelle
  • Pas de gestion de la restauration !
    • manuel : recovery.signal, restore_command
    • pour un secondaire : --write-recovery-conf

pgBackRest

PgbackRest

pgBackRest - Présentation générale

  • David Steele (Crunchy Data)
  • Langage : C
  • License : MIT (libre)
  • Type d’interface : CLI (ligne de commande)

pgBackRest - Fonctionnalités

  • Gère la sauvegarde et la restauration
    • pull ou push, multidépôts
    • mono- ou multiserveur
  • Indépendant des commandes système
    • protocole dédié
  • Sauvegardes complètes, différentielles ou incrémentales
  • Multithread, sauvegarde depuis un secondaire, archivage asynchrone…
  • Projet mature

pgBackRest - Sauvegardes

  • Type de sauvegarde : physique/PITR (à chaud)
  • Type de stockage : local, push ou pull
  • Planification : crontab (ou autre)
  • Complètes, différentielles et incrémentales
  • Compression des WAL

pgBackRest - Restauration

  • Depuis le serveur de BDD avec un dépôt local ou à distance
  • Point dans le temps : date, identifiant de transaction, timeline ou point de restauration

pgBackRest - Installation

  • Accéder au dépôt communautaire PGDG
  • Installer le paquet pgbackrest

pgBackRest - Utilisation

Usage:
    pgbackrest [options] [command]

Commands:
    annotate        Add or modify backup annotation.
    archive-get     Get a WAL segment from the archive.
    archive-push    Push a WAL segment to the archive.
    backup          Backup a database cluster.
    check           Check the configuration.
    expire          Expire backups that exceed retention.
    help            Get help.
    info            Retrieve information about backups.
    repo-get        Get a file from a repository.
    repo-ls         List files in a repository.
    restore         Restore a database cluster.
    server          pgBackRest server.
    server-ping     Ping pgBackRest server.
    stanza-create   Create the required stanza data.
    stanza-delete   Delete a stanza.
    stanza-upgrade  Upgrade a stanza.
    start           Allow pgBackRest processes to run.
    stop            Stop pgBackRest processes from running.
    verify          Verify contents of the repository.
    version         Get version.

pgBackRest - Configuration

  • /etc/pgbackrest.conf
  • Configuration générale dans la section [global]
  • Chaque instance à sauvegarder doit avoir sa propre section, appelée stanza
  • possibilité d’éclater la configuration dans plusieurs fichiers : config-include-path

pgBackRest - Configuration PostgreSQL

  • Adapter l’archivage dans le fichier postgresql.conf
archive_mode = on
wal_level = replica
archive_command = 'pgbackrest --stanza=erp_prod archive-push %p'
archive_timeout = '? min'   # à définir

pgBackRest - Configuration globale

  • Fichier pgbackrest.conf
  • Section [global] pour la configuration globale
[global]
process-max=1
repo1-path=/var/lib/pgbackrest

pgBackRest - Configuration de la rétention

  • Type de rétention des sauvegardes complètes
repo1-retention-full-type=count|time
  • Nombre de sauvegardes complètes
repo1-retention-full=2
  • Nombre de sauvegardes différentielles
repo1-retention-diff=3

pgBackRest - Configuration SSH

  • Utilisateur postgres pour les serveurs PostgreSQL
  • Échanger les clés SSH publiques entre les serveurs PostgreSQL et le serveur de sauvegarde
  • Configurer repo1-host* dans la pgbackrest.conf

pgBackRest - Configuration TLS

  • Alternative au SSH
  • {repo1|pg1}-host-type = tls
  • paramètres tls-server-{address|auth|cert|key|ca}
  • paramètres repo1-host-{cert|key|ca}
  • paramètres pg1-host-{cert|key|ca}
  • pgbackrest server

pgBackRest - Configuration par instance

  • Une section par instance
    • appelée stanza

pgBackRest - Exemple configuration par instance

  • Section spécifique par instance
  • Permet d’adapter la configuration aux différentes instances
  • Exemple
[erp_prod]
pg1-path=/var/lib/pgsql/10/data

pgBackRest - Initialiser le répertoire de stockage des sauvegardes

  • Pour initialiser le répertoire de stockage des sauvegardes
$ sudo -u postgres pgbackrest --stanza=erp_prod stanza-create
  • Vérifier la configuration de l’archivage
$ sudo -u postgres pgbackrest --stanza=erp_prod check

pgBackRest - Effectuer une sauvegarde

  • Pour déclencher une nouvelle sauvegarde complète
$ sudo -u postgres pgbackrest --stanza=erp_prod --type=full backup
  • Types supportés : incr, diff, full
  • La plupart des paramètres peuvent être surchargés

pgBackRest - Lister les sauvegardes

  • Lister les sauvegardes présentes et leur taille
$ sudo -u postgres pgbackrest --stanza=erp_prod info
  • ou une sauvegarde spécifique (backup set)
$ sudo -u postgres pgbackrest --stanza=erp_prod --set 20221026-071751F info

pgBackRest - Dépôts

  • Plusieurs dépôts simultanés possibles
    • sauvegarde par dépôt selon rétention
    • archivage sur tous les dépôts (asynchrone conseillé!)
    • --repo1-option=… , appel avec --repo=1
  • POSIX (NFS, ssh), CIFS, SFTP, cloud (S3, Azure, GFS)

pgBackRest - bundling et sauvegarde incrémentale en mode block

  • Regrouper les petits fichiers dans des bundles
repo1-bundle=y
  • Sauvegarde incrémentale en mode block (requiert le bundling)
repo1-bundle=y
repo1-block=y

pgBackRest - Restauration

  • Effectuer une restauration
$ sudo -u postgres pgbackrest --stanza=erp_prod restore
  • Nombreuses options à la restauration, notamment :
    • --delta
    • --target / --type

Barman

Barman

Barman - Présentation générale

  • 2ndQuadrant Italia
  • Langage: python >= 3.4
  • OS: Unix/Linux
  • Versions compatibles: >= 8.3
  • License: GPL3 (libre)
  • Type d’interface: CLI (ligne de commande)

Barman - Scénario « streaming-only »

Architecture barman 1

Barman - Scénario « rsync-over-ssh »

Architecture barman 2

Barman - Sauvegardes

  • Type de sauvegarde : physique/PITR (à chaud)
  • Type de stockage : local ou pull
  • Planification : crontab
  • Méthodes :
    • pg_backup_start() / rsync / pg_backup_stop()
    • pg_basebackup / pg_receivewal
  • Incrémentales : si rsync + hardlink
  • Compression des WAL

Barman - Sauvegardes (suite)

  • Limitation du débit réseau lors des transferts
  • Compression des données lors des transferts via le réseau
  • Sauvegardes concurrentes
  • Hook pre/post sauvegarde
  • Hook pre/post archivage WAL
  • Compression WAL : gzip, bzip2, pigz, pbzip2, etc.
  • Compression des données via pg_basebackup

Barman - Politique de rétention

  • Durée (jour/semaine)
  • Nombre de sauvegardes

Barman - Restauration

  • Locale ou à distance
  • Point dans le temps : date, identifiant de transaction, timeline ou point de restauration

Barman - Installation

  • Accéder au dépôt communautaire PGDG
  • Installer les paquets barman et barman-cli

Barman - Utilisation

usage: barman [-h] [-v] [-c CONFIG] [--color {never,always,auto}] [-q] [-d]
              [-f {json,console}]

          {archive-wal,backup,check,check-backup,check-wal-archive,cron,
          delete,diagnose,generate-manifest,get-wal,help,keep,list-backup,
          list-backups,list-files,list-server,list-servers,put-wal,
          rebuild-xlogdb,receive-wal,recover,replication-status,show-backup,
          show-backups,show-server,show-servers,status,switch-wal,switch-xlog,
          sync-backup,sync-info,sync-wals,verify,verify-backup}

[...]
optional arguments:
  -h, --help            show this help message and exit
  -v, --version         show program's version number and exit
  -c CONFIG, --config CONFIG
                        uses a configuration file (defaults: ~/.barman.conf,
                        /etc/barman.conf, /etc/barman/barman.conf)
  --color {never,always,auto}, --colour {never,always,auto}
                        Whether to use colors in the output (default: 'auto')
  -q, --quiet           be quiet (default: False)
  -d, --debug           debug output (default: False)
  -f {json,console}, --format {json,console}
                        output format (default: 'console')

Barman - Configuration

  • /etc/barman.conf
  • Format INI
  • Configuration générale dans la section [barman]
  • Chaque instance à sauvegarder doit avoir sa propre section
  • Un fichier de configuration par instance via la directive :
configuration_files_directory = /etc/barman.d

Barman - Configuration utilisateur

  • Utilisateur système barman

Barman - Configuration SSH

  • Utilisateur postgres pour les serveurs PostgreSQL
  • Utilisateur barman pour le serveur de sauvegardes
  • Générer les clés SSH (RSA) des utilisateurs système postgres (serveurs PG) et barman (serveur barman)
  • Échanger les clés SSH publiques entre les serveurs PostgreSQL et le serveur de sauvegarde
  • Établir manuellement une première connexion SSH entre chaque machine
  • Inutile si utilisation de pg_basebackup / pg_receivewal

Barman - Configuration PostgreSQL

  • Adapter la configuration de l’archivage dans le fichier postgresql.conf :
wal_level = 'replica'
archive_mode = on
archive_command = 'barman-wal-archive backup-srv pgsrv %p'
  • … ou paramétrer la réplication si utilisation de pg_basebackup / pg_receivewal

Barman - Configuration globale

  • barman.conf
[barman]
barman_home = /var/lib/barman
barman_user = barman
log_file = /var/log/barman/barman.log
log_level = INFO
configuration_files_directory = /etc/barman.d

Barman - Configuration sauvegardes

  • Configuration globale des options de sauvegarde
compression = gzip
backup_compression = gzip
immediate_checkpoint = false
basebackup_retry_times = 0
basebackup_retry_sleep = 30

Barman - Configuration réseau

  • Possibilité de réduire la bande passante
  • Et de compresser le trafic réseau
  • Exemple
bandwidth_limit = 4000
network_compression = false

Barman - Configuration rétention

  • Configuration de la rétention en nombre de sauvegardes
  • Ou en « fenêtre de restauration », en jours, semaines ou mois
  • Déclenchement d’une erreur en cas de sauvegarde trop ancienne
  • Exemple
minimum_redundancy = 5
retention_policy = RECOVERY WINDOW OF 7 DAYS
last_backup_maximum_age = 2 DAYS

Barman - Configuration des hooks

  • Lancer des scripts avant ou après les sauvegardes
  • Et avant ou après le traitement du WAL archivé par Barman
  • Exemple :
pre_backup_script = ...
post_backup_script = ...
pre_archive_script = ...
post_archive_script = ...

Barman - Configuration d’un dépôt synchronisé

  • Copie à l’identique du dépôt d’origine
  • Sur le dépôt à synchroniser :
    • primary_ssh_command
  • Commandes :
    • barman sync-info --primary <instance> <ID-sauvegarde>
    • barman sync-backup <instance> <ID-sauvegarde>
    • barman sync-wal <instance>

Barman - Configuration par instance

  • configuration_files_directory
    • un fichier de configuration par instance
  • Ou une section par instance

Barman - Exemple configuration par instance

  • Section spécifique par instance
  • Permet d’adapter la configuration aux différentes instances
  • Exemple
[pgsrv]
description = "PostgreSQL Instance pgsrv"
ssh_command = ssh postgres@pgsrv
conninfo = host=pgsrv user=postgres dbname=postgres
backup_method = rsync
reuse_backup = link
backup_options = exclusive_backup
archiver = on

Barman - Exemple configuration Streaming Only

[pgsrv]
description =  "Sauvegarde de pgsrv via Streaming Replication"
conninfo = host=pgsrv user=barman dbname=postgres
streaming_conninfo = host=pgsrv user=streaming_barman
backup_method = postgres
streaming_archiver = on
create_slot = auto
slot_name = barman
  • barman replication-status pgsrv

Barman - Vérification de la configuration

  • La commande show-server montre la configuration
$ sudo -u barman barman show-server {<instance> | all}
  • La commande check effectue des tests pour la valider
$ sudo -u barman barman check {<instance> | all}
$ sudo -u barman barman check {<instance> | all} --nagios

Barman - Statut

  • La commande status affiche des informations détaillées
    • sur la configuration Barman
    • sur l’instance spécifiée
  • Exemple
$ sudo -u barman barman status {<instance> | all}

Barman - Diagnostiquer

  • La commande diagnose renvoie
    • les informations renvoyées par la commande status
    • des informations supplémentaires (sur le système par exemple)
    • au format json
  • Exemple
$ sudo -u barman barman diagnose

Barman - Nouvelle sauvegarde

  • Pour déclencher une nouvelle sauvegarde
$ sudo -u barman barman backup {<instance> | all} [--wait]
  • Le détail de sauvegarde effectuée est affiché en sortie

Barman - Lister les sauvegardes

  • Pour lister les sauvegardes existantes
$ sudo -u barman barman list-backup {<instance> | all}
  • Affiche notamment la taille de la sauvegarde et des WAL associés

Barman - Détail d’une sauvegarde

  • show-backup affiche le détail d’une sauvegarde (taille…)
$ sudo -u barman barman show-backup <instance> <ID-sauvegarde>
  • list-files affiche le détail des fichiers d’une sauvegarde
$ sudo -u barman barman list-files <instance> <ID-sauvegarde>

Barman - Suppression d’une sauvegarde

  • Pour supprimer manuellement une sauvegarde
$ sudo -u barman barman delete <instance> <ID-sauvegarde>
  • Renvoie une erreur si la redondance minimale ne le permet pas

Barman - Conserver une sauvegarde

  • Pour conserver une sauvegarde
$ sudo -u barman barman keep <instance> <ID-sauvegarde>
  • Pour relâcher une sauvegarde
$ sudo -u barman barman keep --release <instance> <ID-sauvegarde>

Barman - Tâches de maintenance

  • La commande Barman cron déclenche la maintenance
    • récupération des WAL archivés
    • compression
    • politique de rétention
    • démarrage de pg_receivewal
  • Exemple
$ sudo -u barman barman cron
  • À planifier ! (vérifier /etc/cron.d/barman)

Barman - Restauration

  • Copie/transfert de la sauvegarde
  • Copie/transfert des journaux de transactions
  • Génère le paramétrage pour la restauration
  • Copie/transfert des fichiers de configuration

Barman - Options de restauration

  • Locale ou à distance
  • Cibles : timeline, date, ID de transaction ou point de restauration
  • Déplacement des tablespaces

Barman - Exemple de restauration à distance

  • Exemple d’une restauration
    • déclenchée depuis le serveur Barman
    • avec un point dans le temps spécifié
$ sudo -u barman barman recover                   \
    --remote-ssh-command "ssh postgres@pgsrv"     \
    --target-time "2019-12-11 14:00:00"           \
    pgsrv 20191211T121244 /var/lib/pgsql/12/data/

pitrery

pitrery - Présentation générale

  • R&D Dalibo

  • Langage : bash

  • OS : Unix/Linux

  • Versions compatibles : 8.2 à 14 (pas 15+)

  • Développement arrêté, ne plus utiliser

Autres outils de l’écosystème

  • De nombreux autres outils existent
    • …ou ont existé
  • WAL-E, OmniPITR, pg_rman, walmgr…
  • WAL-G

WAL-G - présentation

  • Successeur de WAL-E, par Citus Data & Yandex
  • Orientation cloud
  • Aussi pour MySQL et SQL Server

Conclusion

  • Des outils pour vous aider !
  • Pratiquer, pratiquer et pratiquer
  • Superviser les sauvegardes !

Quiz

Travaux pratiques

Utilisation de pgBackRest (Optionnel)

Utilisation de barman (Optionnel)

Travaux pratiques (solutions)

Solutions de réplication

PostgreSQL

Préambule

  • Attention au vocabulaire !
  • Identifier le besoin
  • Keep It Simple…

Au menu

  • Rappels théoriques
  • Réplication interne
    • réplication physique
    • réplication logique
  • Quelques logiciels externes de réplication
  • Alternatives

Objectifs

  • Identifier les différences entre les solutions de réplication proposées
  • Choisir le système le mieux adapté à votre besoin

Rappels théoriques

  • Termes
  • Réplication
    • synchrone / asynchrone
    • symétrique / asymétrique
    • diffusion des modifications

Cluster, primaire, secondaire, standby

  • Cluster : ambiguïté !
    • groupe de bases de données = 1 instance (PostgreSQL)
    • groupe de serveurs (haute disponibilité et/ou réplication)
  • Pour désigner les membres :
    • Primaire/primary
    • Secondaire/standby

Réplication asynchrone asymétrique

  • Asymétrique
    • écritures sur un serveur primaire unique
    • lectures sur le primaire et/ou les secondaires
  • Asynchrone
    • les écritures sur les serveurs secondaires sont différées
    • perte de données possible en cas de crash du primaire
  • Exemples :
    • réplication par streaming, log shipping, trigger

Réplication asynchrone symétrique

  • Symétrique
    • « multimaître »
    • écritures sur les différents primaires
    • besoin d’un gestionnaire de conflits
    • lectures sur les différents primaires
  • Asynchrone
    • la réplication des écritures est différées
    • perte de données possible en cas de crash du serveur primaire
    • risque d’incohérences !
  • Exemples :
    • BDR (EDB) : réplication logique

Réplication synchrone asymétrique

  • Asymétrique
    • écritures sur un serveur primaire unique
    • lectures sur le serveur primaire et/ou les secondaires
  • Synchrone
    • les écritures sur les secondaires sont immédiates
    • le client sait si sa commande a réussi sur plusieurs serveurs

Réplication synchrone symétrique

  • Symétrique
    • écritures sur les différents serveurs primaires
    • besoin d’un gestionnaire de conflits
    • lectures sur les différents serveurs
  • Synchrone
    • les écritures sur les autres serveurs sont immédiates
    • le client sait si sa commande est validée sur plusieurs serveurs
    • risque important de lenteur !

Diffusion des modifications

  • Par requêtes
    • diffusion de la requête
  • Par triggers
    • diffusion des données résultant de l’opération
  • Par journaux, physique
    • diffusion des blocs disques modifiés
  • Par journaux, logique
    • extraction et diffusion des données résultant de l’opération depuis les journaux

Réplication interne physique

  • Réplication
    • asymétrique
    • asynchrone (défaut) ou synchrone (et selon les transactions)
  • Secondaires
    • non disponibles (Warm Standby)
    • disponibles en lecture seule (Hot Standby)
    • cascade
    • retard programmé

Log Shipping

  • But :
    • envoyer les journaux de transactions à un secondaire
  • Première solution disponible
  • Gros inconvénients :
    • perte possible de plusieurs journaux
    • latence à la réplication
    • penser à archive_timeout ou pg_receivewal

Streaming replication

  • But
    • avoir un retard moins important sur le serveur secondaire
  • Rejouer les enregistrements de transactions du serveur primaire par paquets
    • paquets plus petits qu’un journal de transactions

Warm Standby

  • Serveur de secours
    • prêt à prendre le relai du primaire
    • (presque) identique au primaire
  • Différentes configurations selon les versions
    • asynchrone ou synchrone
    • application immédiate ou retardée
  • En pratique, préférer le Hot Standby

Hot Standby

  • Serveur secondaire
    • accepte les connexions entrantes
    • requêtes en lecture seule et sauvegardes
    • prêt à prendre le relai du primaire
  • Différentes configurations selon les versions
    • asynchrone ou synchrone
    • application immédiate ou retardée

Exemple

Exemple d’architecture

Réplication interne

Réplication interne

Réplication en cascade

Réplication en cascade

Réplication interne logique

  • Réplique les changements
    • d’une seule base de données
    • d’un ensemble de tables défini
  • Principe Éditeur/Abonnés

Réplication logique - Fonctionnement

  • Création d’une publication sur un serveur
  • Souscription d’un autre serveur à cette publication
  • Limitations :
    • DDL, Large objects, séquences, tables étrangères et vues matérialisées non répliqués
    • peu adaptée pour un failover

Réplication externe

  • Outils les plus connus :
    • Pgpool
    • Slony, Bucardo (abandonnés)
    • pgLogical
  • Niches

Sharding

  • Répartition des données sur plusieurs instances
  • Évolution horizontale en ajoutant des serveurs
  • Parallélisation
  • Clé de répartition cruciale
  • Administration complexifiée
  • Sous PostgreSQL :
    • Foreign Data Wrapper
    • PL/Proxy
    • Citus (extension), et nombreux forks

Réplication bas niveau

  • RAID
  • DRBD
  • SAN Mirroring
  • À prendre évidemment en compte…

RAID

  • Obligatoire
  • Fiabilité d’un serveur
  • RAID 1 ou RAID 10
  • RAID 5 déconseillé (performances)
  • Lectures plus rapides
    • dépend du nombre de disques impliqués

DRBD

  • Simple / synchrone / Bien documenté
  • Lent / Secondaire inaccessible / Linux uniquement

SAN Mirroring

  • Comparable à DRBD
  • Solution intégrée
  • Manque de transparence

Conclusion

Quelle que soit la solution envisagée :

  • Bien définir son besoin
  • Identifier tous les SPOF
  • Superviser son cluster
  • Tester régulièrement les procédures de failover (Loi de Murphy…)

Questions

N’hésitez pas, c’est le moment !

Quiz

Réplication physique : fondamentaux

PostgreSQL

Introduction

  • Principes
  • Mise en place
  • Administration

Objectifs

  • Connaître les avantages et limites de la réplication physique
  • Savoir la mettre en place
  • Savoir administrer et superviser une solution de réplication physique

Concepts / principes

  • Les journaux de transactions contiennent toutes les modifications
    • utilisation du contenu des journaux
  • Le serveur secondaire doit posséder une image des fichiers à un instant t
  • La réplication modifiera les fichiers
    • d’après le contenu des journaux suivants

Principales évolutions de la réplication physique

  • 8.2 : Réplication par journaux (log shipping), Warm Standby
  • 9.0 : Réplication en streaming, Hot Standby
  • 9.1 à 9.3 : Réplication synchrone, cascade, pg_basebackup
  • 9.4 : Slots de réplication, délai de réplication, décodage logique
  • 9.5 : pg_rewind, archivage depuis un serveur secondaire
  • 9.6 : Rejeu synchrone
  • 10 : Réplication synchrone sur base d’un quorum, slots temporaires
  • 12 : Déplacement de la configuration du recovery.conf vers le postgresql.conf
  • 13 : Sécurisation des slots
  • 15 : rejeu accéléré

Avantages

  • Système de rejeu éprouvé
  • Mise en place simple
  • Pas d’arrêt ou de blocage des utilisateurs
  • Réplique tout

Inconvénients

  • Réplication de l’instance complète
  • Serveur secondaire uniquement en lecture
  • Impossible de changer d’architecture
  • Même version majeure de PostgreSQL pour tous les serveurs

Mise en place de la réplication par streaming

  • Réplication en flux
  • Un processus du serveur primaire discute avec un processus du serveur secondaire
    • d’où un lag moins important
  • Asynchrone ou synchrone
  • En cascade

Serveur primaire (1/2) - Configuration

Dans postgresql.conf :

  • wal_level = replica (ou logical)
  • max_wal_senders = X
    • 1 par client par streaming
    • défaut : 10
  • wal_sender_timeout = 60s

Serveur primaire (2/2) - Authentification

  • Le serveur secondaire doit pouvoir se connecter au serveur primaire
  • Pseudo-base replication
  • Utilisateur dédié conseillé avec attributs LOGIN et REPLICATION
  • Configurer pg_hba.conf :
   host replication user_repli 10.2.3.4/32   scram-sha-256
  • Recharger la configuration

Serveur secondaire (1/4) - Copie des données

Copie des données du serveur primaire (à chaud !) :

  • Copie généralement à chaud donc incohérente !
  • Le plus simple : pg_basebackup
    • simple mais a des limites
  • Idéal : outil PITR
  • Possible : rsync, cp
    • ne pas oublier pg_backup_start()/pg_backup_stop() !
    • exclure certains répertoires et fichiers
    • garantir la disponibilité des journaux de transaction

Serveur secondaire (2/4) - Fichiers de configuration

  • postgresql.conf & postgresql.auto.conf
    • paramètres
  • standby.signal (dans PGDATA)
    • vide

Serveur secondaire (2/4) - Paramètres

  • primary_conninfo (streaming) :
primary_conninfo = 'user=postgres host=prod port=5434
 passfile=/var/lib/postgresql/.pgpass
 application_name=secondaire2 '
  • Optionnel :
    • primary_slot_name
    • recovery_command
    • wal_receiver_timeout

Serveur secondaire (3/4) - Démarrage

  • Démarrer PostgreSQL
  • Suivre dans les traces que tout va bien

Processus

Sur le primaire :

  • walsender ... streaming 0/3BD48728

Sur le secondaire :

  • walreceiver streaming 0/3BD48728

Promotion

  • Attention au split-brain !
  • Vérification avant promotion
  • Promotion : méthode et déroulement
  • Retour à l’état stable

Attention au split-brain !

  • Si un serveur secondaire devient le nouveau primaire
    • s’assurer que l’ancien primaire ne reçoit plus d’écriture
  • Éviter que les deux instances soient ouvertes aux écritures
    • confusion et perte de données !

Vérification avant promotion

  • Primaire :
# systemctl stop postgresql-14
$ pg_controldata -D /var/lib/pgsql/14/data/ \
| grep -E '(Database cluster state)|(REDO location)'
Database cluster state:               shut down
Latest checkpoint's REDO location:    0/3BD487D0
  • Secondaire :
$ psql -c 'CHECKPOINT;'
$ pg_controldata -D /var/lib/pgsql/14/data/ \
| grep -E '(Database cluster state)|(REDO location)'
Database cluster state:               in archive recovery
Latest checkpoint's REDO location:    0/3BD487D0

Promotion du standby : méthode

  • Shell :
    • pg_ctl promote
  • SQL :
    • fonction pg_promote()
  • Déclenchement par fichier :
    • promote_trigger_file(<=v15)

Promotion du standby : déroulement

Une promotion déclenche :

  • déconnexion de la streaming replication (bascule programmée)
  • rejeu des dernières transactions en attente d’application
  • choix d’une nouvelle timeline du journal de transaction
  • suppression du fichier standby.signal
  • nouvelle timeline et fichier .history
  • ouverture aux écritures

Opérations après promotion du standby

  • VACUUM ANALYZE conseillé
    • calcul d’informations nécessaires pour autovacuum

Retour à l’état stable

  • Si un standby a été momentanément indisponible, reconnexion directe possible si :
    • journaux nécessaires encore présents sur primaire (slot, wal_keep_size/wal_keep_segments)
    • journaux nécessaires présents en archives (restore_command)
  • Sinon
    • « décrochage »
    • reconstruction nécessaire

Retour à l’état stable, suite

  • Synchronisation automatique une fois la connexion rétablie
  • Mais reconstruction obligatoire :
    • si le serveur secondaire était plus avancé que le serveur promu (« divergence »)
  • Reconstruire les serveurs secondaires à partir du nouveau principal :
    • rsync, restauration PITR, plutôt que pg_basebackup
    • pg_rewind
  • Reconstruction : manuelle !
  • Tablespaces !

Conclusion

  • Système de réplication fiable
  • Simple à maîtriser et à configurer

Quiz

Travaux pratiques

Sur Rocky Linux 8 ou 9

Réplication asynchrone en flux avec un seul secondaire

Promotion de l’instance secondaire

Retour à la normale

Sur Debian 12

Réplication asynchrone en flux avec un seul secondaire

Promotion de l’instance secondaire

Retour à la normale

Travaux pratiques (solutions)

Sur Rocky Linux 8 ou 9

Sur Debian 12

Réplication physique avancée

PostgreSQL

Introduction

  • Supervision
  • Fonctionnalités avancées

Au menu

  • Supervision
  • Gestion des conflits
  • Asynchrone ou synchrone
  • Réplication en cascade
  • Slot de réplication
  • Log shipping

Supervision (streaming)

  • Quelles vues et fonctions utilitaires ?
  • Comment voir et calculer le retard des secondaires ?

Utilitaires pour le streaming

  • pg_is_in_recovery() : instance en réplication ?
  • Calcul du retard en octets :
-- primaire
SELECT pg_wal_lsn_diff ( pg_current_wal_lsn(), '0/73D3C1F0' );
  • et en temps
-- secondaire
SELECT now() - pg_last_xact_replay_timestamp() ; -- si activité

pg_stat_replication

Type de réplication & lag des secondaires :

SELECT * FROM pg_stat_replication ;
-[ RECORD 1 ]----+------------------------------
pid              | 286511
usesysid         | 10
usename          | postgres
application_name | secondaire2
client_addr      | 192.168.0.55
client_hostname  | 
client_port      | -1
backend_start    | 2023-12-19 10:41:47.431471+01
backend_xmin     | 
state            | streaming
sent_lsn         | 14/C402A000
write_lsn        | 14/C402A000
flush_lsn        | 14/C402A000
replay_lsn       | 14/C311D460
write_lag        | 00:00:00.032183
flush_lag        | 00:00:00.032601
replay_lag       | 00:00:02.984354
sync_priority    | 1
sync_state       | sync
reply_time       | 2023-12-19 11:05:37.903584+01

Autres vues pour le streaming

  • S’il y un slot
    • pg_replication_slots
  • Sur le secondaire
    • pg_stat_wal_receiver

Supervision (log shipping)

  • Le primaire ne sait rien
  • Supervision de l’archivage comme pour du PITR
    • pg_stat_archiver
  • Secondaire :
    • pg_wal_lsn_diff()
    • traces
    • calcul du retard manuel (pg_last_wal_replay_lsn())

Conflits de réplication

Détection des conflits de réplication

  • Une requête en lecture pose des verrous
    • conflit possible avec changements répliqués !
  • Vue pg_stat_database_conflicts (secondaires)
  • Traces :
    • log_recovery_conflict_waits (v14+)

Prévenir les conflits de réplication

  • wal_standby_streaming_delay
  • hot_standby_feedback à on + wal_receiver_status_interval (10s)
  • gênent le vacuum !

Contrôle de la réplication

  • pg_wal_replay_pause() : mettre en pause le rejeu
  • pg_wal_replay_resume() : reprendre
  • pg_is_wal_replay_paused() : statut
  • Utilité :
    • requêtes longues
    • pg_dump depuis un secondaire

Réplication synchrone

Le primaire attend l’enregistrement sur le secondaire.

  • Comment configurer ?
  • Comment limiter l’impact sur les performances ?

Secondaires synchrones

  • Par défaut : réplication physique asynchrone
  • Secondaires synchrones :
# s1 synchrone, s2 en dépannage
synchronous_standby_names = 'FIRST 1 (s1, s2)'
# 2 synchrones au moins
synchronous_standby_names = 'ANY 2 (s1,s2,s3)'
# n'importe quel secondaire
synchronous_standby_names = '*'
  • Plusieurs synchrones simultanés possibles
    • ou un quorum

Niveau de synchronicité & performances

  • Niveau de synchronicité :
SET synchronous_commit = off / local / remote_write / on / remote_apply
  • Ajustable par base/utilisateur/session/transaction
  • Risque de blocage du primaire à cause des secondaires !

Réplication en cascade

  • Un secondaire peut fournir les informations de réplication
  • Décharger le serveur primaire de ce travail
  • Diminuer la bande passante du serveur primaire

Décrochage d’un secondaire

  • Par défaut, le primaire n’attend pas les secondaires pour recycler ses WAL
    • risque de « décrochage » !
  • 3 solutions :
  • archivage en plus du streaming
    • bascule automatique
    • mutualisation avec sauvegarde PITR
  • Slot de réplication
  • Garder des journaux
    • wal_keep_size (v13+) / wal_keep_segments (<13)

Sécurisation par log shipping

  • archive_command / restore_command
    • script par l’outil PITR
    • ou cp, scp, lftp, rsync, script…
  • Nettoyage
    • rétention des journaux si outil PITR
    • ou outil dédié :
archive_cleanup_command = '/usr/pgsql-14/bin/pg_archivecleanup -d rep_archives/ %r'

Slot de réplication : mise en place

  • Slot de réplication sur le primaire :
    • max_replication_slots
    • NB : non répliqué !
    • création manuelle :
    SELECT pg_create_physical_replication_slot ('nomsecondaire') ;
  • Secondaire :
    • dans postgresql.conf
    primary_slot_name = 'nomsecondaire'
    • redémarrage de l’instance (<v13) ou rechargement (v13+)

Slot de réplication : avantages & risques

  • Avantages :
    • plus de risque de décrochage des secondaires
    • supervision facile : pg_replication_slots
    • utilisable par pg_basebackup
  • Risque : accumulation des journaux
    • danger pour le primaire !
    • sécurité : max_slot_wal_keep_size (v13+)
  • Risque : vacuum bloqué
    • hot_standby_feedback ?

Synthèse des paramètres

Serveur primaire

Log shipping Streaming
wal_level = replica * wal_level = replica *
archive_mode = on *
archive_command *
archive_library
archive_timeout wal_sender_timeout
max_wal_senders
max_replication_slots
wal_keep_size
max_slot_wal_keep_size *

Serveur secondaire

Log shipping Streaming
wal_level = replica * wal_level = replica *
restore_command *
archive_cleanup_command
(selon outil) primary_conninfo *
wal_receiver_timeout
hot_standby
primary_slot_name*
max_standby_archive_delay max_standby_streaming_delay
hot_standby_feedback
wal_receiver_status_interval

Conclusion

  • Système de réplication fiable…
    • et très complet

Questions

N’hésitez pas, c’est le moment !

Quiz

Travaux pratiques

Réplication asynchrone en flux avec deux secondaires

Slots de réplication

Log shipping

Réplication synchrone en flux avec trois secondaires

Réplication synchrone : cohérence des lectures (optionnel)

Travaux pratiques (solutions)

Les outils de réplication

PostgreSQL

Introduction

  • Les outils à la rescousse !
    • (Re)construction d’un secondaire
    • Log shipping & PITR
    • Promotion automatique

Au menu

  • (Re)construction d’un secondaire
    • outils de copie
    • pg_rewind
  • Log shipping & PITR
    • pgBackRest
    • Barman
  • Promotion automatique
    • Patroni
    • repmgr
    • PAF

(Re)construire un secondaire

  • pg_basebackup
  • rsync
  • outils PITR
  • pg_rewind

(Re)construction d’un secondaire : pg_basebackup

  • Simple et pratique
  • …mais recopie tout !

(Re)construction d’un secondaire : script rsync

  • Intérêts :
    • reprendre des transferts interrompus
    • compression
  • Prévoir :
    • pg_backup_start()/pg_backup_stop()
    • rsync --whole-file
    • les tablespaces
    • ne pas tout copier !
    • postgresql.conf

(Re)construction d’un secondaire : outil PITR

  • Le plus confortable
  • Ne charge pas le primaire
  • Mode « delta »
pgbackrest --stanza=instance      --type=standby      --delta  \
  --repo1-host=depot --repo1-host-user=postgres --repo1-host-port=22 \
  --pg1-path=/var/lib/postgresql/14/secondaire \
  --recovery-option=primary_conninfo='host=principal port=5433 user=replicator' \
  --recovery-option=primary_slot_name='secondaire' \
  --target-timeline=latest \
  restore

pg_rewind

  • Outil inclus
  • Évite la reconstruction complète malgré une divergence
  • Pré-requis :
    • data-checksums
    • ou wal_log_hints = on
    • tous les WAL depuis la divergence
    • full_page_writes = on (défaut)
  • Revient au point de divergence

Log shipping & PITR

  • Utilisation des archives pour :
    • se prémunir du décrochage d’un secondaire
    • une sauvegarde PITR
  • Utilisation des sauvegardes PITR pour :
    • resynchroniser un serveur secondaire

pgBackRest

  • pgbackrest restore
    • --delta
    • --type=standby
    • --recovery-option

barman

  • barman recover
    • --standby-mode
    • --target-*

Promotion automatique

  • L’objectif est de minimiser le temps d’interruption du service en cas d’avarie
  • Un peu de vocabulaire :
    • SPOF : Single Point Of Failure
    • Redondance : pour éviter les SPOF
    • Ressources : éléments gérés par un cluster
    • Split brain : deux primaires ! et perte de données
    • Fencing : isoler un serveur défaillant
    • STONITH : Shoot The Other Node In The Head (voir Fencing)
    • Watchdog : permet à un serveur de s’auto isoler
    • Quorum : participe à la résolution des partitions réseau

Patroni

  • Outil de HA
  • Basé sur un gestionnaire de configuration distribué : etcd, Consul, ZooKeeper…
  • Contexte physique, VM ou container
  • Spilo : image docker PostgreSQL+Patroni

repmgr

  • Outil spécialisé PostgreSQL
  • En pratique, fiable pour 2 nœuds
  • Gère automatiquement la bascule en cas de problème
    • health check
    • failover et switchover automatiques
  • Witness

Pacemaker

  • Solution de Haute Disponibilité généraliste
  • Disponible sur les distributions les plus répandues
  • Se base sur Corosync, un service de messagerie inter-nœuds
  • Permet de surveiller la disponibilité des machines
  • Gère le quorum, le fencing, le watchdog et le SBD
  • Gère les ressources d’un cluster et leur interdépendance
  • Extensible

PAF

  • Postgres Automatic Failover
  • Ressource Agent pour Pacemaker et Corosync permettant de :
    • détecter un incident
    • relancer l’instance primaire
    • basculer sur un autre nœud en cas d’échec de relance
    • élire le meilleur secondaire (avec le retard le plus faible)
    • basculer les rôles au sein du cluster en primaire et secondaire
  • Avec les fonctionnalités offertes par Pacemaker & Corosync :
    • surveillance de la disponibilité du service
    • quorum & Fencing
    • gestion des ressources du cluster

Conclusion

De nombreuses applications tierces peuvent nous aider à administrer efficacement un cluster en réplication.

Questions

N’hésitez pas, c’est le moment !

Travaux pratiques

(Pré-requis) Environnement

Promotion d’une instance secondaire

Suivi de timeline

pg_rewind

pgBackRest

Travaux pratiques (solutions)

Réplication logique

PostgreSQL

Objectifs

  • Réplication logique native
    • connaître les avantages et limites
    • savoir la mettre en place
    • savoir l’administrer et la superviser
  • Connaître d’autres outils de réplication logique

Au menu

  • Principes
  • Mise en place
  • Exemple
  • Administration
  • Supervision
  • Migration majeure avec la réplication logique
  • Limitations

Principes de la réplication logique native

  • Réplication logique
    • résout certaines des limitations de la réplication physique
    • native depuis la version 10
    • avant v10 : solutions externes
    • préférer tout de même PostgreSQL >= 14

Réplication physique vs. logique

Physique Logique
Instance complète Tables aux choix
Par bloc Par ligne/colonnes
Asymétrique (1 principal) Asymétrique / croisée
Depuis primaire ou secondaire Depuis primaire ou secondaire (v16)
Toutes opérations Opération au choix
Réplica identique Destination modifiable
Même architecture -
Mêmes versions majeures -
Synchrone/Asynchrone Synchrone/Asynchrone

Schéma de principe de la réplication logique

Quelques termes essentiels

  • Serveur origine (publieur/éditeur)
    • publication
  • Serveur(s) abonné(s) (subscriber)
    • abonnement (subscription)

Réplication logique et streaming

La réplication logique utilise le streaming :

  • wal_level = logical
  • Processus wal sender
    • mais pas de wal receiver
    • un logical replication worker à la place
  • Décodage logique des journaux
  • Asynchrone / synchrone
  • Slots de réplication

Granularité de la réplication logique

  • Par table
    • toutes les tables d’une base
    • toutes les tables d’un schéma (v15+)
    • quelques tables spécifiques
  • Granularité d’une table
    • table complète
    • même partitionnée (v13+)
    • uniquement certaines lignes/colonnes (v15+)
  • Par opération
    • INSERT, UPDATE, DELETE, TRUNCATE

Possibilités sur les tables répliquées

  • Possibilités
    • index supplémentaires
    • modification des valeurs
    • colonnes supplémentaires
    • triggers également activables sur la table répliquée
  • Attention à la cohérence des modèles
  • Attention à ne pas bloquer la réplication logique !
    • aller au plus simple

Limitations de la réplication logique

  • Pas de réplication des requêtes DDL
    • à refaire manuellement
    • être rigoureux et surveiller les traces !
  • Pas de réplication des valeurs des séquences
  • Pas de réplication des LO (table système)
  • Problèmes avec les tables partitionnées (< v13)
  • PK/UK conseillée pour les UPDATE/DELETE
  • Coût CPU, disque, RAM
  • Réplication déclenchée uniquement lors du COMMIT (< v14)
  • Attention en cas de bascule/restauration !

Mise en place

Étapes :

  • Configuration du serveur origine
  • Configuration du serveur destination
  • Création d’une publication
  • Ajout d’une souscription

Configurer le serveur origine : utilisateur de réplication

CREATE ROLE logrepli LOGIN REPLICATION ;
GRANT SELECT ON ALL TABLES IN SCHEMA monschema TO logrepli ;
# pg_hba.conf
host base_publication  logrepli XXX.XXX.XXX.XXX/XX scram-sha-256

Configurer le serveur origine : postgresql.conf

  • wal_level = logical
    • rédémarrage
  • logical_decoding_work_mem = 64MB (v13+)
    • en-deça : RAM jusque COMMIT
    • puis disque
    • ou transmission immédiate (v14+)

Configuration du serveur destination

  • Création, si nécessaire, des tables répliquées
pg_dump -h origine -s -t la_table la_base | psql la_base

Créer une publication

CREATE PUBLICATION pub_t1     FOR TABLE t1 ;
CREATE PUBLICATION pub_t1part FOR TABLE t1 (c1, c3);  -- v15
CREATE PUBLICATION pub_tout   FOR ALL TABLES ;
CREATE PUBLICATION pub_public FOR TABLES IN SCHEMA public ; -- v15
CREATE PUBLICATION pub_filtree
FOR TABLE employes  WHERE ( ville = 'Brest' ) ; --v15
WITH ( publish = 'update, delete, insert, truncate')  -- défaut
WITH (publish_via_partition_root = false)  -- défaut, v13

Souscrire à une publication

CREATE SUBSCRIPTION nom
    CONNECTION 'infos_connexion'
    PUBLICATION nom_publication [, ...]
    [ WITH ( parametre_souscription [= value] [, ... ] ) ]
  • infos_connexion : chaîne de connexion habituelle
  • Par : superutilisateur ou pg_create_subscription

Options de la souscription (1/2)

Par défaut :

  • connect = true
    • connexion immédiate
  • copy_data = true
    • copie initiale des données
  • create_slot = true
    • création du slot de réplication
  • enabled = true
    • activation immédiate de la souscription
  • slot_name = <nom de la souscription>
    • nom du slot de réplication

Options de la souscription (2/2)

Par défaut :

  • streaming = off
    • true pour envoyer les modifications avant COMMIT (v14+)
    • évite de gros fichiers sur le primaire
    • parallel: plusieurs workers (v16+)
  • binary = off (v14+)
    • pour envoyer les données sous un format binaire
  • disable_on_error = false
    • désactivation de la souscription en cas d’erreurs détectées
  • synchronous_commit = off
    • surcharge synchronous_commit pour les wal sender

Mise en place : exemple

  • Réplication complète d’une base
  • Réplication partielle d’une base
  • Réplication croisée

Serveurs et schéma

  • 4 serveurs
    • s1, 192.168.10.1 : origine de toutes les réplications, et destination de la réplication croisée
    • s2, 192.168.10.2 : destination de la réplication complète
    • s3, 192.168.10.3 : destination de la réplication partielle
    • s4, 192.168.10.4 : origine et destination de la réplication croisée
  • Schéma
    • 2 tables ordinaires
    • 1 table partitionnée, avec trois partitions

Réplication complète

  • Configuration du serveur origine
  • Configuration du serveur destination
  • Création de la publication
  • Ajout de la souscription

Configuration du serveur origine (1/2)

  • Création et configuration de l’utilisateur de réplication
CREATE ROLE logrepli LOGIN REPLICATION;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO logrepli;
  • Fichier postgresql.conf
wal_level = logical

Configuration du serveur origine (2/2)

  • Fichier pg_hba.conf
host b1 logrepli 192.168.10.0/24 trust
  • Redémarrer le serveur origine
  • Attention, dans la vraie vie, ne pas utiliser trust
    • et utiliser le fichier .pgpass

Configuration des 4 serveurs destinations

  • Création de l’utilisateur de réplication
CREATE ROLE logrepli LOGIN REPLICATION;
  • Création des tables répliquées (sans contenu)
createdb -h s2 b1
pg_dump -h s1 -s b1 | psql -h s2 b1

Créer une publication complète

  • Création d’une publication de toutes les tables de la base b1 sur le serveur origine s1
CREATE PUBLICATION publi_complete
  FOR ALL TABLES;

Souscrire à la publication

  • Souscrire sur s2 à la publication de s1
CREATE SUBSCRIPTION subscr_complete
  CONNECTION 'host=192.168.10.1 user=logrepli dbname=b1'
  PUBLICATION publi_complete;
  • Un slot de réplication est créé sur l’origine
  • Les données initiales sont immédiatement transférées

Tests de la réplication complète

  • Insertion, modification, suppression sur les différentes tables de s1
  • Vérifications sur s2
    • toutes doivent avoir les mêmes données entre s1 et s2

Réplication partielle

  • Identique à la réplication complète, à une exception…
  • Créer la publication partielle
CREATE PUBLICATION publi_partielle
  FOR TABLE t1,t2 ;
  • Souscrire sur s3 à cette nouvelle publication de s1
CREATE SUBSCRIPTION subscr_partielle
  CONNECTION 'host=192.168.10.1 user=logrepli dbname=b1'
  PUBLICATION publi_partielle;

Réplication croisée

  • Écrire sur une table sur s1
    • et répliquer sur s4
  • Écrire sur une (autre) table sur s4
    • et répliquer sur s1
  • Pour compliquer :
    • on utilisera la table partitionnée

Réplication de t3_1 de s1 vers s4

  • Créer la publication partielle sur s1
CREATE PUBLICATION publi_t3_1
  FOR TABLE t3_1;
  • Y souscrire sur s4
CREATE SUBSCRIPTION subscr_t3_1
  CONNECTION 'host=192.168.10.1 user=logrepli dbname=b1'
  PUBLICATION publi_t3_1;
  • Configurer s4 comme serveur origine
    • wal_level , pg_hba.conf

Réplication de t3_2 de s4 vers s1

  • Créer la publication partielle sur s4
CREATE PUBLICATION publi_t3_2
  FOR TABLE t3_2;
  • Y souscrire sur s1
CREATE SUBSCRIPTION subscr_t3_2
  CONNECTION 'host=192.168.10.4 user=logrepli dbname=b1'
  PUBLICATION publi_t3_2;

Tests de la réplication croisée

  • Insertion, modification, suppression sur t3 (partition 1) sur s1
    • Vérifications sur s4 : les nouvelles données doivent être présentes
  • Insertion, modification, suppression sur t3 (partition 2) sur s4
    • Vérifications sur s1 : les nouvelles données doivent être présentes

Administration

  • Processus
  • Fichiers
  • Procédures
    • Empêcher les écritures sur un serveur destination
    • Que faire pour les DDL ?
    • Gérer les opérations de maintenance
    • Gérer les sauvegardes

Processus

  • Serveur origine
    • wal sender
  • Serveur destination
    • logical replication launcher
    • logical replication worker

Synthèse des paramètres sur le serveur origine

Paramètre Valeur
wal_level logical
logical_decoding_work_mem 64MB ou plus
max_slot_wal_keep_size 0 (à ajuster)
wal_sender_timeout 1 min
max_wal_senders 10 (parfois à ajuster)
max_replication_slots 10 (parfois à ajuster

Synthèse des paramètres sur le serveur destination

Paramètre Valeur
max_worker_processes 8 (parfois à ajuster)
max_logical_replication_workers 4 (parfois à ajuster)

Fichiers (serveur origine)

  • 2 répertoires importants
  • pg_replslot
    • slots de réplication
    • 1 répertoire par slot (+ slots temporaires)
    • 1 fichier state dans le répertoire
    • fichiers .spill (volumétrie !)
  • pg_logical
    • métadonnées

Empêcher les écritures sur un serveur destination

  • Par défaut, toutes les écritures sont autorisées sur le serveur destination
    • y compris écrire dans une table répliquée avec un autre serveur comme origine
  • Problèmes
    • serveurs non synchronisés
    • blocage de la réplication en cas de conflit sur la clé primaire
  • Solution
    • révoquer le droit d’écriture sur le serveur destination
    • mais ne pas révoquer ce droit pour le rôle de réplication !

Que faire pour les DDL ?

  • Les opérations DDL ne sont pas répliquées
  • De nouveaux objets ?
    • les déclarer sur tous les serveurs du cluster de réplication
    • tout du moins, ceux intéressés par ces objets
  • Changement de définition des objets ?
    • à réaliser sur chaque serveur

Que faire pour les nouvelles tables ?

  • Créer la table sur origine et destination
  • Publication FOR ALL TABLES/FOR TABLES IN SCHEMA
    • prise en compte automatique ajouter la table aux souscriptions concernées :
    -- origine
    ALTER PUBLICATION … ADD TABLE …, TABLE … ;
    ALTER SUBSCRIPTION … REFRESH PUBLICATION ;

Comment ajouter une nouvelle colonne ?

    1. Ajouter la colonne sur l’abonné
    1. Puis ajouter la colonne sur le publieur
  • Si le contraire : pas grave, la réplication reprendra une fois les colonnes ajoutées

Comment supprimer une colonne ?

    1. Supprimer la colonne sur le publieur
    1. Supprimer la colonne sur l’abonné
  • Si le contraire : pas grave, la réplication reprendra une fois les colonnes supprimées

Comment ajouter une nouvelle contrainte ?

    1. Ajouter la contrainte sur le publieur
    1. Ajouter la contrainte sur l’abonné
  • Si incohérence : bloquage de la réplication

Comment corriger une erreur de réplication ?

  • Si les données diffèrent entre les serveurs, il faut corriger manuellement les données
  • Si blocage
    • publication arrêtée
    • pas de recyclage des journaux → accumulation → danger !
  • Puis, avancer le pointeur du slot de réplication
    • fonction pg_replication_slot_advance()
    • outil pg_waldump ou extension pg_walinspect

Gérer les opérations de maintenance

  • À faire séparément sur tous les serveurs
  • VACUUM, ANALYZE, REINDEX

Gérer les sauvegardes & restaurations logiques

  • pg_dumpall et pg_dump
    • sauvegardent publications et souscriptions
    • options --no-publications et --no-subscriptions
  • Restauration d’une publication :
    • nouveau slot de réplication !
    • réconciliation de données à prévoir
  • Restauration d’un abonnement :
    • ENABLE et REFRESH PUBLICATION
    • reprendre à zéro la copie… ou copier manuellement ?

Gérer les bascules & les restaurations physiques

Comme pour la réplication physique :

  • Sauvegarde PITR
    • publications et souscriptions
    • slots ?
  • Slots perdus et « trous » dans la réplication si :
    • bascule origine
    • restauration origine
    • restauration destination
  • Contrôle délicat !
    • interdire les écritures à ces moments ?
  • Bascule de la destination
    • si propre, devrait mieux se passer

Réplication logique depuis un secondaire comme origine

  • Depuis PostgreSQL 16
  • wal_level = logical sur le secondaire/origine
  • Création de la publication toujours sur le primaire
  • Le secondaire porte le slot et décode
  • Latence supplémentaire

Combien de réplications logiques ?

  • 1 publication logique = 1 walsender+1 slot par abonné
  • Chaque worker doit décoder les WAL
    • Attention au CPU et à la RAM !
  • Risques de slots bloqués
  • Contournements :
    • regrouper les réplications
    • réplication depuis un secondaire
    • streaming = on

Supervision

  • Méta-données
  • Statistiques
  • Outils

Catalogues systèmes - méta-données

  • pg_publication
    • définition des publications
    • \dRp sous psql
  • pg_publication_tables
    • tables ciblées par chaque publication
  • pg_subscription
    • définition des souscriptions
    • \dRs sous psql

Vues statistiques

  • pg_stat_replication
    • statut de réplication
  • pg_replication_slots
    • slots de réplication : statut
  • pg_stat_replication_slots (v14)
    • volumes écrits/envoyés en streaming via les slots de réplication logique
  • pg_stat_subscription
    • état des souscriptions
  • pg_replication_origin_status
    • statut des origines de réplication
  • pg_stat_database_conflicts (si origine est un secondaire)

Outils de supervision

  • check_pgactivity
    • replication_slots
  • check_postgres
    • same_schema

Migration majeure par réplication logique

  • Possible entre versions 10 et supérieures
  • Remplace la réplication par trigger (Slony, Bucardo…)
  • Bascule très rapide
  • Et retour possible
  • Des limitations

Rappel des limitations de la réplication logique native

  • Pas de réplication : DDL, LO, valeurs de séquence
  • Pas de réplication des tables partitionnées ( < v13)
    • mais réplication possible des partitions
  • Pas de réplication vers une table partitionnée ( < v13)
  • Contraintes d’unicité obligatoires pour les UPDATE/DELETE
  • Coût CPU, disque, RAM
  • Réplication déclenchée uniquement lors du COMMIT (< v14)
  • Que faire lors des restaurations/bascules ?

Conclusion

  • Réplication logique simple et pratique
    • …avec ses subtilités

Questions

N’hésitez pas, c’est le moment !

Quiz

Travaux pratiques

Pré-requis

Réplication complète d’une base

Réplication partielle d’une base

Réplication croisée

Réplication et partitionnement

Travaux pratiques (solutions)