PostgreSQLLa base de données la plus sophistiquée au monde.

23.3. Sauvegardes à chaud et récupération à un instant (PITR)

En permanence, PostgreSQL™ maintient des journaux WAL (write ahead log) dans le sous-répertoire pg_xlog/ du répertoire des données du groupe. Ces journaux décrivent chaque modification effectuée sur les fichiers de données des bases. Ils existent principalement pour des raisons de sécurité suite à un arrêt brutal : si le système s'arrête brutalement, la base de données peut être restaurée pour avoir une cohérence des données en « rejouant » les entrées des journaux enregistrées depuis le dernier point de vérification. Néanmoins, l'existence de ces journaux rend possible l'utilisation d'une troisième stratégie pour la sauvegarde des bases de données : nous pouvons combiner une sauvegarde au niveau système de fichiers avec la sauvegarde des fichiers WAL. Si la récupération est nécessaire, nous restaurons la sauvegarde, puis rejouons à partir des fichiers WAL sauvegardés pour amener la sauvegarde jusqu'à la date actuelle. Cette approche est plus complexe à administrer que toutes les autres approches mais elle apporte des bénéfices significatifs :

  • Nous n'avons pas besoin de faire une sauvegarde parfaitement cohérente comme point de départ. Toute incohérence dans la sauvegarde sera corrigée par la ré-exécution des journaux (ceci n'est pas significativement différent de ce qu'il se passe lors d'une récupération après un arrêt brutal). Donc, nous n'avons pas besoin d'une fonctionnalité d'image système du système de fichiers, simplement tar ou un autre outil d'archivage.

  • Comme nous pouvons assembler une longue séquence de fichiers à WAL pour les rejouer, la sauvegarde continue est possible en continuant simplement d'archiver les fichiers WAL. Ceci est particulièrement intéressant pour les grosses bases de données où il pourrait ne pas être facile de réaliser une sauvegarde complète fréquemment.

  • Rien ne dit que nous devons rejouer les entrées WAL jusqu'à la fin. Nous pouvons stopper la ré-exécution à un certain point et avoir une image cohérente de la base de données à ce moment-là. Du coup, cette technique supporte la récupération à un instant t (PITR) : il est possible de restaurer la base de données à n'importe quel point dans le temps depuis la dernière sauvegarde de base.

  • Si nous remplissons en continue la série de fichiers WAL dans une autre machine qui a été chargée avec le même fichier de sauvegarde de base, nous avons un système « à jour en permanence » : à tout moment, nous pouvons monter la deuxième machine et avoir une copie quasi complète de la base de données.

Comme avec la technique de sauvegarde standard du système de fichiers, cette méthode supporte la restauration d'un groupe de bases de données complet, pas un sous-ensemble. De plus, il requiert beaucoup d'espace d'archivage : la sauvegarde de base peut être légère mais un système très utilisé générera beaucoup de mégaoctets de trafic WAL qui seront à archiver. Malgré tout, c'est la technique de sauvegarde préférée dans beaucoup de situations où la haute fiabilité est nécessaire.

Pour récupérer avec succès suite à l'utilisation d'une sauvegarde à chaud, vous avez besoin d'une séquence continue de fichiers WAL archivés qui s'étendent au moins jusqu'au point de départ de votre sauvegarde. Pour commencer, vous devriez configurer et tester votre procédure d'archivage des journaux WAL avant de faire votre première sauvegarde de base. Il nous faut donc commencer par vous présenter les mécanismes d'archivage des fichiers WAL.

23.3.1. Configurer l'archivage WAL

Dans un sens abstrait, un système PostgreSQL™ fonctionnel produit une séquence indéfiniment longue d'enregistrements WAL. Le système divise physiquement cette séquence en fichiers segment WAL, qui font normalement 16 Mo chaque (bien que la taille puisse être modifiée lors de la construction de PostgreSQL™). Les fichiers segment se voient donnés des noms numériques pour refléter leur position dans la séquence abstraite des WAL. Lorsque le système n'utilise pas l'archivage des WAL, il crée seulement quelques fichiers segment, puis les « recycle » en renommant les fichiers segment devenus inutiles. Il est supposé qu'un fichier segment dont le contenu précède le dernier point de vérification n'a plus d'intérêt et peut être recyclé.

