Outils de sauvegarde physique

17 avril 2024

Dalibo SCOP

Sur ce document

Formation Module I4
Titre Outils de sauvegarde physique
Révision 24.04
PDF https://dali.bo/i4_pdf
EPUB https://dali.bo/i4_epub
HTML https://dali.bo/i4_html
Slides https://dali.bo/i4_slides
TP https://dali.bo/i4_tp
TP (solutions) https://dali.bo/i4_solutions

Vous trouverez en ligne les différentes versions complètes de ce document.


Chers lectrices & lecteurs,

Nos formations PostgreSQL sont issues de nombreuses années d’études, d’expérience de terrain et de passion pour les logiciels libres. Pour Dalibo, l’utilisation de PostgreSQL n’est pas une marque d’opportunisme commercial, mais l’expression d’un engagement de longue date. Le choix de l’Open Source est aussi le choix de l’implication dans la communauté du logiciel.

Au‑delà du contenu technique en lui‑même, notre intention est de transmettre les valeurs qui animent et unissent les développeurs de PostgreSQL depuis toujours : partage, ouverture, transparence, créativité, dynamisme… Le but premier de nos formations est de vous aider à mieux exploiter toute la puissance de PostgreSQL mais nous espérons également qu’elles vous inciteront à devenir un membre actif de la communauté en partageant à votre tour le savoir‑faire que vous aurez acquis avec nous.

Nous mettons un point d’honneur à maintenir nos manuels à jour, avec des informations précises et des exemples détaillés. Toutefois malgré nos efforts et nos multiples relectures, il est probable que ce document contienne des oublis, des coquilles, des imprécisions ou des erreurs. Si vous constatez un souci, n’hésitez pas à le signaler via l’adresse !

À propos de DALIBO

DALIBO est le spécialiste français de PostgreSQL. Nous proposons du support, de la formation et du conseil depuis 2005.

Retrouvez toutes nos formations sur https://dalibo.com/formations

Remerciements

Ce manuel de formation est une aventure collective qui se transmet au sein de notre société depuis des années. Nous remercions chaleureusement ici toutes les personnes qui ont contribué directement ou indirectement à cet ouvrage, notamment :

Jean‑Paul Argudo, Alexandre Anriot, Carole Arnaud, Alexandre Baron, David Bidoc, Sharon Bonan, Franck Boudehen, Arnaud Bruniquel, Pierrick Chovelon, Damien Clochard, Christophe Courtois, Marc Cousin, Gilles Darold, Jehan‑Guillaume de Rorthais, Ronan Dunklau, Vik Fearing, Stefan Fercot, Pierre Giraud, Nicolas Gollet, Dimitri Fontaine, Florent Jardin, Virginie Jourdan, Luc Lamarle, Denis Laxalde, Guillaume Lelarge, Alain Lesage, Benoit Lobréau, Jean‑Louis Louër, Thibaut Madelaine, Adrien Nayrat, Alexandre Pereira, Flavie Perette, Robin Portigliatti, Thomas Reiss, Maël Rimbault, Julien Rouhaud, Stéphane Schildknecht, Julien Tachoires, Nicolas Thauvin, Be Hai Tran, Christophe Truffier, Cédric Villemain, Thibaud Walkowiak, Frédéric Yhuel.

Forme de ce manuel

Les versions PDF, EPUB ou HTML de ce document sont structurées autour des slides de nos formations. Le texte suivant chaque slide contient le cours et de nombreux détails qui ne peuvent être données à l’oral.

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

Vous n’avez pas le droit d’utiliser cette création à des fins commerciales.

Si vous modifiez, transformez ou adaptez cette création, vous n’avez le droit de distribuer la création qui en résulte que sous un contrat identique à celui-ci.

Vous devez citer le nom de l’auteur original de la manière indiquée par l’auteur de l’œuvre ou le titulaire des droits qui vous confère cette autorisation (mais pas d’une manière qui suggérerait qu’ils vous soutiennent ou approuvent votre utilisation de l’œuvre). À chaque réutilisation ou distribution de cette création, vous devez faire apparaître clairement au public les conditions contractuelles de sa mise à disposition. La meilleure manière de les indiquer est un lien vers cette page web. Chacune de ces conditions peut être levée si vous obtenez l’autorisation du titulaire des droits sur cette œuvre. Rien dans ce contrat ne diminue ou ne restreint le droit moral de l’auteur ou des auteurs.

Le texte complet de la licence est disponible sur http://creativecommons.org/licenses/by-nc-sa/2.0/fr/legalcode

Cela inclut les diapositives, les manuels eux-mêmes et les travaux pratiques. Cette formation peut également contenir quelques images et schémas dont la redistribution est soumise à des licences différentes qui sont alors précisées.

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.

Sur les versions précédentes susceptibles d’être encore rencontrées en production, seuls quelques points très importants sont évoqués, en plus éventuellement de quelques éléments historiques.

Sauf précision contraire, le système d’exploitation utilisé est Linux.

PostgreSQL : Outils de sauvegarde physique

PostgreSQL

Introduction

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

Nous avons vu le fonctionnement interne du mécanisme de sauvegarde physique. Celui-ci étant en place nativement dans le moteur PostgreSQL depuis de nombreuses versions, sa robustesse n’est plus à prouver. Cependant, son industrialisation reste fastidieuse.

