23.3. Archivage continu et récupération d'un instantané (PITR)
PostgreSQL™ maintient en
permanence des journaux WAL (write ahead
log) dans le sous-répertoire pg_xlog/
du répertoire de données du cluster. Ces journaux décrivent chaque
modification effectuée sur les fichiers de données des bases. Ils
existent principalement pour se prémunir des suites d'un arrêt brutal
: si le système s'arrête brutalement, la base de données peut être
restaurée dans un état cohérent 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 : la combinaison d'une
sauvegarde de niveau système de fichiers avec la sauvegarde des
fichiers WAL. Si la récupération est nécessaire, la sauvegarde est
restaurée, puis les fichiers WAL sauvegardés sont rejoué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 :
-
Il n'est pas nécessaire de disposer d'une sauvegarde
parfaitement cohérente comme point de départ. Toute incohérence
dans la sauvegarde est 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).
La fonctionnalité d'image du système de fichiers n'est alors
pas nécessaire, tar ou tout
autre outil d'archivage est suffisant.
-
Puisqu'une longue séquence de fichiers WAL peut être assemblée
pour être rejouée, une sauvegarde continue est obtenue en
continuant simplement à archiver les fichiers WAL. C'est
particulièrement intéressant pour les grosses bases de données
dont une sauvegarde complète fréquente est difficilement
réalisable.
-
Les entrées WAL ne doivent pas obligatoirement être rejouées
intégralement. La ré-exécution peut être stoppée en tout point,
tout en garantissant une image cohérente de la base de données
telle qu'elle était à ce moment-là. Ainsi, cette technique
autorise la récupération d'un
instantané (PITR) : il est possible de restaurer l'état de
la base de données telle qu'elle était en tout point dans le
temps depuis la dernière sauvegarde de base.
-
Si la série de fichiers WAL est fournie en continu à une autre
machine chargée avec le même fichier de sauvegarde de base, on
obtient un système « de reprise
intermédiaire » (
warm
standby
) : à tout moment, la deuxième machine peut
être montée et disposer d'une copie quasi-complète de la base
de données.
Tout comme la technique de sauvegarde standard du système de
fichiers, cette méthode ne supporte que la restauration d'un cluster
de bases de données complet, pas d'un sous-ensemble. De plus, un
espace d'archivage important est requis : la sauvegarde de la base
peut être volumineuse et un système très utilisé engendre un trafic
WAL à archiver de plusieurs Mo. Malgré tout, c'est la technique de
sauvegarde préférée dans de nombreuses situations où une haute
fiabilité est requise.
Une récupération fructueuse à partir de l'archivage continu (aussi
appelé sauvegarde à chaud par certains vendeurs de SGBD) nécessite
une séquence ininterrompue de fichiers WAL archivés qui s'étend au
moins jusqu'au point de départ de la sauvegarde. Pour commencer, il
faut configurer et tester la procédure d'archivage des journaux WAL
avant
d'effectuer la première
sauvegarde de base. C'est pourquoi la suite du document commence par
présenter les mécanismes d'archivage des fichiers WAL.
23.3.1. Configurer l'archivage WAL
Au sens abstrait, un système PostgreSQL™ fonctionnel produit une
séquence infinie d'enregistrements WAL. Le système divise
physiquement cette séquence en fichiers de
segment WAL de 16 Mo chacun (en général, mais cette taille
peut être modifiée lors de la construction de PostgreSQL™). Les fichiers de segment
reçoivent 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 ne crée que quelques fichiers de segment,
qu'il « recycle » en renommant
les fichiers de segment devenus inutiles. Un fichier segment dont
le contenu précède le dernier point de vérification est supposé
inutile et peut être recyclé.
Lors de l'archivage des données WAL, le contenu de chaque fichier
de segment doit être capturé dès qu'il est rempli pour sauvegarder
les données ailleurs avant son recyclage. En fonction de
l'application et du matériel disponible, « sauvegarder les données ailleurs » peut se
faire de plusieurs façons : les fichiers de segment peuvent être
copiés dans un répertoire NFS monté sur une autre machine, être
écrits sur une cartouche (après s'être assuré qu'il existe un moyen
d'identifier le nom d'origine de chaque fichier) ou être groupés
pour gravage sur un CD, ou tout à fait 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™ permet de préciser la
commande shell à exécuter pour copier le fichier de segment complet
à l'endroit désiré. La commande peut être aussi simple qu'un
cp ou impliquer un shell complexe -- c'est
l'utilisateur qui décide.
La commande shell à utiliser est indiquée à l'aide du paramètre de
configuration archive_command
qui, en pratique, est toujours placé dans le fichier postgresql.conf. Dans cette chaîne, tout %p est remplacé par le chemin absolu de l'archive
alors que tout %f n'est remplacé que par
le nom du fichier. (Le nom du chemin est relatif au répertoire de
travail du serveur, c'est-à-dire le répertoire des données du
cluster.) %% est utilisé pour écrire le
caractère % dans la commande. La commande
la plus simple ressemble à
archive_command = 'cp -i %p /mnt/serveur/repertoire_archive/%f </dev/null'
qui copie les segments WAL archivables dans le répertoire
/mnt/serveur/repertoire_archive. (Ceci
est un exemple, pas une recommandation, et peut ne pas fonctionner
sur toutes les plateformes.)
La commande d'archivage est exécutée sous l'identité de
l'utilisateur propriétaire du serveur PostgreSQL™. La série de fichiers WAL en
cours d'archivage contient absolument tout ce qui se trouve dans la
base de données, il convient donc de s'assurer que les données
archivées sont protégées des autres utilisateurs ; on peut, par
exemple, archiver dans un répertoire sur lequel les droits de
lecture ne sont positionnés ni pour le groupe ni pour le reste du
monde.
Il est important que la commande d'archivage ne renvoie le code de
sortie zéro que si, et seulement si, l'exécution a réussi. En
obtenant un résultat zéro, PostgreSQL™ suppose que le fichier
segment WAL a été archivé avec succès et qu'il peut le supprimer ou
le recycler. Un statut différent de zéro indique à PostgreSQL™ que le fichier n'a pas été
archivé ; il essaie alors périodiquement jusqu'à la réussite de
l'archivage.
La commande d'archivage doit en général être conçue pour refuser
d'écraser tout fichier archive qui existe déjà. C'est une
fonctionnalité de sécurité importante pour préserver l'intégrité de
l'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 la commande
d'archivage proposée pour s'assurer qu'en effet elle n'écrase pas
un fichier existant
et qu'elle retourne
un statut différent de zéro dans ce cas
. Il a été
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, il convient d'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 la configuration d'archivage, il faut
considérer ce qui arrive si la commande d'archivage échoue de façon
répétée, parce que certains aspects demandent une intervention de
l'opérateur ou par manque d'espace dans le répertoire d'archivage.
Ceci peut arriver, par exemple, lors de l'écriture sur une
cartouche sans changeur automatique ; quand la cartouche est
pleine, rien ne peut être archivé tant que la cassette n'est pas
changée. Toute erreur ou requête à un opérateur humain doit être
rapportée de façon approprié pour que la situation puisse être
résolue rapidement. Le répertoire pg_xlog/ continue à se remplir de fichiers de
segment WAL jusqu'à la résolution de la situation.
La vitesse de la commande d'archivage n'est pas importante, tant
qu'elle suit le 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 peut être perdue croît. Cela
signifie aussi que le répertoire pg_xlog/
contient un grand nombre de fichiers segment non archivés, qui
peuvent finir par dépasser l'espace disque disponible. Il est
conseillé de surveiller le processus d'archivage pour s'assurer que
tout fonctionne normalement.
Lors de l'écriture de la commande d'archivage, il faut garder à
l'esprit que les noms de fichier à archiver peuvent contenir
jusqu'à 64 caractères et être composés de toute combinaison de
lettres ASCII, de chiffres et de points. Il n'est pas nécessaire de
retenir le chemin relatif original (%p)
mais il est nécessaire de rappeler le nom du fichier (%f).
Bien que l'archivage WAL autorise à restaurer toute modification
réalisée sur les données de la base PostgreSQL™, il ne restaure 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
et non au travers d'opérations SQL. Il est souhaitable de conserver
les fichiers de configuration à un endroit où ils sont sauvegardés
par les procédures standard 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.
La commande d'archivage n'est appelée que sur les segments WAL
complets. Du coup, si le serveur engendre peu de trafic WAL (ou
qu'il y a des périodes de calme où le trafic WAL est léger), il
peut y avoir une longue période entre la fin d'une transaction et
son enregistrement sûr dans le stockage d'archive. Pour placer une
limite sur l'ancienneté des données archivées, on configure
archive_timeout
qui force le serveur à changer de fichier segment WAL passé ce
délai. Les fichiers archivés lors d'un tel forçage ont toujours la
même taille que les fichiers complets. Il est donc déconseillé de
configurer un délai archive_timeout trop
court -- cela fait grossir anormalement le stockage. Une minute
pour archive_timeout est généralement
raisonnable.
De plus, le changement d'un segment peut être forcé manuellement
avec pg_switch_xlog. Cela permet de
s'assurer qu'une transaction tout juste terminée est immédiatement
archivée. D'autres fonctions utilitaires relatives à la gestion des
WAL sont disponibles dans Tableau 9.47,
« Fonctions de contrôle de la sauvegarde ».
23.3.2. Réaliser une sauvegarde de base
La procédure pour réaliser une sauvegarde de base est relativement
simple :
-
S'assurer que l'archivage WAL est activé et fonctionnel.
-
Se connecter à la base de données en tant que
superutilisateur et lancer la commande
SELECT pg_start_backup('label');
où label est une chaîne utilisée
pour identifier de façon unique l'opération de sauvegarde
(une bonne pratique est d'utiliser le chemin complet du
fichier de sauvegarde). pg_start_backup crée un fichier de label de sauvegarde nommé backup_label dans le répertoire du cluster.
Ce fichier contient les informations de la sauvegarde.
La base de données de connexion utilisée pour lancer cette
commande n'a aucune importance. Le résultat de la fonction
peut être ignoré, mais il faut gérer l'erreur éventuelle
avant de continuer.
-
Effectuer 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.
-
Se connecter à nouveau à la base de données en tant que
superutilisateur et lancer la commande
SELECT pg_stop_backup();
Cela met fin au processus de sauvegarde et réalise un
basculement automatique vers le prochain segment WAL. Ce
basculement est nécessaire pour permettre au dernier fichier
de segment WAL écrit pendant la sauvegarde d'être
immédiatement archivable.
-
Une fois que les fichiers des segments WAL utilisés lors de
la sauvegarde sont archivés, c'est terminé. Le fichier
identifié par le résultat de pg_stop_backup est le dernier segment à
archiver pour terminer la sauvegarde. L'archivage de ces
fichiers intervient automatiquement car archive_command est déjà configuré. Dans de
nombreux cas, c'est assez rapide mais il est conseillé de
surveiller le système d'archivage pour s'assurer que celui-ci
s'effectue correctement et que la sauvegarde est complète.
Certains outils de sauvegarde émettent des messages
d'avertissements ou d'erreurs si les fichiers qu'ils essaient de
copier sont modifiés au cours de la copie. Cette situation, normale
lors de la sauvegarde d'une base active, ne doit pas être
considérée comme une erreur ; il suffit de s'assurer que ces
messages peuvent être distingués des autres messages. Certaines
versions de rsync, par exemple,
renvoient un code de sortie distinct en cas de « disparition de fichiers source ». Il est
possible d'écrire un script qui considère ce code de sortie comme
normal.
De plus, certaines versions de GNU tar retournent un code d'erreur qu'on peut
confondre avec une erreur fatale si le fichier a été tronqué
pendant sa copie par tar.
Heureusement, les versions 1.16 et suivantes de GNU tar retournent 1 si
le fichier a été modifié pendant la sauvegarde et 2 pour les autres erreurs.
Il n'est pas utile d'accorder de l'importance au 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
pose pas de problème. (Néanmoins, si le serveur est normalement
utilisé alors que full_page_writes est
désactivé, une perte de performances entre pg_start_backup et pg_stop_backup peut être constatée car full_page_writes est réellement forcée lors du mode
de sauvegarde.) Il convient toutefois de s'assurer que ces étapes
sont effectuées séquentiellement, sans chevauchement. Dans le cas
contraire, la sauvegarde est invalidée.
La sauvegarde doit inclure tous les fichiers du répertoire du
groupe de bases de données (/usr/local/pgsql/data, par exemple). Si des
tablespace
qui ne se trouvent pas dans
ce répertoire sont utilisés, il ne faut pas oublier de les inclure
(et s'assurer également que la sauvegarde archive les liens
symboliques comme des liens, sans quoi la restauration des
tablespace
sera problématique).
Néanmoins, les fichiers du sous-répertoire pg_xlog/, contenu dans le répertoire du cluster,
peuvent être omis. Cette petite complication permet de réduire le
risque d'erreurs lors de la restauration. C'est facile à réaliser
si pg_xlog/ est un lien symbolique vers
quelque endroit extérieur au répertoire du cluster, ce qui est
toutefois une configuration courante, pour des raisons de
performance.
La sauvegarde n'est utilisable que si les fichiers de segment WAL
engendrés pendant ou après cette sauvegarde sont préservés. Pour
faciliter cela, la fonction pg_stop_backup crée un fichier d'historique de la sauvegarde
immédiatement stocké dans la zone d'archivage des WAL. Ce fichier
est nommé d'après le nom du premier fichier segment WAL nécessaire
à l'utilisation de la sauvegarde. Ainsi, si le fichier WAL de
démarrage est 0000000100001234000055CD, le
nom du fichier d'historique ressemble à 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 en général être
ignoré). Une fois que la sauvegarde du système de fichiers et des
segments WAL utilisés pendant celle-ci (comme précisé dans le
fichier d'historique des sauvegardes) sont archivés de façon sûre,
tous les segments WAL archivés de noms numériquement plus petits ne
sont plus nécessaires à la récupération de la sauvegarde du système
de fichiers et peuvent être supprimés. Toutefois, il est préférable
de conserver plusieurs jeux de sauvegarde pour être absolument
certain de pouvoir récupérer les données.
Le fichier d'historique de la sauvegarde est un simple fichier
texte. Il contient le label passé à pg_start_backup, l'heure et les segments WAL de
début et de fin de la sauvegarde. Si le label est utilisé pour
identifier l'endroit où le fichier de sauvegarde associé est
conservé, alors le fichier d'historique archivé est suffisant pour
savoir quel fichier de sauvegarde restaurer, en cas de besoin.
Puisqu'il faut conserver tous les fichiers WAL archivés depuis la
dernière sauvegarde de base, l'intervalle entre les sauvegardes de
base est habituellement choisi en fonction de l'espace de stockage
qu'on accepte de consommer en fichiers d'archives WAL. Il faut
également considérer le temps à dépenser pour la récupération, si
celle-ci s'avère nécessaire -- le système doit rejouer tous les
segments WAL et ceci peut prendre beaucoup de temps si la dernière
sauvegarde de base est ancienne.
La fonction pg_start_backup crée un
fichier nommé backup_label dans le
répertoire du cluster de bases de données. Ce fichier est ensuite
supprimé par pg_stop_backup. Ce fichier
est bien sûr archivé comme faisant parti du fichier de sauvegarde.
Le fichier de label de la sauvegarde inclut la chaîne de label
passée à pg_start_backup, l'heure à
laquelle pg_start_backup a été exécuté et
le nom du fichier WAL initial. En cas de confusion, il est ainsi
possible de regarder dans le fichier sauvegarde et de déterminer
avec précision de quelle session de sauvegarde provient ce fichier.
Il est aussi possible de faire une sauvegarde alors que le serveur
est arrêté. Dans ce cas, pg_start_backup
et pg_stop_backup ne peuvent évidemment
pas être utilisés. L'utilisateur doit alors se débrouiller pour
identifier les fichiers de sauvegarde et déterminer jusqu'où
remonter avec les fichiers WAL associés. Il est généralement
préférable de suivre la procédure d'archivage en ligne décrite
ci-dessus.
23.3.3. Récupération d'une sauvegarde en ligne
Le pire est arrivé et il faut maintenant repartir d'une sauvegarde.
Voici la procédure :
-
Arrêter le serveur s'il est en cours d'exécution.
-
Si la place nécessaire est disponible, copier le répertoire
complet de données du cluster et tous les
tablespaces
dans un emplacement
temporaire en prévision d'un éventuel besoin ultérieur. Cette
précaution nécessite qu'un espace suffisant sur le système
soit disponible pour contenir deux copies de la base de
données existante. S'il n'y a pas assez de place disponible,
il faut au minimum copier le contenu du sous-répertoire
pg_xlog du répertoire des données
du cluster car il peut contenir des journaux qui n'ont pas
été archivés avant l'arrêt du serveur.
-
Effacer tous les fichiers et sous-répertoires existant sous
le répertoire des données du cluster et sous les répertoires
racines des
tablespaces
.
-
Restaurer les fichiers de la base de données à partir de la
sauvegarde. Il faut veiller à 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 des
tablespaces
sont utilisés, il
faut s'assurer que les liens symboliques dans pg_tblspc/ ont été correctement restaurés.
-
Supprimer tout fichier présent dans pg_xlog/ ; ils proviennent de la sauvegarde
et sont du coup probablement obsolètes. Si pg_xlog/ n'a pas été archivé, il suffit de
recréer ce répertoire ainsi que le sous-répertoire pg_xlog/archive_status/.
-
Si des fichiers de segment WAL non archivés ont été
sauvegardés dans l'étape 2, les copier dans pg_xlog/. Il est préférable de les copier
plutôt que de les déplacer afin qu'une version non modifiée
de ces fichiers soit toujours disponible si un problème
survient et qu'il faille recommencer.
-
Créer un fichier de commandes de récupération recovery.conf dans le répertoire des données
du cluster (voir Configuration
de la récupération). Il peut, de plus être judicieux de
modifier temporairement le fichier pg_hba.conf pour empêcher les utilisateurs
ordinaires de se connecter tant qu'il n'est pas certain que
la récupération a réussi.
-
Démarrer le serveur. Le serveur se trouve alors en mode
récupération et commence la lecture des fichiers WAL archivés
dont il a besoin. Si la récupération se termine sur une
erreur externe, le serveur peut tout simplement être relancé.
Il continue alors la récupération. À la fin du processus de
récupération, le serveur renomme recovery.conf en recovery.done (pour empêcher de retourner
accidentellement en mode de récupération en cas de nouvel
arrêt brutal ultérieur), puis passe en mode de fonctionnement
normal.
-
Inspecter le contenu de la base de données pour s'assurer que
la récupération a bien fonctionné. Dans le cas contraire,
retourner à l'étape 1. Si tout va bien, le fichier pg_hba.conf peut-être restauré pour autoriser
les utilisateurs à se reconnecter.
Le point clé de tout ceci est l'écriture d'un fichier de commandes
de récupération qui décrit comment et jusqu'où récupérer. Le
fichier recovery.conf.sample (normalement
présent dans le répertoire d'installation share/) peut être utilisé comme prototype. La seule
chose qu'il faut absolument préciser dans recovery.conf, c'est restore_command qui indique à PostgreSQL™ comment récupérer les
fichiers de segment WAL archivés. À l'instar d'archive_command, c'est une chaîne de commande shell.
Elle peut 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
nom du chemin est relatif au répertoire de travail du serveur,
c'est-à-dire le répertoire des données du cluster.) Pour écrire le
caractère % dans la commande, on utilise
%%. La commande la plus simple ressemble à
restore_command = 'cp /mnt/serveur/répertoire_archive/%f %p'
qui copie les segments WAL précédemment archivés à partir du
répertoire /mnt/serveur/répertoire_archive. Il est toujours
possible d'utiliser une commande plus compliquée, voire même un
script shell qui demande à l'utilisateur de monter la cassette
appropriée.
Il est important que la commande retourne un code de sortie
différent de zéro en cas d'échec. Des journaux absents de l'archive
seront
demandés à la
commande ; elle doit renvoyer autre chose que zéro dans ce cas. Ce
n'est pas une condition d'erreur. Il faut également garder à
l'esprit que le nom de base du chemin %p
diffère de %f ; il ne sont pas
interchangeables.
Les segments WAL qui ne se trouvent pas dans l'archive sont
recherchés dans pg_xlog/ ; cela autorise
l'utilisation de segments récents non archivés. Néanmoins, les
segments disponibles dans l'archive sont utilisés de préférence aux
fichiers contenus dans pg_xlog/. Le
système ne surcharge pas le contenu de pg_xlog/ lors de la récupération des fichiers
archivés.
Normalement, la récupération traite tous les segments WAL
disponibles, restaurant du coup la base de données à l'instant
présent (ou aussi proche que possible, en fonction des segments WAL
disponibles). Mais, pour récupérer à un instant particulier
(disons, juste avant que l'administrateur junior ait supprimé la
table principale de transactions), il suffit de spécifier le point
d'arrêt voulu dans recovery.conf. Ce
point d'arrêt, connu sous le nom de « cible de récupération » (ou
recovery
target
), peut être indiqué soit à l'aide d'une
date/heure, soit par l'ID de la dernière transaction. Au moment de
la rédaction de ce document, seule l'option date/heure est
réellement utilisable car il n'existe pas d'outils permettant
d'identifier précisément l'ID de transaction à utiliser.
Note
Le point d'arrêt doit être postérieur à la fin de la sauvegarde
de la base (le moment où pg_stop_backup a été exécuté). Une sauvegarde
ne peut pas être utilisée pour repartir d'un instant où elle
était encore en cours (pour ce faire, il faut récupérer la
sauvegarde précédente et rejouer à partir de là).
Si la récupération découvre une corruption des données WAL, elle se
termine à ce point et le serveur ne démarre pas. Dans un tel cas,
le processus de récupération peut alors être ré-exécuté à partir du
début en précisant une « cible de
récupération » avant le point de récupération pour
permettre à cette dernière de se terminer correctement. Si la
récupération échoue pour une raison externe (arrêt brutal du
système ou archive WAL devenue inaccessible), la récupération peut
être simplement relancée. Elle redémarre alors pratiquement là où
elle a échoué. Le redémarrage de la restauration fonctionne comme
les points de contrôle du déroulement normal : le serveur force une
écriture régulière de son état sur les disques et actualise alors
le fichier pg_control pour indiquer que
les données WAL déjà parcourues n'ont plus à être parcourus.
23.3.3.1. Configuration
de la récupération
Ces paramètres de configuration ne peuvent être placées que dans
le fichier recovery.conf et
s'appliquent uniquement pour la durée de la récupération. Ils
doivent être réinitialisés avant toute récupération ultérieure.
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. Tout %p est remplacé
par le chemin vers le répertoire de copie sur le serveur.
(Le nom du chemin est relatif au répertoire de travail du
serveur, c'est-à-dire le répertoire des données du
cluster.) %% est utilisé pour
écrire le caractère % dans la
commande.
Il est impératif que la commande ne renvoie un code de
sortie zéro que si, et seulement si, elle a réussi. Des
noms de fichiers absents de l'archive
seront demandés
; 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)
-
L'estampille temporelle au-delà de laquelle arrêter la
récupération. Seul un des deux paramètres recovery_target_time et recovery_target_xid
peut être précisé. Par défaut, la récupération court
jusqu'à la fin du journal WAL. Le point d'arrêt précis est
aussi influencé par recovery_target_inclusive.
-
recovery_target_xid (string)
-
L'ID de la transaction à laquelle arrêter la récupération.
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 sont récupérées sont celles
qui ont été validées avant celle indiquée (quelques fois en
l'incluant). Seul un des deux paramètres recovery_target_xid et recovery_target_time
peut être indiqué. Par défaut, la récupération court
jusqu'à la fin du journal WAL. Le point d'arrêt précis est
aussi influencé par recovery_target_inclusive.
-
recovery_target_inclusive (boolean)
-
Ce paramètre indique si la récupération doit s'arrêter
immédiatement après la cible de récupération précisée
(true) ou juste avant (false). Il s'applique à recovery_target_time
et recovery_target_xid,
en fonction de celui qui est indiqué pour cette
récupération. Il indique si les transactions possédant
l'instant cible exact de validation ou l'ID cible,
respectivement, sont incluses dans la récupération. La
valeur par défaut est true.
-
recovery_target_timeline (string)
-
La ligne temporelle (
timeline
) à utiliser pour la
récupération. Par défaut, la récupération s'effectue en
utilisant la ligne temporelle en cours au moment de la
sauvegarde. Ce paramètre ne doit être configuré que dans
pour les situations de récupération complexes, dans
lesquelles il est nécessaire de retourner à un état
postérieur à une récupération d'instantané. Voir la
Section 23.3.4,
« Lignes temporelles (
Timelines
) » pour plus
d'informations.
23.3.4. Lignes temporelles (Timelines)
La possibilité de restaurer la base de données à partir d'un
instantané crée une complexité digne des histoires de
science-fiction traitant du voyage dans le temps et des univers
parallèles. Dans l'historique original de la base de données, une
table critique a peut-être été supprimée à 17h15 mardi soir. Sans
stress, la sauvegarde est récupérée et restaurée jusqu'à 17h14
mardi soir. Tout est de nouveau fonctionnel. Dans
cette
histoire de l'univers de la base
de données, la table n'a jamais été supprimée. Or, l'utilisateur
réalise peu après que ce n'était pas une si grande idée et veut
revenir à un point ultérieur de l'historique. Cela n'est pas
possible, si, alors que la base de données est de nouveau
fonctionnelle, elle réutilise certaines séquences de fichiers WAL
qui permettent de retourner à ce point. Il est donc nécessaire de
pouvoir distinguer les séries d'enregistrements WAL engendrées
après la récupération de l'instantané de celles issues de
l'historique originel de la base.
Pour gérer ces difficultés, PostgreSQL™ inclut la notion de
lignes temporelles (ou
timelines
).
Chaque fois qu'une restauration d'un instantané antérieur à la fin
de la séquence WAL est exécutée, une nouvelle timeline est créée
pour identifier les séries d'enregistrements WAL consécutives à la
récupération (toutefois, si la récupération s'effectue sur la
totalité des WAL, il n'y a pas de nouvelle timeline : celle
existant est étendue). Le numéro d'identifiant de la timeline est
inclus dans le nom des fichiers de segment WAL. De ce fait, une
nouvelle timeline ne réécrit pas sur les données engendré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, cela peut parfois sauver des vies. Dans une
situation où l'instantané à récupérer n'est pas connu avec
certitude, il va falloir tester les récupérations de différents
instantanés jusqu'à trouver le meilleur. Sans les timelines, ce
processus engendre vite un bazar ingérable. Avec les timelines, il
est possible de récupérer
n'importe
quel
état précédent, même les états de branches
temporelles abandonnées.
Chaque fois qu'une nouvelle timeline est créée, PostgreSQL™ crée un fichier
d'« historique des timelines »
qui indique à quelle timeline il est attaché, et depuis quand. Ces
fichiers d'historique sont nécessaires pour permettre au système de
choisir les bons fichiers de segment WAL lors de la récupération à
partir d'une archive qui contient plusieurs timelines. Ils sont
donc archivés comme tout fichier de segment WAL. Puisque ce sont de
simples fichiers texte, il est peu coûteux et même judicieux de les
conserver indéfiniment (contrairement aux fichiers de segment,
volumineux). Il est possible d'ajouter des commentaires au fichier
d'historique expliquant comment et pourquoi cette timeline a été
créée. De tels commentaires s'avèrent précieux lorsque
l'expérimentation conduit à de nombreuses timelines.
Par défaut, la récupération s'effectue sur la timeline en vigueur
au cours de la la sauvegarde. Si l'on souhaite effectuer la
récupération dans une timeline fille (c'est-à-dire retourner à un
état enregistré après une tentative de récupération), il faut
préciser l'identifiant de la timeline dans recovery.conf. Il n'est pas possible de récupérer
dans des timelines antérieures à la sauvegarde.
Au moment où ces lignes sont écrites, plusieurs limitations de la
technique d'achivage continu sont connues. Elles seront
probablement corrigées dans une prochaine version :
-
Les opérations sur les index de hachage ne sont pas tracées
dans les WAL. Ces index ne sont donc pas actualisés lorsque
la sauvegarde est rejouée. Pour cela, il est recommandé
d'utiliser la commande REINDEX sur chacun des
index à la fin de la récupération.
-
Si une commande CREATE
DATABASE est exécutée alors qu'une sauvegarde est en
cours, et que la base de données modèle utilisée par
l'instruction
CREATE
DATABASE
est à son tour modifiée pendant la
sauvegarde, il est possible que la récupération propage ces
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èle lors d'une sauvegarde de base.
-
Les commandes CREATE
TABLESPACE sont tracées dans les WAL avec le chemin
absolu et sont donc rejouées en tant que créations de
tablespace
suivant le même chemin
absolu. Ceci peut être indésirable si la trace est rejouée
sur une autre machine. Cela peut s'avérer dangereux même
lorsque le journal est rejoué sur la même machine, mais dans
un répertoire différent : la ré-exécution surcharge toujours
le contenu du
tablespace
original. Pour éviter
de tels problèmes, la meilleure solution consiste à effectuer
une nouvelle sauvegarde de la base après la création ou la
suppression de
tablespace
.
Il faut de plus garder à l'esprit 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. Il peut en effet être nécessaire de corriger des
pages disque partiellement écrites. En fonction du matériel et des
logiciels composant le système, le risque d'écriture partielle peut
être suffisamment faible pour être ignoré, auquel cas le volume
total des traces archivées peut être considérablement réduit par la
désactivation des images de page à l'aide du paramètre full_page_writes
(lire les notes et avertissements dans Chapitre 27,
Fiabilité et WAL avant de le faire). Désactiver les images de
page n'empêche pas l'utilisation des traces pour les opérations
PITR. Un piste éventuelle de développements futurs consiste à
compresser les données des WAL archivés en supprimant les copies
inutiles de pages même si full_page_writes
est actif. Entre temps, les administrateurs peuvent souhaiter
réduire le nombre d'images de pages inclus dans WAL en augmentant
autant que possible les paramètres d'intervalle entre les points de
vérification.