Lors de l'archivage des données WAL, nous voulons capturer le contenu de chaque fichier segment une fois qu'il est rempli et sauvegarder les données quelque part avant que le fichier segment ne soit recyclé pour être réutilisé. Suivant l'application et le matériel disponible, « sauvegarder les données quelque part » peut se faire de plusieurs façons : nous pouvons copier les fichiers segment dans un répertoire NFS monté sur une autre machine, les écrire sur une cartouche (en vous assurant que vous avez un moyen de restaurer le fichier avec son nom d'origine) ou le grouper pour les graver sur un CD, ou encore autre chose. Pour fournir autant de flexibilité que possible à l'administrateur de la base de données, PostgreSQL™ essaie de ne faire aucune supposition sur la façon dont l'archivage est réalisé. À la place, PostgreSQL™ vous laisse spécifier une commande shell à exécuter pour copier le fichier segment rempli là où vous le souhaitez. La commande pourrait être aussi simple qu'un cp ou il pourrait impliquer un shell complexe -- à vous de voir.

La commande shell à utiliser est spécifiée par le paramètre de configuration archive_command qui, en pratique, sera toujours placé dans le fichier postgresql.conf. Dans cette chaîne, tout %p est remplacé par le chemin de l'archive alors que tout %f est remplacé seulement par le nom du fichier. (Le chemin est relatif au répertoire courant du serveur, c'est-à-dire le répertoire des données du cluster.) Écrivez %% si vous avez besoin d'écrire le vrai caractère % dans la commande. La commande utile la plus simple est quelque chose comme

archive_command = 'cp -i %p /mnt/serveur/repertoire_archive/%f </dev/null'

qui copiera les segments WAL archivables dans le répertoire /mnt/serveur/repertoire_archive. (Ceci est un exemple, pas une recommandation, et pourrait ne pas fonctionner sur toutes les plateformes.)

La commande d'archivage sera exécutée en tant qu'utilisateur propriétaire du serveur PostgreSQL™. Comme la série de fichiers WAL en cours d'archivage contient réellement tout ce qui se trouve dans votre base de données, vous vous assurerez que les données archivées sont protégées des autres utilisateurs ; par exemple, si les archives sont stockées dans un répertoire où se trouvent des droits de lecture pour le groupe ou pour les autres.

Il est important que la commande d'archivage renvoie le code de sortie zéro si et seulement si l'exécution a réussi. En obtenant un résultat zéro, PostgreSQL™ supposera que le fichier segment WAL a été archivé avec succès et qu'il peut le supprimer ou le recycler. Néanmoins, un statut différent de zéro indique à PostgreSQL™ que le fichier n'a pas été archivé ; il essaiera périodiquement jusqu'à ce qu'il y arrive.

La commande d'archivage devrait être généralement conçue pour refuser d'écraser tout fichier archive déjà existant. Ceci est une fonctionnalité de sécurité importante pour préserver l'intégrité de votre archive dans le cas d'une erreur de l'administrateur (comme l'envoi de la sortie de deux serveurs différents dans le même répertoire d'archivage). Il est conseillé de tester votre commande d'archivage proposée pour vous assurer qu'en effet il n'écrase pas un fichier existant et qu'il renvoie un statut différent de zéro dans ce cas. Nous avons découvert que cp -i travaille correctement sur certaines plateformes, mais pas sur toutes. Si la commande choisie ne gère pas elle-même ce cas, vous pouvez ajouter une commande pour tester l'existence du fichier d'archivage. Par exemple, quelque chose comme

archive_command = 'test ! -f .../%f && cp %p .../%f'

fonctionne correctement sur la plupart des variantes Unix.

Lors de la conception de votre configuration d'archivage, considérez ce qui se passerait si la commande d'archivage échouait de façon répétée parce que certains aspects demanderaient une intervention de l'opérateur ou à cause d'un manque d'espace dans le répertoire d'archivage. Par exemple, ceci pourrait arriver si vous écrivez sur une cartouche sans changeur automatique ; quand la cartouche est remplie, rien ne peut être archivé tant que la cassette n'est pas changée. Vous devez vous assurer que toute erreur ou requête à un opérateur humain est rapportée de façon approprié pour que la situation puisse être résolue relativement rapidement. Le répertoire pg_xlog/ continuera à se remplir de fichiers segment WAL jusqu'à la résolution de la situation.