Des outils tiers existent et vont permettre de faciliter la gestion des sauvegardes, de leur mise en place jusqu’à la restauration. Dans ce module nous allons voir en détail certains de ces outils et étudier les critères qui vont nous permettre de choisir la meilleure solution selon notre contexte.


Au menu

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

Lors de cette présentation, nous allons passer en revue les différents outils principaux de gestion de sauvegardes, leurs forces, le paramétrage, l’installation et l’exploitation.


Définition du besoin - Contexte

  • 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 ?

Où les sauvegardes doivent-elles être stockées ?

Quelles ressources sont à disposition : serveur de sauvegarde dédié ? quelle puissance pour la compression ?

De quel type d’accès aux serveurs de base de données dispose-t-on ? Quelle est la version du système d’exploitation ?

Il est très important de se poser toutes ces questions, les réponses vont servir à établir le contexte et permettre de choisir l’outil et la méthode la plus appropriée.

Attention, pour des raisons de sécurité et de fiabilité, les répertoires choisis pour la restauration des données de votre instance ne doivent pas être à la racine d’un point de montage.

Si un ou plusieurs points de montage sont dédiés à l’utilisation de PostgreSQL, positionnez toujours les données dans un sous-répertoire, voire deux niveaux en dessous du point de montage (eg. <point de montage>/<version majeure>/<nom instance>).


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 est une application cliente intégrée à PostgreSQL, au même titre que pg_dump ou pg_dumpall.

pg_basebackup a été conçu pour permettre l’initialisation d’une instance secondaire, et il peut donc être utilisé pour effectuer facilement une sauvegarde physique ponctuelle. Celle-ci inclut les fichiers et journaux nécessaires pour une restauration telle que l’instance était à la fin de la sauvegarde.

pg_basebackup peut aussi être à la base d’outils permettant le PITR (par exemple barman). Ces outils s’occupent en plus de l’archivage des journaux générés pendant et après la sauvegarde initiale, pour une restauration dans un état postérieur à la fin de cette sauvegarde.


pg_basebackup - Formats de sauvegarde

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

Le format par défaut de la sauvegarde est plain, ce qui signifie que les fichiers seront créés tels quels dans le répertoire de destination (ou les répertoires en cas de tablespaces). C’est idéal pour obtenir une copie immédiatement utilisable.

Pour une archive à proprement parler, préférer l’option --format tar. pg_basebackup génère alors une archive base.tar pour le PGDATA de l’instance, puis une archive <oid>.tar par tablespace. Les journaux récupérés seront également dans un fichier .tar.

L’option --gzip (-z) ajoute la compression gzip. Le niveau de compression peut également être spécifié avec --compress=1 à 9 (-Z). Cela permet d’arbitrer entre la durée de la sauvegarde et sa taille.


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 s’est beaucoup amélioré au fil des versions et son comportement a parfois changé. Regardez bien la documentation de votre version.

Même avec un serveur un peu ancien, il possible d’installer un pg_basebackup récent, en installant les outils clients de la dernière version de PostgreSQL.

Récupération des journaux :

pg_basebackup sait récupérer les fichiers WAL nécessaires à la restauration de la sauvegarde sans passer par la commande d’archivage. Il connaît deux méthodes :

Avec l’option --wal-method fetch (ou -X), les WAL générés pendant la sauvegarde seront demandés une fois celle-ci terminée, à condition qu’ils n’aient pas été recyclés entre-temps (ce qui peut nécessiter un slot de réplication, ou éventuellement une configuration élevée du paramètre wal_keep_size/wal_keep_segments).

L’option par défaut est cependant -X stream : les WAL sont récupérés non pas en fin de sauvegarde, mais en streaming pendant celle-ci. Cela nécessite néanmoins l’utilisation d’un wal sender supplémentaire, le paramètre max_wal_senders doit parfois être augmenté en conséquence.

Rappelons que si l’archivage des WAL n’est pas actif, la sauvegarde effectuée ne sera utilisée que pour restaurer l’instance telle qu’elle était au moment de la fin de la sauvegarde : il ne sera pas possible de réaliser une restauration PITR.

À l’inverse, -X none peut être utile si la récupération des journaux est réalisée par ailleurs (généralement par archive_command ou archive_library). Attention, l’archive réalisée avec pg_basebackup ne sera alors pas « complète », et ne pourra pas être restaurée sans ces archives des journaux (il faudra indiquer où aller les chercher avec restore_command.)

Slots de réplication :

Par défaut, pg_basebackup va créer un slot de réplication temporaire sur le serveur pour sécuriser la sauvegarde. Il disparaîtra une fois celle-ci terminée.

Pour faciliter la mise en place d’une instance secondaire, et garantir que tous les journaux nécessaires seront encore sur le primaire à son démarrage, il est possible de créer un slot de réplication permanent, et de le fournir à pg_basebackup avec --slot nom_du_slot. pg_basebackup peut le créer lui-même avec --create. Si l’on préfère le créer préalablement, il suffit d’exécuter la requête suivante :

SELECT pg_create_physical_replication_slot ('nom_du_slot');

Rappelons qu’un slot initialisé mais inutilisé doit être rapidement supprimé pour ne pas mener à une dangereuse accumulation des journaux.

Sécurisation de la sauvegarde :

Par défaut, pg_basebackup crée un fichier manifeste (à partir de PostgreSQL 13). Ce fichier contient la liste des fichiers sauvegardés, leur taille et leur somme de contrôle. Cela permet après coup de vérifier l’intégrité de la sauvegarde à l’aide de l’outil pg_verifybackup.

L’algorithme par défaut de la somme de contrôle, CRC32, suffit pour détecter une erreur technique accidentelle ; d’autres algorithmes disponibles permettent de détecter une manipulation volontaire de la sauvegarde.

Vérification des sommes de contrôle :

Une sauvegarde avec pg_basebackup entraîne la vérification des sommes de contrôle de l’instance. Cela garantit que la sauvegarde n’héritera pas d’une corruption existante, sinon l’outil tombe en erreur.

L’option --no-verify-checksums autorise la sauvegarde d’une instance où une corruption est détectée (sauvegarde aussi problématique, certes, mais qui peut permettre de travailler sur la récupération, ou de sauver l’essentiel).

Emplacement de la sauvegarde

À partir de la version 15, l’option --target permet de spécifier où la sauvegarde doit être réalisée :

  • sur le serveur où la commande est lancée (client) ;
  • sur le serveur de base de données (server) ;
  • dans le vide (blackhole).

Des destinations peuvent être ajoutées par des extensions, basebackup_to_shell est fournie à titre d’exemple et permet d’exécuter une commande à l’issue d’une sauvegarde.

Lorsque la destination server est choisie, plusieurs restrictions s’appliquent à la sauvegarde :

  • le format doit être tar ;
  • l’utilisateur employé pour la réaliser doit être membre du rôle pg_write_server_files ;
  • la méthode de récupération des WAL doit être fetch ou none.

Compression de la sauvegarde :

À partir de la version 15, il est possible de demander la compression de la sauvegarde avec un grand niveau de personnalisation :

  • algorithme de compression parmi gzip, lz4 et zstd ;
  • rapidité de la compression hors parallélisme (lz4) ;
  • niveau de compression (zstd) ;
  • parallélisation de la compression (zstd) ;
  • localisation de la compression (serveur ou client).

Cela permet de gérer différents scénarios et d’éviter certains goulets d’étranglement lors d’une sauvegarde.

Autres options :

Le débit de la sauvegarde est configurable avec l’option --max-rate= (-r) pour limiter l’impact sur l’instance ou le réseau. Cette restriction de débit ne concerne pas les journaux transférés en parallèle (-X stream).

Pour gagner un peu de temps, si l’instance n’est pas trop chargée, --checkpoint=fast accélère le checkpoint préalable à la sauvegarde.

Avec une sauvegarde plain, il est possible de modifier sur la cible les chemins des éventuels tablespaces avec l’option --tablespace-mapping=<vieuxrep>=<nouveaurep> (ou -T), et de relocaliser le répertoire des fichiers WAL avec l’option --waldir=<nouveau chemin>.

Depuis un secondaire :

pg_basebackup permet nativement de réaliser une sauvegarde à partir d’une instance secondaire. Le paramétrage nécessaire figure plus bas.

Suivi :

Pour suivre le déroulement de la sauvegarde depuis un terminal, il existe l’option --progress (-P).

À partir de PostgreSQL 13, il existe aussi une vue pour ce suivi : pg_stat_progress_basebackup.

Options complètes :

Pour mémoire, toutes les options disponibles sont celles-ci (en version 15) :

$ pg_basebackup --help
pg_basebackup prend une sauvegarde binaire d'un serveur PostgreSQL en cours
d'exécution.

Usage :
  pg_basebackup [OPTION]...

Options contrôlant la sortie :
  -D, --pgdata=RÉPERTOIRE        reçoit la sauvegarde de base dans ce répertoire
  -F, --format=p|t               format en sortie (plain (par défaut), tar)
  -r, --max-rate=TAUX            taux maximum de transfert du répertoire de
                                 données (en Ko/s, ou utiliser le suffixe « k »
                                 ou « M »)
  -R, --write-recovery-conf      écrit la configuration pour la réplication
  -t, --target=CIBLE[:DETAIL]    cible de sauvegarde (si autre que client)
  -T, --tablespace-mapping=ANCIENREP=NOUVEAUREP
                                 déplace le répertoire ANCIENREP en NOUVEAUREP
      --waldir=RÉP_WAL           emplacement du répertoire des journaux de
                                 transactions
  -X, --wal-method=none|fetch|stream
                                 inclut les journaux de transactions requis avec
                                 la méthode spécifiée
  -z, --gzip                     compresse la sortie tar
  -Z, --compress=[{client|server}-]METHODE[:DETAIL]
                                 compresse sur le client ou le serveur comme indiqué
  -Z, --compress=none            ne compresse pas la sortie tar