La vitesse de la commande d'archivage n'est pas importante, tant qu'elle est au même rythme que la génération de données WAL du serveur. Les opérations normales continuent même si le processus d'archivage est un peu plus lent. Si l'archivage est significativement plus lent, alors la quantité de données qui pourrait être perdue va croître. Cela signifie aussi que le répertoire pg_xlog/ contiendra un grand nombre de fichiers segment non archivés, qui finiront éventuellement par dépasser l'espace disque disponible. Il vous est conseillé de surveiller le processus d'archivage pour vous assurer que tout fonctionne normalement.

Si vous êtes encore inquiet sur votre capacité à récupérer tout à l'instant présent, vous devriez prendre quelques actions supplémentaires pour vous assurer que les fichiers segments WAL partiellement remplis sont aussi copiés quelque part. Ceci est particulièrement important si votre serveur génère peu de trafic WAL (ou que seules certaines périodes sont dans ce cas) car cela prendra beaucoup de temps avant qu'un fichier segment WAL soit complètement remplis et prêt à archiver. Une façon possible de gérer ceci est de configurer un job cron qui, périodiquement (une fois par minute, peut-être), identifie le fichier segment WAL en cours et le sauvegarde à un endroit sûr. Ensuite, la combinaison des segments WAL archivés et du segment courant sauvegardé seront suffisant pour vous assurer de pouvoir toujours restaurer à une minute près. Ce comportement n'est pas actuellement construit dans PostgreSQL™ parce que nous ne voulions pas compliquer la définition de archive_command en lui demandant de garder trace des différentes copies archivées successivement du même fichier WAL. archive_command est seulement appelée sur des segments WAL complets. Sauf dans le cas d'un échec, il sera appelé seulement une fois pour un nom de fichier donné.

En écrivant votre commande d'archivage, vous devez vous assurer que les noms de fichier à archiver auront 64 caractères maximum et peuvent contenir toute combinaison de lettres ASCII, de chiffres et de points. Il n'est pas nécessaire de rappeler le chemin complet original (%p) mais il est nécessaire de rappeler le nom du fichier (%f).

Notez que, bien que l'archivage WAL vous autorisera à restaurer toute modification réalisée sur les données de votre base PostgreSQL™, il ne restaurera pas les modifications effectuées sur les fichiers de configuration (c'est-à-dire postgresql.conf, pg_hba.conf et pg_ident.conf) car ceux-ci sont édités manuellement plutôt qu'au travers d'opérations SQL. Vous pourriez souhaiter conserver les fichiers de configuration à un endroit où ils seront sauvegardés avec vos procédures standards de sauvegarde du système de fichiers. Voir la Section 17.2, « Emplacement des fichiers » pour savoir comment modifier l'emplacement des fichiers de configuration.

23.3.2. Réaliser une sauvegarde de base

La procédure pour réaliser une sauvegarde de base est relativement simple :

  1. Assurez-vous que l'archivage WAL est activé et fonctionnel.

  2. Connectez-vous à la base de données en tant que superutilisateur et lancez la commande

    SELECT pg_start_backup('label');
    

    label est toute chaîne que vous voulez utiliser pour identifier de façon unique l'opération de sauvegarde (une bonne pratique est d'utiliser le chemin complet où vous avez l'intention de placer le fichier de sauvegarde). pg_start_backup crée un fichier label de sauvegarde nommé backup_label dans le répertoire du groupe avec des informations sur votre sauvegarde.

    Peu importe la base de données à laquelle vous vous connectez pour lancer cette commande. Vous pouvez ignorer le résultat renvoyé par la fonction mais, si elle rapporte une erreur, gérez-la avant de continuer.

  3. Effectuez la sauvegarde à l'aide de tout outil de sauvegarde du système de fichiers, tel tar ou cpio. Il n'est ni nécessaire ni désirable de stopper les opérations normales de la base de données pour cela.

  4. Connectez-vous de nouveau sur la base de données en tant que superutilisateur et lancez la commande

    SELECT pg_stop_backup();
    

    Elle devrait réussir.

  5. Une fois que les fichiers des segments WAL utilisés lors de la sauvegarde sont archivés de la même façon qu'une partie de l'activité normale de sauvegarde de la base de données, vous avez terminé.

Certains outils de sauvegarde que vous souhaiteriez utiliser émettent des messages d'avertissements ou d'erreurs si les fichiers qu'ils essaient de copier changent lors de la copie. Cette situation est normale, ce n'est pas une erreur, lors de la création de la sauvegarde de base d'une base de données active ; vous devez donc vous assurer que vous pouvez distinguer les messages de cette sorte des autres messages. Par exemple, certaines versions de rsync renvoient un code de sortie séparé pour des « fichiers source disparus », et vous pouvez écrire un script qui accepte ce code de sortie comme un cas normal. De plus, certaines versions de GNU tar considèrent que la modification d'un fichier lors de sa copie par tar est une erreur. Il ne semble pas exister de moyen simple pour distinguer cette erreur des autres types d'erreurs, autrement qu'en inspectant manuellement les messages de tar. Du coup, GNU tar n'est pas le meilleur outil pour réaliser des sauvegardes de base.

Il n'est pas nécessaire d'être très concerné sur le temps passé entre pg_start_backup et le début réel de la sauvegarde, pas plus qu'entre la fin de la sauvegarde et pg_stop_backup ; un délai de quelques minutes ne posera pas de problème. Vous devez néanmoins vous assurer que ces opérations sont effectuées dans la bonne séquence et ne se recouvrent pas.