Options générales :
  -c, --checkpoint=fast|spread   exécute un CHECKPOINT rapide ou réparti
      --create-slot              crée un slot de réplication
  -l, --label=LABEL              configure le label de sauvegarde
  -n, --no-clean                 ne nettoie pas en cas d'erreur
  -N, --no-sync                  n'attend pas que les modifications soient
                                 proprement écrites sur disque
  -P, --progress                 affiche la progression de la sauvegarde
  -S, --slot=NOMREP              slot de réplication à utiliser
  -v, --verbose                  affiche des messages verbeux
  -V, --version                  affiche la version puis quitte
      --manifest-checksums=SHA{224,256,384,512}|CRC32C|NONE
                                 utilise cet algorithme pour les sommes de
                                 contrôle du manifeste
      --manifest-force-encode    encode tous les noms de fichier dans le
                                 manifeste en hexadécimal
      --no-estimate-size         ne réalise pas d'estimation sur la taille de la
                                 sauvegarde côté serveur
      --no-manifest              supprime la génération de manifeste de
                                 sauvegarde
      --no-slot                  empêche la création de slots de réplication
                                 temporaires
      --no-verify-checksums      ne vérifie pas les sommes de contrôle
  -?, --help                     affiche cette aide puis quitte

Options de connexion :
  -d, --dbname=CHAÎNE_CONNEX     chaîne de connexion
  -h, --host=HÔTE                hôte du serveur de bases de données ou
                                 répertoire des sockets
  -p, --port=PORT                numéro de port du serveur de bases de données
  -s, --status-interval=INTERVAL durée entre l'envoi de paquets de statut au
                                 serveur (en secondes)
  -U, --username=UTILISATEUR     se connecte avec cet utilisateur
  -w, --no-password              ne demande jamais le mot de passe
  -W, --password                 force la demande du mot de passe (devrait
                                 survenir automatiquement)

Rapporter les bogues à <pgsql-bugs@lists.postgresql.org>.
Page d'accueil de PostgreSQL : <https://www.postgresql.org/>

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

Configuration :

pg_basebackup étant conçu pour la mise en place d’une instance en réplication, l’instance principale nécessite d’être configurée en conséquence :

  • max_wal_senders doit avoir une valeur supérieure à 0 pour permettre à pg_basebackup de se connecter (au moins 2 si on utilise le transfert des WAL par streaming) — c’est le cas par défaut ;
  • le fichier pg_hba.conf de l’instance principale doit être configuré pour autoriser les connexions de type replication depuis la machine où la sauvegarde est déclenchée, par exemple ainsi :
host  replication  repli_user  192.168.0.100/32  scram-sha-256

Dans l’idéal, l’utilisateur employé est dédié à la réplication. Pour automatiser, stocker le mot de passe nécessaire dans un fichier .pgpass.

L’archivage n’est pas géré par pg_basebackup. Il ne récupère par streaming que les journaux nécessaires à la cohérence de sa sauvegarde. Il faudra paramétrer archive_command ou archive_library à la main pour une sauvegarde PITR.

Si la sauvegarde est effectuée à partir d’une instance secondaire :

  • ces paramétrages sont nécessaires (et en place par défaut) :
    • instance secondaire ouverte en lecture (hot_standby à on) ;
    • max_wal_senders supérieur 0 et droits en place pour permettre à pg_basebackup de se connecter ;
    • écriture complète des pages dans les WAL activée (full_page_writes à on) ;
  • pour du PITR :
    • l’archivage des fichiers WAL doit être configuré indépendamment.
    • une attention particulière doit être apportée au fait que tous les fichiers WAL nécessaires à la restauration ont bien été archivés.

Gestion des sauvegardes :

La gestion des sauvegardes (rétention, purge…) n’est pas prévue dans l’outil.

pg_basebackup n’effectue pas non plus de lien entre les WAL archivés et les sauvegardes effectuées (si pg_basebackup ne les sauvegarde pas lui-même avec l’option -X).

Restauration :

pg_basebackup n’offre pas d’outil ni d’option pour la restauration.

La copie est directement utilisable, éventuellement après déplacement et/ou décompression des .tar.gz. Mais, généralement, on ajoutera un fichier recovery.signal, et on définira la restore_command pour récupérer les archives. Dans l’idéal, restore_command sera déjà prête dans le postgresql.conf.

Si le but est de monter un serveur secondaire de l’instance copiée, il existe une option utile : --write-recovery-conf (ou -R), qui génère la configuration nécessaire dans le répertoire de la sauvegarde (postgresql.auto.conf et fichier vide standby.signal). avec les paramètres pour une réplication en streaming.


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 multi-serveurs
  • Indépendant des commandes système
    • protocole dédié
  • Sauvegardes complètes, différentielles ou incrémentales
  • Multi-thread, sauvegarde depuis un secondaire, archivage asynchrone…
  • Projet mature

pgBackRest est un outil de gestion de sauvegardes PITR écrit en perl et en C, par David Steele de Crunchy Data.

Il met l’accent sur les performances avec de gros volumes et les fonctionnalités, au prix d’une complexité à la configuration :

  • un protocole dédié pour le transfert et la compression des données ;
  • des opérations parallélisables en multi-thread ;
  • la possibilité de réaliser des sauvegardes complètes, différentielles et incrémentielles ;
  • la possibilité d’archiver ou restaurer les WAL de façon asynchrone, et donc plus rapide ;
  • la possibilité d’abandonner l’archivage en cas d’accumulation et de risque de saturation de pg_wal ;
  • la gestion de dépôts de sauvegarde multiples (pour sécuriser, ou avoir plusieurs niveaux d’archives) ;
  • le support intégré de dépôts S3 ou Azure ;
  • le support d’un accès TLS géré par pgBackRest en alternative à SSH ;
  • la sauvegarde depuis un serveur secondaire ;
  • le chiffrement des sauvegardes ;
  • la restauration en mode delta, très pratique pour restaurer un serveur qui a décroché mais n’a que peu divergé ;
  • la reprise d’une sauvegarde échouée.