Assurez-vous que votre sauvegarde inclut tous les fichiers du répertoire du groupe de bases de données (c'est-à-dire /usr/local/pgsql/data). Si vous utilisez des tablespaces qui ne se trouvent pas dans ce répertoire, faites attention à bien les inclure (et assurez-vous que votre sauvegarde archive les liens symboliques comme des liens, sinon la restauration posera problème pour les tablespaces).

Néanmoins, vous devriez omettre de sauvegarder les fichiers du sous-répertoire pg_xlog/ contenu dans le répertoire du groupe. Cette petite complication est intéressante parce qu'elle réduit le risque d'erreurs lors de la restauration. Ceci est facile à arranger si pg_xlog/ est un lien symbolique pointant quelque part à l'extérieur du répertoire du groupe, ce qui est une configuration commune pour des raisons de performance.

Pour utiliser cette sauvegarde, vous aurez besoin de conserver les fichiers segments WAL générés pendant ou après le lancement de la sauvegarde. Pour vous aider dans ce travail, la fonction pg_stop_backup crée un fichier historique de la sauvegarde qui est immédiatement stocké dans l'aire des archives WAL. Ce fichier est nommé d'après le nom du premier fichier segment WAL dont vous avez besoin pour utiliser la sauvegarde. Par exemple, si le fichier WAL du début est 0000000100001234000055CD, le fichier historique sera nommé quelque chose comme 0000000100001234000055CD.007C9330.backup (le deuxième nombre dans le nom de ce fichier contient la position exacte à l'intérieur du fichier WAL et peut être habituellement ignorée). Une fois que vous avez archivé de façon sûre la sauvegarde du système de fichiers et les segments WAL utilisés pendant la sauvegarde (comme spécifié dans le fichier d'historique des sauvegardes), tous les segments WAL archivés avec des noms numériquement plus petits ne sont plus nécessaires pour la récupération de la sauvegarde du système de fichiers et pourraient être supprimés. Néanmoins, vous devriez penser à conserver plusieurs ensembles de sauvegarde pour être absolument certain de pouvoir récupérer vos données. Gardez en tête que seuls les fichiers WAL complets sont archivés, donc il y aura un délai entre l'exécution de pg_stop_backup et l'archivage de tous les fichiers de segment WAL pour rendre la sauvegarde du système de fichiers cohérente.

Le fichier d'historique de la sauvegarde est un simple fichier texte. Il contient le label que vous avez donné à pg_start_backup, ainsi que l'heure de début et de fin, et les segments WAL de la sauvegarde. Si vous utilisez le label pour identifier où le fichier de sauvegarde associé est conservé, alors le fichier historique archivé est suffisant pour vous dire quel fichier de sauvegarde restaurer, si vous en avez besoin.

Comme vous devez conserver tous les fichiers WAL archivés depuis votre dernière sauvegarde de base, l'intervalle entre les sauvegardes de base devrait habituellement être choisie suivant la quantité de stockage que vous voulez consommer en fichiers archives WAL. Vous devriez aussi considérer combien de temps vous êtes prêt à dépenser pendant la récupération, si celle-ci est nécessaire -- le système devra rejouer tous les segments WAL et ceci peut prendre beaucoup de temps si la dernière sauvegarde de base est ancienne.

Il est aussi important de noter que la fonction pg_start_backup crée un fichier nommé backup_label dans le répertoire du groupe de bases de données qui est ensuite supprimé de nouveau par pg_stop_backup. Ce fichier sera bien sûr archivé comme faisant parti du fichier de sauvegarde. Le fichier label de la sauvegarde inclut la chaîne label que vous avez donné à pg_start_backup, ainsi que l'heure à laquelle pg_start_backup a été exécuté et le nom du fichier WAL du début. En cas de confusion, il sera du coup possible de regarder dans le fichier sauvegarde et de déterminer exactement de quelle session de sauvegarde provient ce fichier.

Il est aussi possible de faire une sauvegarde alors que le postmaster est arrêté. Dans ce cas, vous ne pouvez évidemment pas utiliser pg_start_backup ou pg_stop_backup et vous serez donc contraint à garder trace vous-même des fichiers de sauvegarde et de jusqu'où vont les fichiers WAL associés. Il est généralement mieux de suivre la procédure de sauvegarde à chaud ci-dessus.

23.3.3. Récupérer à partir d'une sauvegarde à chaud

OK, le pire est arrivé et vous avez besoin de récupérer votre sauvegarde. Voici la procédure :

  1. Arrêtez le postmaster s'il est en cours d'exécution.

  2. Si vous avez de la place pour le faire, copiez le répertoire entier des données du groupe et tout tablespace dans un emplacement temporaire au cas où vous en auriez besoin plus tard. Notez que cette précaution demandera que vous ayez assez de place libre sur votre système pour contenir deux copies de votre base de données existante. Si vous n'avez pas assez de place, vous devez au moins copier le contenu du sous-répertoire pg_xlog du répertoire des données car il pourrait contenir des journaux qui n'ont pas été archivés avant l'arrêt du serveur.

  3. Effacez tous les fichier et sous-répertoires existants sous le répertoire des données du groupe et sous les répertoires racines des tablespaces que vous utilisez.

  4. Restaurez les fichiers de la base de données à partir de votre sauvegarde. Faites attention à ce qu'ils soient restaurés avec le bon propriétaire (l'utilisateur système de la base de données, et non pas root !) et avec les bons droits. Si vous utilisez les espaces logiques, vous vérifirez que les liens symboliques dans pg_tblspc/ ont été correctement restaurés.

  5. Supprimez tout fichier présent dans pg_xlog/ ; ils proviennent de la sauvegarde et sont du coup probablement obsolètes. Si vous n'avez pas archivé pg_xlog/ du tout, alors re-créez ce répertoire ainsi que le sous-répertoire pg_xlog/archive_status/.

  6. Si vous aviez des fichiers segments WAL non archivés que vous avez sauvegardé dans l'étape 2, copiez-les dans pg_xlog/ (il est mieux de les copier, pas de les déplacer, car vous aurez toujours les fichiers non modifiés si un problème survient et que vous devez recommencer).

  7. Créez un fichier de commandes de récupération recovery.conf dans le répertoire des données du groupe (voir Configuration de la récupération). De plus, vous pourriez vouloir modifier temporairement pg_hba.conf pour empêcher les utilisateurs ordinaires de se connecter tant que vous n'êtes pas certain que la récupération a réussi.

  8. Lancez le postmaster. Le postmaster se trouvera en mode récupération et commencera la lecture des fichiers WAL archivés dont il a besoin. À la fin du processus de récupération, le postmaster renommera recovery.conf en recovery.done (pour empêcher de retourner accidentellement en mode de récupération dans le cas d'un arrêt brutal un peu plus tard), puis commencera les opérations normales de la base de données.

  9. Inspectez le contenu de la base de données pour vous assurer que vous avez récupéré ce que vous vouliez. Sinon, retournez à l'étape 1. Si tout va bien, laissez vos utilisateurs venir en restaurant le fichier pg_hba.conf à son état normal.

La partie clé de tout ceci est de configurer le fichier de commandes de récupération. Il décrit comment vous voulez récupérer et à quel point la récupération doit fonctionner. Vous pouvez utiliser recovery.conf.sample (normalement présent dans le répertoire d'installation share/) comme prototype. La seule chose que vous devez absolument spécifier dans recovery.conf est restore_command indiquant à PostgreSQL™ comment récupérer les fichiers segments WAL archivés. Comme archive_command, ceci est une chaîne contenant le nom de la commande. Elle pourrait contenir %f, qui est remplacé par le nom du journal souhaité, et %p, qui est remplacé par le chemin du répertoire où copier le journal. (Le chemin est relatif au répertoire courant du serveur, c'est-à-dire le répertoire des données du cluster.) Écrivez %% si vous avez besoin d'embarquer un vrai caractère % dans la commande. La commande utile la plus simple est quelque chose comme

restore_command = 'cp /mnt/serveur/répertoire_archive/%f %p'

qui copiera les segments WAL précédemment archivés à partir du répertoire /mnt/serveur/répertoire_archive. Vous pourriez bien sûr utiliser quelque chose de plus compliqué, peut-être même un script shell qui demandera à l'utilisateur de monter la cassette appropriée.

Il est important que la commande renvoie un code de sortie différent de zéro en cas d'échec. La commande se verra demander les journaux absents de l'archive ; il doit renvoyer autre chose que zéro dans ce cas. Ceci n'est pas une condition d'erreur. Soyez conscient que le nom de base du chemin %p sera différent de %f ; ne vous attendez pas à ce qu'ils soient interchangeables.

Les segments WAL qui n'ont pas pu être trouvés dans l'archive seront recherchés dans pg_xlog/ ; cela autorise l'utilisation des segments non archivés. Néanmoins, les segments disponibles à partir de l'archive seront utilisés de préférence par rapport aux fichiers dans pg_xlog/. Le système ne surchargera pas le contenu existant de pg_xlog/ lors de la récupération des fichiers archivés.

Normalement, la récupération traitera tous les segments WAL disponibles, restaurant du coup la base de données à cet instant (ou aussi proche que nous le pouvons suivant les segments WAL disponibles). Mais, si vous voulez récupérer à un instant particulier (disons, juste avant que l'administrateur junior ait supprimé votre table principale de transaction), spécifiez simplement le point d'arrêt requis dans recovery.conf. Vous pouvez spécifier le point d'arrêt, connu sous le nom de « cible de récupération », soit par la date/heure soit par l'ID de la dernière transaction. Au moment où nous écrivons ceci, seule l'option date/heure est tout à fait utilisable car il n'existe pas d'outils pour vous aider à identifier avec une certaine précision l'ID de transaction à utiliser.

[Note]

Note

Le point d'arrêt doit se situer après l'heure de fin de la sauvegarde de base (le moment de pg_stop_backup). Vous ne pouvez pas utiliser une sauvegarde de base pour récupérer à un tel instant où la sauvegarde était encore en cours (pour récupérer jusqu'à cet instant, vous devez récupérer votre sauvegarde de base précédente et recommencer à partir de là).

23.3.3.1. Configuration de la récupération

Ces configurations peuvent seulement être placées dans le fichier recovery.conf et s'appliquent seulement pour la durée de la récupération. Ils doivent être réinitialisés pour toute récupération ultérieure que vous souhaitez réaliser. Ils ne peuvent pas être modifiés une fois que la récupération a commencé.

restore_command (string)

La commande shell à exécuter pour récupérer un segment archivé de la série de fichiers WAL. Ce paramètre est requis. Tout %f dans la chaîne est remplacé par le nom du fichier à récupérer à partir de l'archive et tout %p est remplacé par le chemin pour le copier sur le serveur. (Le chemin est relatif au répertoire courant du serveur, c'est-à-dire le répertoire des données du cluster.) Écrivez %% pour embarquer un vrai caractère % dans la commande

Il est important que la commande renvoie un code de sortie zéro si et seulement si elle a réussi. La commande se verra demander les noms des fichiers absents dans l'archive ; elle doit renvoyer une valeur différente de zéro dans ce cas. Exemples :

restore_command = 'cp /mnt/serveur/reparchives/%f "%p"'
restore_command = 'copy /mnt/serveur/reparchives/%f "%p"'  # Windows
recovery_target_time (timestamp)

Ce paramètre spécifie le temps à partir duquel le serveur doit arrêter la récupération. Au plus un entre recovery_target_time et recovery_target_xid peut être spécifié. Par défaut, la récupération se passe jusqu'à la fin du journal WAL. Le point d'arrêt précis est aussi influencé par recovery_target_inclusive.

recovery_target_xid (string)

Ce paramètre spécifie l'ID de transaction où arrêter la récupération. Gardez en tête qu'alors que les ID de transactions sont affectés séquentiellement au début de la transaction, les transactions peuvent se terminer dans un ordre numérique différent. Les transactions qui seront récupérées sont celles qui ont été validées avant celle spécifiée (et quelque fois en l'incluant). Au plus un entre recovery_target_xid et recovery_target_time peut être spécifié. La valeur par défaut est de récupérer jusqu'à la fin du journal WAL. Le point d'arrêt précis est aussi influencé par recovery_target_inclusive.

recovery_target_inclusive (boolean)

Spécifie si nous stoppons tout de suite après la cible de récupération spécifiée (true) ou tout juste avant (false). S'applique à recovery_target_time et recovery_target_xid, quelque soit celui qui est spécifié pour cette récupération. Ceci indique si les transactions ayant exactement l'instant de validation cible ou l'ID, respectivement, seront inclus dans la récupération. La valeur par défaut est true.

recovery_target_timeline (string)

Spécifie la récupération à un timeline particulier. La valeur par défaut est de récupérer suivant le timeline en cours au moment où la sauvegarde de base a été effectuée. Vous aurez seulement besoin de configurer ce paramètre dans les situations complexes de récupération où le besoin de retourner à un état qui a été atteint après une récupération à un temps donné. Voir la Section 23.3.4, « Timelines » pour des informations.

23.3.4. Timelines

La possibilité de restaurer la base de données à un instant précédent crée une complexité qui sont la base des histoires de science-fiction sur le voyage dans le temps et les univers parallèles. Dans l'historique original de la base de données, vous avez peut-être supprimé une table critique à 17h15 mardi soir. Imperturbable, vous récupérez votre sauvegarde, la restaurez jusqu'à 17h14 mardi soir et êtes de nouveau fonctionnel. Dans cette histoire de l'univers de la base de données, vous n'avez jamais supprimé la table. Mais, supposez que vous réalisez plus tard qu'après tout, ce n'était pas une si grande idée et que vous voudriez revenir à un point plus lointain dans l'historique original. Vous ne serez plus capable de le faire si, une fois que votre base de donnée était de nouveau fonctionnelle, elle a écrit par dessus certaines des séquences de fichiers segments WAL qui vous aurait permis de récupérer à cet instant. Donc, vous voulez réellement distinguer les séries d'enregistrements WAL générées après la récupération à un instant donné de celles générées dans l'historique originale de la base de données.

Pour gérer ces problèmes, PostgreSQL™ comprends la notion de timelines. À chaque fois qu'une restauration d'archive est terminée, un nouveau timeline est créé pour identifier la série d'enregistrements WAL générés après cette restauration. Le numéro d'identifiant de la timeline fait partie des noms des fichiers segment WAL et, du coup, une nouvelle timeline ne réécrit pas sur les données générées par des timelines précédentes. En fait, il est possible d'archiver plusieurs timelines différentes. Bien que cela semble être une fonctionnalité inutile, parfois, cela vous sauve la vie. Considérez la situation où vous n'êtes plus sûr de l'instant jusqu'où récupérer. Du coup, vous devez tester des récupérations à différents instants jusqu'à trouver le meilleur moment dans l'ancien historique. Sans les timelines, ce processus génèrerait un incroyable bazar. Avec les timelines, vous pouvez récupérer à n'importe quel état précédent, ceci incluant les états dans les branches de timelines que vous abandonnerez plus tard.

Chaque fois qu'une nouvelle timeline est créée, PostgreSQL™ crée un fichier d'« historique des timeline » qui montre les timelines, leur branchement et le moment auquel c'est arrivé. Ces fichiers historiques sont requis pour permettre au système de récupérer les bons fichiers segment WAL lors de la récupération à partir d'une archive contenant plusieurs timelines. Du coup, elles sont archivées dans l'aire des WAL comme tous les fichiers segment WAL. Les fichiers historiques sont de simples fichiers texte, donc il est peu coûteux et approprié de les conserver indéfiniment (contrairement aux fichiers segments qui sont gros). Vous pouvez, si vous le souhaitez, ajouter des commentaires au fichier historique pour ajouter vos propres notes sur comment et pourquoi cette timeline est particulièrement intéressante. De tels commentaires seront particulièrement utiles quand vous avez un ticket des différentes timelines comme résultat de l'expérimentation.

Le comportement par défaut de la récupération est de récupérer parmi la timeline en cours au moment où la sauvegarde de base a été effectuée. Si vous voulez récupérer à une timeline enfant (c'est-à-dire si vous voulez retourner à un état qui a été enregistré après la tentative de récupération), vous avez besoin de spécifier l'ID cible de la timeline dans recovery.conf. Vous ne pouvez pas récupérer des timelines qui ont effectué leur branchement plus tôt que le moment où a été effectuée la sauvegarde de base.

23.3.5. Avertissements

Au moment où nous écrivons ces lignes, il existe plusieurs limitations sur la technique de sauvegarde à chaud. Elles seront probablement corrigées dans une prochaine version :

  • Les opérations sur des index hachés ou R-tree ne sont pas tracées actuellement dans les WAL, donc ces types d'index ne seront pas mis à jour. Le contournement recommandé est de REINDEXer manuellement chacun de ces index après avoir terminé une opération de récupération.

  • Si une commande CREATE DATABASE est exécutée alors qu'une sauvegarde est en cours, alors la base de données modèle que l'instruction CREATE DATABASE a copié est modifiée alors que la sauvegarde de la base est toujours en cours, il est possible que la récupération sera la cause de la propagation des modifications dans la base de données créée. Pour éviter ce risque, il est préférable de ne pas modifier les bases de données modèles lors d'une sauvegarde de base.

  • Les commandes CREATE TABLESPACE sont tracées dans WAL avec le chemin absolu littéral et seront donc rejouées en tant que créations de tablespaces avec le même chemin absolu. Ceci pourrait être indésirable si la trace est rejouée sur la même machine mais dans un nouveau répertoire de données : la ré-exécution surchargera toujours le contenu du tablespace original. Pour éviter des problèmes potentiels de cette sorte, la meilleure pratique est de prendre une nouvelle sauvegarde de base après la création ou la suppression d'espaces logiques.

De plus, il devrait être noté que le format actuel des WAL est extrêmement difficile à gérer car il inclut de nombreuses images des pages disques. Ces images de page sont conçues pour supporter la récupération après un arrêt brutal car nous pouvons avoir besoin de corriger des pages disque partiellement écrites. Suivant le matériel et le logiciel de votre système, le risque d'écriture partielle pourrait être assez faible pour être ignoré, auquel cas vous pouvez réduire significativement le volume total des traces archivées en désactivat les images de page grâce au paramètre full_page_writes (lire les notes et avertissements dans Chapitre 26, Fiabilité et journaux de transaction avant de le faire). Désactiver les images de page n'empêche pas l'utilisation des traces pour les opérations PITR. Un développement possible serait de compresser les données des WAL archivées en supprimant les copies inutiles de pages même si full_page_writes est actif. Entre temps, les administrateurs pourraient souhaiter réduire le nombre d'images de pages inclus dans WAL en augmentant autant que possible les paramètres d'intervalle des points de vérification.