pgBackRest n’utilise pas pg_receivewal pour garantir la sauvegarde du dernier journal (non terminé) avant un sinistre. Les auteurs considèrent que dans ce cas un secondaire synchrone est plus adapté et plus fiable.

Le projet est très actif et considéré comme fiable, et les fonctionnalités proposées sont intéressantes.

Pour la supervision de l’outil, une sonde Nagios est fournie par un des développeurs : check_pgbackrest.


pgBackRest - Sauvegardes

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

pgBackRest gère uniquement des sauvegardes physiques.

Il peut fonctionner soit en local (directement sur le serveur hébergeant l’instance à sauvegarder) pour un stockage local des sauvegardes, soit être exécuté depuis un serveur distant, déléguant ainsi l’ordonnancement, la compression et le stockage des données à celui-ci.

La technique utilisée pour la prise de sauvegarde repose sur le mécanisme interne standard et historique : pg_backup_start(), copie des fichiers, pg_backup_stop().


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

La restauration d’une sauvegarde peut se faire soit localement, si les sauvegardes sont stockées en local, soit à distance. Dans ce dernier cas, les données à restaurer seront transférées via SSH.

Plusieurs types de point dans le temps peuvent être utilisés comme cible :

  • la date ;
  • un identifiant de transaction ;
  • une timeline (en cas de divergence de timeline, pgBackRest peut restaurer les transactions issues d’une timeline précise) ;
  • un point de restauration créé par un appel préalable à la fonction :
    • pg_create_restore_point().

pgBackRest - Installation

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

pgBackRest est disponible sur le dépôt communautaire maintenu par la communauté PostgreSQL pour les systèmes d’exploitation disposant des gestionnaires de paquet au format deb (Debian, Ubuntu…) ou rpm (Red Hat, Rocky Linux, CentOS, Fedora…).

Il est recommandé de manière générale de privilégier une installation à partir de ces paquets plutôt que par les sources, essentiellement pour des raisons de maintenance.


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 propose différentes commandes pouvant être passées en argument afin de contrôler les actions.

L’usage de ces différentes commandes sera détaillé ultérieurement.


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

Le format de configuration INI permet de définir des sections, qui sont matérialisées sous la forme d’une ligne : [nomdesection].

pgBackRest s’attend à lire un fichier de configuration contenant la section [global], contenant les paramètres de configuration globaux, et une section par instance à sauvegarder.

pgBackRest utilise le terme stanza pour regrouper l’ensemble des configurations à appliquer pour une instance à sauvegarder.

Exemple de configuration :

[global]
repo1-path=/var/lib/pgsql/10/backups

[erp_prod]
pg1-path=/var/lib/pgsql/10/data

Il peut y avoir plusieurs stanzas déclarées dans le fichier, notamment s’il est situé sur le serveur où sont stockées les sauvegardes de plusieurs instances.

Pour des questions de lisibilité, il est possible de créer un fichier de configuration par instance à sauvegarder. Le nom du fichier doit se terminer par .conf pour être pris en compte. Les fichiers doivent être regroupés dans un répertoire référencé par le paramètre 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

Il est nécessaire d’activer l’archivage des journaux de transactions en positionnant le paramètre archive_mode à on et en définissant un niveau d’enregistrement d’informations dans les journaux de transactions (wal_level) supérieur ou égal à replica (ou archive avant la version 9.6).

pgBackRest fournit une commande permettant de simplifier la configuration de l’archivage. Pour l’utiliser, il faut configurer le paramètre archive_command pour qu’il utilise l’option archive-push de la commande pgbackrest. Il faut également fournir à cette commande le nom de la stanza à utiliser.

Comme pgBackRest n’archive que des journaux complets, il vaut mieux penser à mettre un archive_timeout adapté au RPO accepté. (S’il est nul, les auteurs recommandent plutôt un secondaire synchrone).


pgBackRest - Configuration globale

  • Fichier pgbackrest.conf
  • Section [global] pour la configuration globale
[global]
process-max=1
repo1-path=/var/lib/pgbackrest
  • process-max : nombre de processus maximum à utiliser pour la compression et le transfert des sauvegardes ;
  • repo1-path : chemin où seront stockées les sauvegardes et les archives ;
  • repo-cipher-pass : passphrase à utiliser pour chiffrer/déchiffrer le répertoire des sauvegardes ;
  • log-level-console : par défaut à warn, définit le niveau de traces des commandes exécutées en console.

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

La politique de rétention des sauvegardes complètes peut être configurée avec l’option repo1-retention-full-type. Elle peut prendre deux valeurs :

  • count : le nombre de sauvegardes à conserver, c’est la valeur par défaut ;
  • time : un nombre de jours pendant lequel on doit pouvoir restaurer, c’est-à-dire que l’on doit avoir au moins une sauvegarde plus vieille que ce nombre de jours.

Voici un exemple pour illustrer le mode de rétention time, dont le fonctionnement n’est pas très intuitif. Si l’on dispose des trois sauvegardes complètes suivantes :

  • F1 : 25 jours ;
  • F2 : 20 jours ;
  • F3 : 10 jours.

Avec une rétention de 15 jours, seule la sauvegarde F1 sera supprimée. F2 sera conservée, car il doit exister au moins une sauvegarde de plus de 15 jours pour garantir de pouvoir restaurer pendant cette période.

Il est possible de différencier le nombre de sauvegardes complètes et différentielles. La rétention pour les sauvegardes différentielles ne peut être définie qu’en nombre.

Lorsqu’une sauvegarde complète expire, toutes les sauvegardes différentielles et incrémentales qui lui sont associées expirent également.


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

Dans le cadre de la mise en place de sauvegardes avec un stockage des données sur un serveur tiers, pgBackRest fonctionnera par SSH.

Il est donc impératif d’autoriser l’authentification SSH par clé, et d’échanger les clés publiques entre les différents serveurs hébergeant les instances PostgreSQL et le serveur de sauvegarde.

Il faudra ensuite adapter les paramètres repo1-host* dans la configuration de pgBackRest.

  • repo1-host : hôte à joindre par SSH ;
  • repo1-host-user : utilisateur pour la connexion SSH ;

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

Il existe une alternative à l’utilisation de SSH qui consiste à configurer un serveur TLS en valorisant le paramètre repo1-host-type et pg1-host-type à tls (défaut : ssh). La configuration du serveur se fait ensuite avec les paramètres :

  • tls-server-address : adresse IP sur laquelle le serveur écoute pour servir des requêtes clients ;
  • tls-server-auth : la liste des clients autorisés à se connecter sous la forme <client-cn>=<stanza> ;
  • tls-server-ca-file : certificat de l’autorité ;
  • tls-server-cert-file : certificat du serveur ;
  • tls-server-key-file : clé du serveur.

Il faut ensuite configurer l’accès au dépôt de sauvegarde :

  • repo1-host-type=tls : la connexion au dépôt utilise TLS ;
  • repo1-host-cert-file : certificat pour se connecter au dépôt ;
  • repo1-host-key-file : clé pour se connecter au dépôt ;
  • repo1-host-ca-file : certificat de l’autorité.

Exemple de configuration :

[global]
repo1-host=backrest-srv
repo1-host-user=backrest
repo1-host-type=tls
repo1-host-cert-file=/etc/certs/srv1-cert.pem
repo1-host-key-file=/etc/certs/srv1-key.pem
repo1-host-ca-file=/etc/certs/CA-cert.pem

tls-server-address=*
tls-server-cert-file=/etc/certs/srv1-cert.pem
tls-server-key-file=/etc/certs/srv1-key.pem
tls-server-ca-file=/etc/certs/CA-cert.pem
tls-server-auth=backrest-srv=main

[main]
pg1-path=/var/lib/pgsql/14/data

Sur le serveur de sauvegarde, la configuration est similaire :

  • pg1-host-type=tls : la connexion au serveur PostgreSQL utilise TLS ;
  • pg1-host-cert-file : certificat pour se connecter au serveur de bases de données ;
  • pg1-host-key-file : certificat pour se connecter au serveur de bases de données ;
  • pg1-host-ca-file : certificat de l’autorité.

Exemple de configuration du serveur de sauvegarde :

[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2

tls-server-address=*
tls-server-cert-file=/etc/certs/backrest-srv-cert.pem
tls-server-key-file=/etc/certs/backrest-srv-key.pem
tls-server-ca-file=/etc/certs/CA-cert.pem
tls-server-auth=srv1=main

[main]
pg1-host=srv1
pg1-port=5432
pg1-path=/var/lib/pgsql/14/data

pg1-host-type=tls
pg1-host-cert-file=/etc/certs/backrest-srv-cert.pem
pg1-host-key-file=/etc/certs/backrest-srv-key.pem
pg1-host-ca-file=/etc/certs/CA-cert.pem

Le serveur TLS doit ensuite être démarré avec la commande pgbackrest server. Un service est prévu à cet effet et installé automatiquement sur les distributions de type RedHat et Debian.

Un ping vers le serveur TLS peut être testé avec la commande pgbackrest server-ping <hote>. Suivant les distributions, il peut être nécessaire d’ouvrir le port 8432 (valeur par défaut de tls-server-port).

[postgres@backrest log]$ pgbackrest server-ping srv1
INFO: server-ping command begin 2.41: [srv1] --exec-id=7467-76e4b8cf
 --log-level-console=info --tls-server-address=*
INFO: server-ping command end: completed successfully (47ms)

Génération des clés et certificats auto-signés :

# Générer une clé privée et un certificat pour l'autorité de certification
openssl req -new -x509 \
                 -days 365 \ 
         -nodes \
         -out CA-cert.pem \
         -keyout CA-key.pem \
         -subj "/CN=root-ca"

# Générer une clé privée et demande de certificat (CSR)
openssl req -new -nodes \ 
                 -out backrest-srv-csr.pem \
         -keyout backrest-srv-key.pem \
         -subj "/CN=backrest-srv"
openssl req -new -nodes \
                 -out srv1-csr.pem \
         -keyout srv1-key.pem \ 
         -subj "/CN=srv1"

# Générer le certificat signé
openssl x509 -req -in backrest-srv-csr.pem \
                  -days 365 \
          -CA CA-cert.pem \
          -CAkey CA-key.pem \
          -CAcreateserial \
          -out backrest-srv-crt.pem
openssl x509 -req -in srv1.csr
                  -days 365 \
          -CA CA-cert.pem \
          -CAkey CA-key.pem \
          -CAcreateserial \
          -out srv1-crt.pem

pgBackRest - Configuration par instance

  • Une section par instance
    • appelée stanza

Après avoir vu les options globales, nous allons voir à présent les options spécifiques à chaque instance à sauvegarder.


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

Une stanza définit l’ensemble des configurations de sauvegardes pour un cluster PostgreSQL spécifique. Chaque section stanza définit l’emplacement du répertoire de données ainsi que l’hôte/utilisateur si le cluster est distant. Chaque configuration de la partie globale peut être surchargée par stanza.

Le nom de la stanza est important et doit être significatif car il sera utilisé lors des tâches d’exploitation pour identifier l’instance cible.

Il est également possible d’ajouter ici des recovery-option afin de personnaliser les options du postgresql.auto.conf qui sera généré automatiquement à la restauration d’une sauvegarde.


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

La commande d’initialisation doit être lancée sur le serveur où se situe le répertoire de stockage après que la stanza ait été configurée dans pgbackrest.conf.

La commande check valide que pgBackRest et le paramètre archive_command soient correctement configurés. Les commandes pg_create_restore_point('pgBackRest Archive Check') et pg_switch_wal() sont appelées à cet effet pour forcer PostgreSQL à archiver un segment WAL.


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

La sauvegarde accepte de nombreux paramètres dont :

  • --archive-copy : archive les WAL dans la sauvegarde en plus de les mettre dans le dépôt de WAL ;
  • --backup-standby : déclenche la sauvegarde sur un serveur secondaire ;
  • --no-online : fait une sauvegarde à froid ;
  • --resume : reprend une sauvegarde précédemment échouée en conservant les fichiers qui n’ont pas changés ;
  • --start-fast : exécuter le checkpoint immédiatement.

Exemple de sortie d’une sauvegarde complète :

$ sudo -u postgres pgbackrest --stanza=erp_prod --type=full backup |grep P00
P00   INFO: backup command begin 2.19: --log-level-console=info
--no-log-timestamp --pg1-path=/var/lib/pgsql/12/data --process-max=1
--repo1-path=/var/lib/pgsql/12/backups --repo1-retention-full=1
--stanza=erp_prod --type=full
P00   INFO: execute non-exclusive pg_start_backup() with label
"pgBackRest backup started at 2019-11-26 12:39:26":
backup begins after the next regular checkpoint completes
P00   INFO: backup start archive = 000000010000000000000005, lsn = 0/5000028
P00   INFO: full backup size = 24.2MB
P00   INFO: execute non-exclusive pg_stop_backup() and wait for all WAL
segments to archive
P00   INFO: backup stop archive = 000000010000000000000005, lsn = 0/5000100
P00   INFO: new backup label = 20191126-123926F
P00   INFO: backup command end: completed successfully
P00   INFO: expire command begin 2.19: --log-level-console=info
--no-log-timestamp --pg1-path=/var/lib/pgsql/12/data --process-max=1
--repo1-path=/var/lib/pgsql/12/backups --repo1-retention-full=1
--stanza=erp_prod --type=full
P00   INFO: expire full backup 20191126-123848F
P00   INFO: remove expired backup 20191126-123848F
P00   INFO: expire command end: completed successfully

La commande se charge automatiquement de supprimer les sauvegardes devenues obsolètes.

Il est possible d’ajouter des annotations aux sauvegardes comme ceci :

$ sudo -u postgres pgbackrest
  --stanza=erp_prod
  --type=full
  --annotation=desc="Premier backup"
  backup

L’annotation peut être observé en affichant les informations du backup set.


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

Exemple de sortie des commandes :

$ sudo -u postgres pgbackrest --stanza=erp_prod info
stanza: erp_prod
    status: ok
    cipher: none

    db (current)
        wal archive min/max (14): 000000030000000000000019/00000003000000000000001B

        full backup: 20221026-071751F
            timestamp start/stop: 2022-10-26 07:17:51 / 2022-10-26 07:17:57
            wal start/stop: 00000003000000000000001B / 00000003000000000000001B
            database size: 25.2MB, database backup size: 25.2MB
            repo1: backup set size: 3.2MB, backup size: 3.2MB
$ sudo -u postgres pgbackrest --stanza=erp_prod --set 20221026-071751F info
stanza: erp_prod
    status: ok
    cipher: none

    db (current)
        wal archive min/max (14): 000000030000000000000019/00000003000000000000001B

        full backup: 20221026-071751F
            timestamp start/stop: 2022-10-26 07:17:51 / 2022-10-26 07:17:57
            wal start/stop: 00000003000000000000001B / 00000003000000000000001B
            lsn start/stop: 0/1B000028 / 0/1B000100
            database size: 25.2MB, database backup size: 25.2MB
            repo1: backup set size: 3.2MB, backup size: 3.2MB
            database list: postgres (13748)
            annotation(s)
                desc: Premier backup

pgBackRest - Planification

  • Pas de planificateur intégré
    • le plus simple est d’utiliser cron

La planification des sauvegardes peut être faite par n’importe quel outil de planification de tâches, le plus connu étant cron.

pgBackRest maintient les traces de ses activités par défaut dans /var/log/pgbackrest avec un niveau de traces plus élevé qu’en console. Il n’est donc généralement pas nécessaire de gérer cela au niveau de la planification.


pgBackRest - Dépôts

  • Plusieurs dépôts simultanés possibles
    • Sauvegarde des journaux en parallèle
    • --repo1-option=… , appel avec --repo=1
  • Types : POSIX (NFS, ssh), CIFS, SFTP
  • Cloud : S3, Azure, GFS

pgBackRest permet de maintenir plusieurs dépôts de sauvegarde simultanément.

Un intérêt est de gérer des rétentions différentes. Par exemple un dépôt local contiendra juste les dernières sauvegardes et journaux, alors qu’un deuxième dépôt sera sur un autre site plus lointain, éventuellement moins cher, et/ou une rétention supérieure.

Les propriétés des différents dépôts (type, chemin, rétention…) se définissent avec les options repo1-path, repo2-path, etc. Désigner un dépôt particulier se fait avec --repo=1 par exemple.

Une sauvegarde se fait en désignant le dépôt, mais l’archivage est simultané sur tous les dépôts. L’archivage asynchrone est conseillé dans ce cas.

Les types de dépôts supportés sont ceux montés sur le serveur ou accessibles par ssh, NFS (avec la même attention aux options de montage que pour PostgreSQL), CIFS (avec des restrictions sur les liens symboliques ou le fsync), mais aussi ceux à base de buckets : S3 ou compatible, Google Cloud, et Azure Blob.


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

« Bundling » des petits fichiers

Si une instances contient de nombreux petits fichiers (base aux nombreuses toutes petites tables, pg_commit_ts rempli à cause de track_commit_timestamp à on, très nombreuses petites partitions, chacune avec des fichiers annexes…), il est possible de les regrouper par paquets.

repo1-bundle=y
# défauts
repo1-bundle-limit=2MiB
repo-bundle-size=20MiB

Les bundles ne sont pas conservés en cas de backup interrompu puis redémarré. Les fichiers doivent être re-sauvegardés lors de la relance. Bundles et hard-links ne peuvent pas être utilisés ensemble.

Cette fonctionnalité est particulièrement utile avec un stockage comme S3 où le coût de création de fichier est prohibitif.

Sauvegarde incrémentale en mode bloc (2.46)

La sauvegarde incrémentale par bloc permet plus de granularité en divisant les fichiers en blocs qui peuvent être sauvegardés indépendamment. C’est particulièrement intéressant pour des fichiers avec peu de modifications, car pgBackRest ne sauvegardera que quelques blocs au lieu du fichier complet (les tables et index sont segmentés en fichiers de 1 Go). Cela permet donc d’économiser de l’espace dans le dépôt de sauvegarde et accélère les restaurations par delta.

La sauvegarde incrémentale par bloc doit être activée sur tous les types de sauvegardes : full, incrémentielle ou différentielle. Cela aura pour impact de rendre la sauvegarde full un peu plus grosse du fait de la création de fichier de cartographie des blocs. En revanche, les sauvegardes différentielles et incrémentielles suivantes pourront utiliser cette cartographie pour économiser de l’espace.

La taille du bloc pour un fichier donné est définie en fonction de l’âge et de la taille du fichier. Généralement, les fichiers les plus gros et/ou les plus anciens auront des tailles de bloc supérieures. Si un fichier est assez vieux, aucune cartographie ne sera crée.

Cette fonctionnalité nécessite le bundling et s’active ainsi :

repo1-block=y 
repo1-bundle=y

pgBackRest - Restauration

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

Exemple de sortie de la commande :

$ sudo -u postgres pgbackrest --stanza=erp_prod restore |grep P00

P00   INFO: restore command begin 2.19: --log-level-console=info
--no-log-timestamp --pg1-path=/var/lib/pgsql/12/data
--process-max=1 --repo1-path=/var/lib/pgsql/12/backups --stanza=erp_prod
P00   INFO: restore backup set 20191126-123926F
P00   INFO: write updated /var/lib/pgsql/12/data/postgresql.auto.conf
P00   INFO: restore global/pg_control (performed last to ensure aborted
restores cannot be started)
P00   INFO: restore command end: completed successfully

L’option --delta permet de ne restaurer que les fichiers qui seraient différents entre la sauvegarde et le répertoire de données déjà présent sur le serveur. Elle permet de gagner beaucoup de temps pour reprendre une restauration qui a été interrompue pour une raison ou une autre, pour resynchroniser une instance qui a « décroché », pour restaurer une version légèrement antérieure ou postérieure dans du PITR.

La cible à restaurer peut être spécifiée avec --target, associé à --type. Par exemple, pour restaurer à une date précise sur une timeline précise :

pgbackrest --stanza=instance --delta \
  --type=time --target='2020-07-16 11:07:00' \
  --target-timeline=4 \
  --target-action=pause \
  --set=20200716-102845F \
  restore

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 est un outil développé avec le langage python, compatible uniquement avec les environnements Linux/Unix. Il a été développé par la société 2ndQuadrant Italia (à présent partie de EDB) et distribué sous license GPL3.


Barman - Scénario « streaming-only »