<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Sauvegarde on Carnet de découvertes</title><link>https://fljd.in/tags/sauvegarde/</link><description>Recent content in Sauvegarde on Carnet de découvertes</description><generator>Hugo -- gohugo.io</generator><language>fr</language><managingEditor>Florent Jardin</managingEditor><lastBuildDate>Wed, 08 Oct 2025 16:00:00 +0200</lastBuildDate><atom:link href="https://fljd.in/tags/sauvegarde/index.xml" rel="self" type="application/rss+xml"/><item><title>Sauvegardes personnelles avec Restic</title><link>https://fljd.in/2025/10/08/sauvegardes-personnelles-avec-restic/</link><pubDate>Wed, 08 Oct 2025 16:00:00 +0200</pubDate><author>Florent Jardin</author><guid>https://fljd.in/2025/10/08/sauvegardes-personnelles-avec-restic/</guid><description>&lt;p&gt;Ces derniers temps, j’ai mis fin à une histoire d’amour avec Debian qui aura
duré près de trois ans. Pas que je n’aime plus le système, oh non, je le préfère
toujours à sa cousine Ubuntu. Mais voilà, j’ai un attachement particulier à
Archlinux depuis, wouh, au moins les bancs de l’école d’ingénieur où nous
l’installions sur des machines virtuelles et où nous nous adonnions à la
pratique du &lt;a href="https://github.com/fosslife/awesome-ricing" target="_blank" rel="noopener"&gt;linux ricing&lt;/a&gt; pour passer le temps.&lt;/p&gt;
&lt;p&gt;Après une expérimentation de &lt;a href="https://manjaro.org/" target="_blank" rel="noopener"&gt;Manjaro i3&lt;/a&gt; entre 2019 et 2022 sur mon poste
professionnel, je me suis convaincu qu’il me fallait retourner à l’essentiel. Au
début du mois de septembre, j’ai réussi le portage de ma &lt;a href="https://gitlab.com/fljdin/dotfiles/-/tree/main/sway" target="_blank" rel="noopener"&gt;config Sway&lt;/a&gt; de
Debian Trixie vers Archlinux. L’occasion parfaite pour requestionner mes
pratiques en matière de sauvegarde de poste et de remplacer &lt;a href="https://fljd.in/2021/08/24/borg-ou-la-sauvegarde-facile/"&gt;BorgBackup&lt;/a&gt; par
Restic.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="prise-en-main-éclair"&gt;Prise en main éclair&lt;/h2&gt;
&lt;p&gt;J’ai lu plusieurs articles et avis au sujet de Restic. Je l’avais vite identifié
comme un outil équivalent à BorgBackup, mais je ne m’étais pas pressé de le
tester. Quelle erreur ! J’ai été déconcerté par la facilité d’utilisation, par
son interface en ligne de commande claire et complète, et par sa
&lt;a href="https://restic.readthedocs.io/en/stable/010_introduction.html" target="_blank" rel="noopener"&gt;documentation&lt;/a&gt; de qualité.&lt;/p&gt;
&lt;p&gt;Pour avoir régulièrement vécu des dégâts sur des clés de mauvaise qualité avec
ma pratique exotique sur BorgBackup, je m’étais penché sur la possibilité de
sauvegarder vers un dossier distant avec SSH. J’ai du insisté deux bonnes heures
à l’époque sans parvenir à quoique ce soit avec Borg.&lt;/p&gt;
&lt;p&gt;Avec Restic, ce n’est pas moins de 13 types différents de dépôts supportés, dont
le &lt;a href="https://restic.readthedocs.io/en/stable/030_preparing_a_new_repo.html#sftp" target="_blank" rel="noopener"&gt;SFTP&lt;/a&gt;. Il ne m’en fallait pas plus pour tourner le dos à son homologue. La
mise en place d’un dépôt est simplifiée à l’extrême :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fish" data-lang="fish"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="na"&gt;-x&lt;/span&gt; &lt;span class="nv"&gt;RESTIC_REPOSITORY&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;sftp:&amp;lt;server&amp;gt;:&amp;lt;directory&amp;gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;restic&lt;/span&gt; init
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;restic&lt;/span&gt; backup ~ &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;--dry-run&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="na"&gt;--exclude-file&lt;/span&gt; ~/.config/restic/excludes.txt
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Je ne suis pas en reste avec une gestion poussée des stratégies de rétention des
instantanés. Pour l’exemple, je maintiens une sauvegarde par semaine, pendant
trois mois.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fish" data-lang="fish"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;restic&lt;/span&gt; forget &lt;span class="na"&gt;--prune&lt;/span&gt; &lt;span class="na"&gt;--keep-within-weekly&lt;/span&gt; 3m
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La technique d’exploration d’un instantané est identique à Borg, avec un montage
&lt;a href="https://www.kernel.org/doc/html/latest/filesystems/fuse.html" target="_blank" rel="noopener"&gt;FUSE&lt;/a&gt; sous Linux. Une fois encore, la &lt;a href="https://restic.readthedocs.io/en/stable/050_restore.html#restore-using-mount" target="_blank" rel="noopener"&gt;documentation&lt;/a&gt; est limpide à ce
sujet.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fish" data-lang="fish"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;sudo&lt;/span&gt; &lt;span class="nf"&gt;install&lt;/span&gt; &lt;span class="na"&gt;-o&lt;/span&gt; &lt;span class="nv"&gt;$USER&lt;/span&gt; &lt;span class="na"&gt;-g&lt;/span&gt; &lt;span class="nv"&gt;$USER&lt;/span&gt; &lt;span class="na"&gt;-d&lt;/span&gt; /mnt/restic
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;restic&lt;/span&gt; mount /mnt/restic
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="planification-avec-systemd"&gt;Planification avec systemd&lt;/h2&gt;
&lt;p&gt;Je me suis prêté au même jeu qu’avec BorgBackup sur ma précédente installation
Debian. En lieu et place de &lt;code&gt;cron&lt;/code&gt;, je planifie mes sauvegardes avec un &lt;em&gt;timer&lt;/em&gt;
utilisateur pour déclencher une tâche deux fois par jour sur mes journées de
travail.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# ~/.config/systemd/user/restic.timer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;Daily&lt;/span&gt; &lt;span class="nx"&gt;Restic&lt;/span&gt; &lt;span class="nx"&gt;backup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;Documentation&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;man&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="nx"&gt;restic&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;OnCalendar&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;Mon&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="nx"&gt;Fri&lt;/span&gt; &lt;span class="mi"&gt;09&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;OnCalendar&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;Mon&lt;/span&gt;&lt;span class="p"&gt;..&lt;/span&gt;&lt;span class="nx"&gt;Fri&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;Persistent&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Install&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;WantedBy&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;timers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La tâche consiste à appeler &lt;code&gt;restic&lt;/code&gt; avec mon fichier d’exclusion, suivi d’une
purge des vieux instantanés présents sur le dépôt.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-toml" data-lang="toml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c"&gt;# ~/.config/systemd/user/restic.service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Unit&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;Restic&lt;/span&gt; &lt;span class="nx"&gt;backup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;Service&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;oneshot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;ExecStart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;restic&lt;/span&gt; &lt;span class="nx"&gt;backup&lt;/span&gt; &lt;span class="err"&gt;%&lt;/span&gt;&lt;span class="nx"&gt;h&lt;/span&gt; &lt;span class="nx"&gt;--exclude-file&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nx"&gt;RESTIC_EXCLUDE_FILE&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nx"&gt;ExecStartPost&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="nx"&gt;restic&lt;/span&gt; &lt;span class="nx"&gt;forget&lt;/span&gt; &lt;span class="nx"&gt;--prune&lt;/span&gt; &lt;span class="nx"&gt;--keep-within-weekly&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pour la configuration, je déclare les variables dans un fichier d’environnement
pour que &lt;code&gt;restic&lt;/code&gt; sache identifier et déchiffrer correctement les instantanés.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ~/.config/environment.d/restic.conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;RESTIC_REPOSITORY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;sftp:&amp;lt;server&amp;gt;:&amp;lt;directory&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;RESTIC_PASSWORD_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$HOME/.config/restic/pass&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;RESTIC_EXCLUDE_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;$HOME/.config/restic/excludes.txt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pour armer la planification, il suffit de recharger &lt;code&gt;systemd&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fish" data-lang="fish"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;systemctl&lt;/span&gt; &lt;span class="na"&gt;--user&lt;/span&gt; daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;En exportant les bonnes variables dans votre shell, la consultation des
instantanés se fait sobrement avec la commande suivante.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fish" data-lang="fish"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;restic&lt;/span&gt; snapshots
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-console" data-lang="console"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;repository 3db74709 opened (version 2, compression level auto)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;ID Time Host Tags Paths Size
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;-----------------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;f7bb4fea 2025-09-16 11:50:18 florent-dalibo /home/florent 4.309 GiB
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;5a4dbf59 2025-09-19 09:30:01 florent-dalibo /home/florent 5.639 GiB
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;1012f0ab 2025-09-27 19:28:38 florent-dalibo /home/florent 5.871 GiB
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;629c2687 2025-10-03 09:30:00 florent-dalibo /home/florent 6.006 GiB
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;98b32adb 2025-10-08 10:00:08 florent-dalibo /home/florent 4.677 GiB
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;-----------------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="go"&gt;5 snapshots
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Restic est un bon outil. Tellement bon, que la communauté Gnome l’utilise à
présent comme &lt;em&gt;backend&lt;/em&gt; pour l’interface Déjà Dup dans leur dernière version
49.0 sortie le &lt;a href="https://discourse.gnome.org/t/deja-dup-49-0-released/31441" target="_blank" rel="noopener"&gt;mois dernier&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pour ma part, tout se déroule bien depuis presque un mois. Il ne manque plus
qu’à sécuriser le serveur distant qui fait office de dépôt avec ses propres
sauvegardes ! Pour ce faire, j’envisage de mettre en place Restic sur la plupart
des répertoires d’importances de mon serveur multimédia, en gardant bien en
mémoire le principe 3-2-1 de la sauvegarde réussie.&lt;/p&gt;
&lt;p&gt;Prenez soin de vos sauvegardes.&lt;/p&gt;</description></item><item><title>BorgBackup ou la sauvegarde facile</title><link>https://fljd.in/2021/08/24/borg-ou-la-sauvegarde-facile/</link><pubDate>Tue, 24 Aug 2021 00:00:00 +0000</pubDate><author>Florent Jardin</author><guid>https://fljd.in/2021/08/24/borg-ou-la-sauvegarde-facile/</guid><description>&lt;p&gt;Jusqu&amp;rsquo;à très récemment, je ne me préoccupais pas de la pertinence de mes
sauvegardes de fichiers personnels réalisées naïvement avec un script &lt;code&gt;rsync&lt;/code&gt;.
C&amp;rsquo;est honteux dans nos métiers, mais l&amp;rsquo;adage du cordonnier s&amp;rsquo;est vérifié avec
moi lors de l&amp;rsquo;exécution d&amp;rsquo;un vulgaire &lt;code&gt;find $NOVAR/ -delete&lt;/code&gt; durant des tests.&lt;/p&gt;
&lt;p&gt;Après cet épisode et l&amp;rsquo;amertume d&amp;rsquo;avoir perdu quelques travaux, ou la surprise
de découvrir les ravages de leur disparition plusieurs semaines après ma fatale
erreur, je me suis tourné vers l&amp;rsquo;outil incontournable dont tous mes collègues me
parlaient : &lt;a href="https://borgbackup.readthedocs.io/en/stable/" target="_blank" rel="noopener"&gt;BorgBackup&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="des-atouts-séduisants"&gt;Des atouts séduisants&lt;/h2&gt;
&lt;p&gt;Cela fait à présent deux années que je travaille au quotidien sur Linux pour mon
activité professionnelle. Étant responsable de mon matériel et des données que
je manipule, il n&amp;rsquo;existe pas de politique particulière pour les sauvegardes
régulières ni le stockage de celles-ci.&lt;/p&gt;
&lt;p&gt;Mon précédent script était passablement trivial, à savoir :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sauvegarder une copie unique des documents courants ;&lt;/li&gt;
&lt;li&gt;Sauvegarder une liste des fichiers de configuration, appelés &lt;em&gt;dotfiles&lt;/em&gt; ;&lt;/li&gt;
&lt;li&gt;Exclure les projets contenant un répertoire &lt;code&gt;.git&lt;/code&gt; ;&lt;/li&gt;
&lt;li&gt;Exclure les fichiers de plus de 200 Mo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Le tout sur une clé USB de 8 Go, chiffrée avec le système &lt;a href="https://fr.wikipedia.org/wiki/LUKS" target="_blank" rel="noopener"&gt;LUKS&lt;/a&gt; pour se
prévenir de la perte ou du vol dans un espace public dudit support.&lt;/p&gt;
&lt;p&gt;Borg (son petit nom), permet de répondre correctement à l&amp;rsquo;ensemble de ces
points, et le fait à merveille. En bénéficiant de la déduplication et de la
compression, j&amp;rsquo;ai pu conserver ma clé USB et m&amp;rsquo;engager dans la rédaction d&amp;rsquo;un
&lt;a href="https://gist.github.com/fljdin/de46c7c8d18cc37e591cb8364ecf8eef" target="_blank" rel="noopener"&gt;nouveau script&lt;/a&gt; plus complet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Exclusion de fichiers et de répertoires&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Certains fichiers ou répertoires cachés vivent leur vie sur nos postes, et un
fichier d&amp;rsquo;exclusion peut être transmis à Borg pour ne pas les inclure dans la
routine de sauvegarde. Le mien est relativement léger pour le moment, et
pourrait s&amp;rsquo;enrichir avec l&amp;rsquo;expérience.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# ~/.config/borg/exclude.list&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/home/**/.git
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/home/**/.vagrant
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/home/*/.local
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/home/*/.cache
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/home/*/.mozilla
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/home/*/.thunderbird
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/home/*/.config/chromium
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/home/*/.config/discord
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/home/*/.npm
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;/home/*/.cpan
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;Déduplication et rétention d&amp;rsquo;une semaine&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Le gain remarquable entre mon script et la nouvelle solution que m&amp;rsquo;offre Borg
réside dans son algorithme de déduplication, où la version d&amp;rsquo;un fichier n&amp;rsquo;est
stockée qu&amp;rsquo;une seule fois jusqu&amp;rsquo;à une éventuelle modification, permettant de ne
conserver qu&amp;rsquo;une copie de mes documents sur une bien plus longue période avec
un coût de stockage ridiculement faible.&lt;/p&gt;
&lt;p&gt;À chaque exécution, je demande le rapport de sauvegarde avec l&amp;rsquo;option &lt;code&gt;--stats&lt;/code&gt;
dont voici un exemplaire sur l&amp;rsquo;exécution de ce matin.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;------------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Archive name: florent-2021-08-24T08:42:05
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Archive fingerprint: be38707dd52f5a86f8e75fe3ad4997aae58b3016366a988b7cb37ce3b
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Time &lt;span class="o"&gt;(&lt;/span&gt;start&lt;span class="o"&gt;)&lt;/span&gt;: Tue, 2021-08-24 08:42:06
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Time &lt;span class="o"&gt;(&lt;/span&gt;end&lt;span class="o"&gt;)&lt;/span&gt;: Tue, 2021-08-24 08:42:06
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Duration: 0.96 seconds
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Number of files: &lt;span class="m"&gt;3720&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Utilization of max. archive size: 0%
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;------------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Original size Compressed size Deduplicated size
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;This archive: 2.11 GB 1.78 GB 480.51 kB
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;All archives: 12.63 GB 10.67 GB 1.75 GB
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Unique chunks Total chunks
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Chunk index: &lt;span class="m"&gt;3974&lt;/span&gt; &lt;span class="m"&gt;25888&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;------------------------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Pour une semaine de rétention, l&amp;rsquo;espace total consommé sur le montage USB
n&amp;rsquo;excède pas (encore) les 1,75 Go alors que les images décompressées pèsent au
total 12,63 Go que ne parvennait pas à stocker mon ancien script sur plusieurs
jours.&lt;/p&gt;
&lt;p&gt;Au passage, la durée d&amp;rsquo;exécution est significativement réduite chaque jour grâce
à ce mécanisme, qui ne sélectionne que les nouveautés d&amp;rsquo;une exécution à l&amp;rsquo;autre.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Un montage virtuel pour naviguer dans le temps&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;outil propose deux options pour la restauration :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;extract&lt;/code&gt; pour restaurer le contenu d&amp;rsquo;une archive dans le répertoire courant
(&lt;a href="https://borgbackup.readthedocs.io/en/stable/usage/extract.html" target="_blank" rel="noopener"&gt;doc&lt;/a&gt;) ;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mount&lt;/code&gt; pour visualiser les fichiers ou dossiers à restaurer, voire les
déplacer manuellement dans le répertoire cible avec un outil graphique
(&lt;a href="https://borgbackup.readthedocs.io/en/stable/usage/mount.html" target="_blank" rel="noopener"&gt;doc&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cette seconde proposition est particulièrement utile pour naviguer d&amp;rsquo;une archive
à une autre, à la recherche d&amp;rsquo;un fichier perdu dans le temps. Le montage
s&amp;rsquo;effectue à l&amp;rsquo;aide du système de fichiers &lt;a href="https://www.kernel.org/doc/html/latest/filesystems/fuse.html" target="_blank" rel="noopener"&gt;FUSE&lt;/a&gt; qui ne nécessite aucun
droit administrateur.&lt;/p&gt;
&lt;p&gt;Pour être utilisé à partir de Borg, le paquet &lt;code&gt;python-llfuse&lt;/code&gt; sera requis selon
votre distribution.&lt;/p&gt;
&lt;h2 id="planification-avec-systemd"&gt;Planification avec systemd&lt;/h2&gt;
&lt;p&gt;Ce fut une découverte lors de mes lectures émerveillées de la &lt;a href="https://gist.github.com/fljdin/de46c7c8d18cc37e591cb8364ecf8eef" target="_blank" rel="noopener"&gt;documentation&lt;/a&gt;
et des &lt;a href="https://wiki.archlinux.org/title/Borg_backup_%28Fran%C3%A7ais%29" target="_blank" rel="noopener"&gt;ressources&lt;/a&gt; de la communauté française d&amp;rsquo;Archlinux. N&amp;rsquo;étant pas
particulièrement fan de &lt;code&gt;cron&lt;/code&gt; pour un usage personnel, j&amp;rsquo;ai suivi à la lettre
la configuration d&amp;rsquo;un service utilisateur et du &lt;em&gt;timer&lt;/em&gt; associé pour garantir le
lancement de la sauvegarde chaque jour, 30 minutes après le démarrage de mon
système.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# .config/systemd/user/borg.service&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Borg backup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;oneshot&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;%h/.bin/borg-create.sh&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# .config/systemd/user/borg.timer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Daily Borg backup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;Documentation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;man:borg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Timer]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;OnBootSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;30min&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;OnUnitActiveSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;1d&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[Install]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;timers.target&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Une fois le service activé, je n&amp;rsquo;ai qu&amp;rsquo;à attendre chaque matin la notification
de fin de sauvegarde pour consulter les rapports avec la commande &lt;code&gt;journalctl&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;journalctl --user -xeu borg.service
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;août &lt;span class="m"&gt;24&lt;/span&gt; 08:42:02 florent systemd&lt;span class="o"&gt;[&lt;/span&gt;877&lt;span class="o"&gt;]&lt;/span&gt;: Starting Borg backup...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;août &lt;span class="m"&gt;24&lt;/span&gt; 08:42:27 florent systemd&lt;span class="o"&gt;[&lt;/span&gt;877&lt;span class="o"&gt;]&lt;/span&gt;: Finished Borg backup.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;août &lt;span class="m"&gt;24&lt;/span&gt; 08:42:27 florent systemd&lt;span class="o"&gt;[&lt;/span&gt;877&lt;span class="o"&gt;]&lt;/span&gt;: borg.service: Consumed 1.535s CPU time.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="conclusion"&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;De trop nombreux utilisateurs (Windows notamment) comptent sur leur miraculeuse
corbeille, jusqu&amp;rsquo;à ce qu&amp;rsquo;une véritable suppression ne survienne ou qu&amp;rsquo;un disque
défaillant fasse des siennes. Pour s&amp;rsquo;assurer qu&amp;rsquo;une donnée ne disparaisse pas
définitivement, la sauvegarde doit être correctement mise en place, idéalement
sur plusieurs périodes et sur plusieurs supports.&lt;/p&gt;
&lt;p&gt;Le conseil vaut aussi bien pour les bases de données que pour les fichiers
personnels : une sauvegarde n&amp;rsquo;est fiable que si la restauration de son
contenu est possible. Une corruption de l&amp;rsquo;archive, une erreur dans l&amp;rsquo;exécution
du script ou une mise à jour majeure de l&amp;rsquo;outil de sauvegarde sont autant de
situations qui peuvent rendre vos sauvegardes irrécupérables.&lt;/p&gt;
&lt;p&gt;Prenez soin de vos sauvegardes.&lt;/p&gt;</description></item><item><title>La brêve histoire du fichier backup_label</title><link>https://fljd.in/2021/01/19/la-breve-histoire-du-fichier-backup_label/</link><pubDate>Tue, 19 Jan 2021 00:00:00 +0000</pubDate><author>Florent Jardin</author><guid>https://fljd.in/2021/01/19/la-breve-histoire-du-fichier-backup_label/</guid><description>&lt;p&gt;Je suis resté longtemps ignorant des mécanismes de &lt;a href="https://public.dalibo.com/archives/publications/glmf108_postgresql_et_ses_journaux_de_transactions.pdf" target="_blank" rel="noopener"&gt;journalisation&lt;/a&gt; et de &lt;em&gt;PITR&lt;/em&gt;
avec PostgreSQL alors même qu&amp;rsquo;il s&amp;rsquo;agit d&amp;rsquo;un des fonctionnements critiques pour
la durabilité des données d&amp;rsquo;une instance. Mieux comprendre ces concepts m&amp;rsquo;aurait
permis à une époque, d&amp;rsquo;être plus serein lors de la mise en place de sauvegardes
et surtout au moment de leur restauration !&lt;/p&gt;
&lt;p&gt;Dans cet article, je vous propose de revenir sur un fichier anecdotique qui a
fait parlé de lui pendant plusieurs années : le fichier &lt;code&gt;backup_label&lt;/code&gt;.
Qui est-il et à quoi sert-il ? Comment a-t-il évolué depuis sa création en
version 8.0 de PostgreSQL et qu&amp;rsquo;adviendra-t-il de lui dans les prochaines années ?&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="il-était-une-fois-la-journalisation"&gt;Il était une fois la journalisation&lt;/h2&gt;
&lt;p&gt;En guise d&amp;rsquo;introduction pour mieux comprendre cet article, il est bon d&amp;rsquo;expliquer
que chaque opération d&amp;rsquo;écriture dans PostgreSQL comme un &lt;code&gt;UPDATE&lt;/code&gt; ou un &lt;code&gt;INSERT&lt;/code&gt;,
est écrite une première fois au moment du &lt;code&gt;COMMIT&lt;/code&gt; de la transaction dans un groupe
de fichiers, que l&amp;rsquo;on appelle &lt;em&gt;WAL&lt;/em&gt; ou &lt;strong&gt;journaux de transactions&lt;/strong&gt;. Ajoutées les
unes à la suite des autres, ces modifications représentent un faible coût pour
l&amp;rsquo;activité des disques par rapport aux écritures aléatoires d&amp;rsquo;autres processus
de synchronisation à l&amp;rsquo;œuvre dans PostgreSQL.&lt;/p&gt;
&lt;p&gt;Parmi l&amp;rsquo;un d&amp;rsquo;eux, le processus &lt;code&gt;checkpointer&lt;/code&gt; s&amp;rsquo;assure que les nouvelles données
en mémoire soient définitivement synchronisées dans les fichiers de données à des
moments réguliers que l&amp;rsquo;on appelle &lt;code&gt;CHECKPOINT&lt;/code&gt;. Cette écriture en deux temps sur
les disques apporte d&amp;rsquo;excellentes performances et garantit qu&amp;rsquo;aucun bloc modifié
ne soit perdu lorsqu&amp;rsquo;une transaction se termine correctement.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://fljd.in/img/fr/2021-01-19-ecriture-differee-sur-disque.png" alt="Écriture différée sur les disques"&gt;&lt;/p&gt;
&lt;p&gt;Par ce mécanisme de journalisation, les fichiers de données de notre instance
sont constamment en retard sur la véritable activité transactionnelle, et ce,
jusqu&amp;rsquo;au prochain &lt;code&gt;CHECKPOINT&lt;/code&gt;. En cas d&amp;rsquo;arrêt brutal du système, les blocs en
attente de synchronisation (&lt;em&gt;dirty pages&lt;/em&gt;) présents dans la mémoire &lt;em&gt;Shared Buffer&lt;/em&gt;
sont perdus et les fichiers de données sont dit &lt;strong&gt;incohérents&lt;/strong&gt; car ils mixent
des données de transactions anciennes, nouvelles, valides ou invalides.&lt;/p&gt;
&lt;p&gt;Dans pareilles situations, il est possible de redémarrer l&amp;rsquo;instance afin qu&amp;rsquo;elle
&lt;em&gt;rejoue&lt;/em&gt; les modifications dans l&amp;rsquo;ordre des transactions telles qu&amp;rsquo;elles avaient
été écrites dans les &lt;em&gt;WAL&lt;/em&gt;. Cette reconstruction des fichiers de données pour
retrouver leur état consistant est sobrement appelée la &lt;strong&gt;récupération des données&lt;/strong&gt;
ou &lt;em&gt;crash recovery&lt;/em&gt;.&lt;/p&gt;
&lt;div class="message"&gt;En version 8.0 et supérieures, ce mécanisme a permis l&amp;rsquo;émergence des solutions
de restauration dans le temps (&lt;em&gt;Point In Time Recovery&lt;/em&gt;) et de réplication par
récupération des journaux (&lt;em&gt;Log Shipping&lt;/em&gt;) sur une instance secondaire.&lt;/div&gt;
&lt;p&gt;Que ce soit à la suite d&amp;rsquo;un crash ou dans le cadre d&amp;rsquo;une restauration de
sauvegarde, les fichiers de données doivent être cohérents pour assurer le retour
du service et l&amp;rsquo;accès en écriture aux données. Quelle mauvaise surprise n&amp;rsquo;a-t-on
pas lorsqu&amp;rsquo;une instance PostgreSQL interrompt son démarrage avec le message
suivant :&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PANIC: could not locate a valid checkpoint record&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Il indique que l&amp;rsquo;instance a détecté une inconsistance dans les fichiers au moment
de son démarrage et qu&amp;rsquo;elle échoue à trouver le &lt;em&gt;point de reprise&lt;/em&gt; le plus proche
de son état. Sans les journaux, la récupération échoue et s&amp;rsquo;arrête. À cet instant
précis, vos nerfs et votre politique de sauvegarde sont mis à rude épreuve.&lt;/p&gt;
&lt;p&gt;Pour le dire encore autrement : en l&amp;rsquo;absence des journaux de transactions ou de
leurs archives, &lt;u&gt;vos plus récentes données sont perdues&lt;/u&gt;.&lt;/p&gt;
&lt;p&gt;… Et l&amp;rsquo;outil &lt;a href="https://pgpedia.info/p/pg_resetwal.html" target="_blank" rel="noopener"&gt;pg_resetwal&lt;/a&gt; ne les récuperera pas pour vous.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="entre-en-scène-le-backup_label"&gt;Entre en scène le backup_label&lt;/h2&gt;
&lt;p&gt;Après ce charmant avertissement, on considèrera que l&amp;rsquo;archivage des journaux
de transactions n&amp;rsquo;est plus une option dans vos plans de sauvegarde. Assurez-vous
que ces archives soient stockées sur un espace sécurisé, voire une zone
décentralisée pour qu&amp;rsquo;elles soient accessibles par toutes les instances secondaires
lorsque vous devez déclencher votre &lt;a href="https://fljd.in/2019/12/19/le-jour-ou-tout-bascule"&gt;plan de bascule&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pour ceux ayant atteint cette partie de l&amp;rsquo;article, vous ne devriez pas être
trop perdus si je vous annonce que le fichier &lt;code&gt;backup_label&lt;/code&gt; est un composant
d&amp;rsquo;un plus large concept, à savoir : la sauvegarde.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Le fichier historique de sauvegarde est un simple fichier texte. Il contient
le label que vous avez attribué à l&amp;rsquo;opération &lt;code&gt;pg_basebackup&lt;/code&gt;, ainsi que les
dates de début, de fin et la liste des segments WAL de la sauvegarde. Si vous
avez utilisé le label pour identifier le fichier de sauvegarde associé, alors
le fichier historique vous permet de savoir quel fichier de sauvegarde vous
devez utiliser pour la restauration.&lt;/p&gt;
&lt;p&gt;Source : &lt;a href="https://docs.postgresql.fr/13/continuous-archiving.html#BACKUP-BASE-BACKUP" target="_blank" rel="noopener"&gt;Réaliser une sauvegarde de base&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Prenons une instance classique en cours d&amp;rsquo;exécution et réalisons une sauvegarde
avec l&amp;rsquo;outil &lt;a href="https://www.postgresql.org/docs/13/app-pgbasebackup.html" target="_blank" rel="noopener"&gt;pg_basebackup&lt;/a&gt; que nous vante la documentation. Observons son
comportement le plus simple avec la génération d&amp;rsquo;une archive au format &lt;code&gt;tar&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ pg_basebackup --label=demo --pgdata=backups --format=tar \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --checkpoint=fast --verbose
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pg_basebackup: initiating base backup, waiting for checkpoint to complete
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pg_basebackup: checkpoint completed
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pg_basebackup: write-ahead log start point: 0/16000028 on timeline 1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pg_basebackup: starting background WAL receiver
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pg_basebackup: created temporary replication slot &amp;#34;pg_basebackup_15594&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pg_basebackup: write-ahead log end point: 0/16000100
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pg_basebackup: waiting for background process to finish streaming ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pg_basebackup: syncing data to disk ...
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pg_basebackup: renaming backup_manifest.tmp to backup_manifest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pg_basebackup: base backup completed
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Depuis la version 10, l&amp;rsquo;option &lt;code&gt;--wal-method&lt;/code&gt; est définie
sur &lt;code&gt;stream&lt;/code&gt; par défaut, ce qui indique que tous les journaux de transactions
présents et à venir dans le sous-répertoire &lt;code&gt;pg_wal&lt;/code&gt; de l&amp;rsquo;instance seront
également sauvegardés dans une archive dédiée, notamment grâce à la création
d&amp;rsquo;un slot de réplication temporaire.&lt;/p&gt;
&lt;p&gt;Depuis la version 13, l&amp;rsquo;outil embarque le fichier manifeste dans la sauvegarde
afin de pouvoir contrôler l&amp;rsquo;intégrité de la copie par la commande
&lt;a href="https://fljd.in/2020/11/18/quelques-outils-meconnus/#pg_verifybackup"&gt;pg_verifybackup&lt;/a&gt;. Contrôlons le contenu du répertoire de sauvegarde et
recherchons le tant attendu &lt;code&gt;backup_label&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ tree backups/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;backups/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── backup_manifest
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;├── base.tar
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;└── pg_wal.tar
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ tar -xf backups/base.tar --to-stdout backup_label
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;START WAL LOCATION: 0/16000028 (file 000000010000000000000016)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CHECKPOINT LOCATION: 0/16000060
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;BACKUP METHOD: streamed
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;BACKUP FROM: master
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;START TIME: 2021-01-18 15:22:52 CET
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LABEL: demo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;START TIMELINE: 1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ce dernier se trouve à la racine de notre archive et joue un rôle très
particulier dans le processus de démarrage &lt;code&gt;startup&lt;/code&gt; puisqu&amp;rsquo;il renseigne le point
de reprise à partir duquel rejouer les journaux. Dans notre exemple, il s&amp;rsquo;agit
de la position &lt;code&gt;0/16000060&lt;/code&gt; présente dans le journal &lt;code&gt;000000010000000000000016&lt;/code&gt;.
En cas d&amp;rsquo;absence du &lt;code&gt;backup_label&lt;/code&gt;, le processus de démarrage consultera à la
place le &lt;a href="https://pgpedia.info/p/pg_control.html" target="_blank" rel="noopener"&gt;fichier de contrôle&lt;/a&gt; afin de déterminer le plus récent point de
reprise sans garantie qu&amp;rsquo;il soit le bon.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="lheure-de-gloire"&gt;L&amp;rsquo;heure de gloire&lt;/h2&gt;
&lt;p&gt;Vous conviendrez que la forme et l&amp;rsquo;intérêt du fichier &lt;code&gt;backup_label&lt;/code&gt; sont
anecdotiques (bien qu&amp;rsquo;essentiels) dans l&amp;rsquo;architecture de sauvegarde avec PostgreSQL.
Il ne s&amp;rsquo;agit que d&amp;rsquo;un fichier texte de quelques lignes, requis exclusivement pour
assurer certains contrôles lors d&amp;rsquo;une restauration.&lt;/p&gt;
&lt;p&gt;Et pourtant, la petite révolution que provoqua la version 8.0 en janvier 2005
avec l&amp;rsquo;archivage continu et la restauration PITR suscita naturellement la
créativité de l&amp;rsquo;équipe de développement au cours des années qui suivirent. Le
fichier &lt;code&gt;backup_label&lt;/code&gt; évolua pour gagner en modularité et en stabilité.&lt;/p&gt;
&lt;p&gt;À l&amp;rsquo;origine, l&amp;rsquo;outil &lt;code&gt;pg_basebackup&lt;/code&gt; n&amp;rsquo;était pas encore disponible et seul l&amp;rsquo;appel
à la méthode &lt;a href="https://pgpedia.info/p/pg_start_backup.html" target="_blank" rel="noopener"&gt;pg_start_backup()&lt;/a&gt; permettait de générer le fichier dans lequel
se trouvaient les quatres informations &lt;a href="https://github.com/postgres/postgres/blob/REL8_0_STABLE/src/backend/access/transam/xlog.c#L5411" target="_blank" rel="noopener"&gt;suivantes&lt;/a&gt; pour accompagner la
sauvegarde à chaud :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="cp"&gt;# backend/access/transam/xlog.c
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;START WAL LOCATION: %X/%X (file %s)&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;startpoint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xlogid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;startpoint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xrecoff&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xlogfilename&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;CHECKPOINT LOCATION: %X/%X&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;checkpointloc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xlogid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;checkpointloc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;xrecoff&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;START TIME: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;strfbuf&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nf"&gt;fprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;LABEL: %s&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;backupidstr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Les versions majeures se sont enchaînées avec son lot de corrections ou
d&amp;rsquo;améliorations. Parmi les contributions notables, j&amp;rsquo;ai relevé pour vous :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.postgresql.org/message-id/flat/D960CB61B694CF459DCFB4B0128514C201ED284B%40exadv11.host.magwien.gv.at" target="_blank" rel="noopener"&gt;Contribution&lt;/a&gt; de Laurenz Albe (commit &lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=c979a1fefafcc83553bf218c7f2270cad77ea31d" target="_blank" rel="noopener"&gt;c979a1fe&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Publié avec la version 8.4, le code &lt;code&gt;xlog.c&lt;/code&gt; se voit enrichir d&amp;rsquo;une méthode
interne pour annuler la sauvegarde en cours. L&amp;rsquo;exécution de la commande
&lt;code&gt;pg_ctl stop&lt;/code&gt; en mode &lt;em&gt;fast&lt;/em&gt; renomme le fichier en &lt;code&gt;backup_label.old&lt;/code&gt; ;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.postgresql.org/message-id/flat/20120624213341.GA90986%40mr-paradox.net" target="_blank" rel="noopener"&gt;Contribution&lt;/a&gt; de Dave Kerr (commit &lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=0f04fc67f71f7cb29ccedb2e7ddf443b9e52b958" target="_blank" rel="noopener"&gt;0f04fc67&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Apparue avec la version mineure 9.0.9, la méthode &lt;code&gt;pg_start_backup()&lt;/code&gt; inclut
un appel &lt;code&gt;fsync()&lt;/code&gt; pour forcer l&amp;rsquo;écriture sur disque du fichier &lt;code&gt;backup_label&lt;/code&gt;.
Cette sécurité garantit la consistance d&amp;rsquo;un instantané matériel ;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.postgresql.org/message-id/flat/4E40F710.6000404%40enterprisedb.com" target="_blank" rel="noopener"&gt;Contribution&lt;/a&gt; de Heikki Linnakangas (commit &lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=41f9ffd928b6fdcedd685483e777b0fa71ece47c" target="_blank" rel="noopener"&gt;41f9ffd9&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Proposé en version 9.2, ce patch corrige des comportements anormaux de
restauration à partir de la nouvelle méthode de sauvegarde par flux. Le fichier
&lt;code&gt;backup_label&lt;/code&gt; précise la méthode employée entre &lt;code&gt;pg_start_backup&lt;/code&gt; ou &lt;code&gt;streamed&lt;/code&gt; ;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.postgresql.org/message-id/flat/201108050646.p756kHC5023570%40ccmds32.silk.ntts.co.jp" target="_blank" rel="noopener"&gt;Contribution&lt;/a&gt; de Jun Ishizuka et Fujii Masao (commit &lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=8366c7803ec3d0591cf2d1226fea1fee947d56c3" target="_blank" rel="noopener"&gt;8366c780&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Depuis la version 9.2, la méthode &lt;code&gt;pg_start_backup()&lt;/code&gt; peut être exécutée sur
une instance secondaire. Le rôle de l&amp;rsquo;instance d&amp;rsquo;où provient la sauvegarde est
renseignée dans le fichier &lt;code&gt;backup_label&lt;/code&gt; ;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="https://www.postgresql.org/message-id/flat/CAB7nPqRosJNapKVW2QPwkN9%2BypfL4yiR4mcNFZcjxS2c8m%2BVkw%40mail.gmail.com" target="_blank" rel="noopener"&gt;Contribution&lt;/a&gt; de Michael Paquier (commit &lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=6271fceb8a4f07dafe9d67dcf7e849b319bb2647" target="_blank" rel="noopener"&gt;6271fceb&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Ajoutée en version 11, l&amp;rsquo;information &lt;em&gt;timeline&lt;/em&gt; dans le fichier &lt;code&gt;backup_label&lt;/code&gt;
rejoint les précédentes pour comparer sa valeur avec celles des journaux à
rejouer lors d&amp;rsquo;une récupération de données ;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Vous l&amp;rsquo;aurez compris, pendant de nombreuses années, la capacité de faire une
sauvegarde dite consistante, reposait sur les deux méthodes vues précédemment.
La fonction historique &lt;code&gt;pg_start_backup()&lt;/code&gt; fut particulièrement touchée
par d&amp;rsquo;incessantes critiques au sujet d&amp;rsquo;un comportement non souhaité, notamment
son mode « exclusif ».&lt;/p&gt;
&lt;p&gt;Voyons cela ensemble sur une instance récente en version 13 :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pg_start_backup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;demo&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- pg_start_backup
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- -----------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- 0/1D000028
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ kill -ABRT $(head -1 data/postmaster.pid)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ cat data/backup_label
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;START WAL LOCATION: 0/1D000028 (file 00000001000000000000001D)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CHECKPOINT LOCATION: 0/1D000060
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;BACKUP METHOD: pg_start_backup
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;BACKUP FROM: master
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;START TIME: 2021-01-18 16:49:57 CET
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LABEL: demo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;START TIMELINE: 1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Le signal &lt;code&gt;ABRT&lt;/code&gt; interrompt sans préavis le processus &lt;code&gt;postmaster&lt;/code&gt; de l&amp;rsquo;instance
et la routine d&amp;rsquo;arrêt &lt;code&gt;CancelBackup&lt;/code&gt; n&amp;rsquo;est pas appelée pour renommer le fichier
en &lt;code&gt;backup_label.old&lt;/code&gt;. Avec une activité classique de production, les journaux
sont recyclés et archivés à mesure que les transactions s&amp;rsquo;enchaînent. Au démarrage
de l&amp;rsquo;instance, le fichier &lt;code&gt;backup_label&lt;/code&gt; présent dans le répertoire de données
est lu par erreur et n&amp;rsquo;indique plus le bon point de reprise pour la récupération
des données.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LOG: database system was shut down at 2021-01-18 17:08:43 CET
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LOG: invalid checkpoint record
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;FATAL: could not locate required checkpoint record
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;HINT: If you are restoring from a backup, touch &amp;#34;data/recovery.signal&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; and add required recovery options.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; If you are not restoring from a backup, try removing the file
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &amp;#34;data/backup_label&amp;#34;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Be careful: removing &amp;#34;data/backup_label&amp;#34; will result in a corrupt
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; cluster if restoring from a backup.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LOG: startup process (PID 19320) exited with exit code 1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LOG: aborting startup due to startup process failure
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LOG: database system is shut down
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Ce message complet n&amp;rsquo;est apparu qu&amp;rsquo;à partir de la version 12 avec un &lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=c900c15269f0f900d666bd1b0c6df3eff5098678" target="_blank" rel="noopener"&gt;avertissement&lt;/a&gt;
plus prononcé dans la documentation au sujet du fichier, faisant suite à de longs
échanges sur la possibilité de se séparer ou non de cette méthode. Dans l&amp;rsquo;un
d&amp;rsquo;eux, on peut lire la remarquable &lt;a href="https://www.postgresql.org/message-id/CA&amp;#43;TgmoaGvpybE=xvJeg9Jc92c-9ikeVz3k-_Hg9=mdG05u=e=g@mail.gmail.com" target="_blank" rel="noopener"&gt;intervention&lt;/a&gt; de Robert Haas qui revient
sur le succès de cette fonctionnalité depuis ses débuts et la confusion fréquente
que rencontrent les utilisateurs qui ne comprennent ni la complexité ni les
instructions claires de la documentation.&lt;/p&gt;
&lt;p&gt;À présent, une note y clarifie les choses.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ce type de sauvegarde peut seulement être réalisé sur un serveur primaire et
ne permet pas des sauvegardes concurrentes. De plus, le fichier backup_label
créé sur un serveur primaire peut empêcher le redémarrage de celui-ci en cas
de crash. D&amp;rsquo;un autre côté, la suppression à tord de ce fichier d&amp;rsquo;une sauvegarde
ou d&amp;rsquo;un serveur secondaire est une erreur fréquente qui peut mener à de
sérieuses corruptions de données.&lt;/p&gt;
&lt;p&gt;Source : &lt;a href="https://docs.postgresql.fr/12/continuous-archiving.html#BACKUP-LOWLEVEL-BASE-BACKUP-EXCLUSIVE" target="_blank" rel="noopener"&gt;Créer une sauvegarde exclusive de bas niveau&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="place-à-la-relève"&gt;Place à la relève&lt;/h2&gt;
&lt;p&gt;Cette limitation était connue de longue date et l&amp;rsquo;équipe de développement
proposa une &lt;a href="https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=7117685461af50f50c03f43e6a622284c8d54694" target="_blank" rel="noopener"&gt;alternative&lt;/a&gt; en septembre 2016 avec la sortie de la version 9.6
et l&amp;rsquo;introduction de la sauvegarde dite « concurrente ». Depuis ce jour, la
sauvegarde exclusive est annoncée obsolète par les développeurs et pourrait être
supprimée dans les versions à venir.&lt;/p&gt;
&lt;p&gt;Le fichier &lt;code&gt;backup_label&lt;/code&gt; ne disparaît pas en soi. Ses informations sont toujours
requises pour la restauration PITR mais le fichier n&amp;rsquo;a plus d&amp;rsquo;état transitoire sur
le disque et n&amp;rsquo;est plus écrit dans le répertoire de l&amp;rsquo;instance par la méthode
&lt;code&gt;pg_start_backup()&lt;/code&gt;. En remplacement, l&amp;rsquo;administrateur ou le script de sauvegarde
doit être en capacité d&amp;rsquo;exécuter la commande &lt;code&gt;pg_stop_backup()&lt;/code&gt; dans la même
connexion à l&amp;rsquo;instance pour y récupérer les éléments et reconstruire le fichier
au moment de la restauration.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pg_start_backup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;label&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;demo&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;exclusive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fast&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- pg_start_backup
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- -----------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- 0/42000028
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;labelfile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pg_stop_backup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;exclusive&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- labelfile
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- ----------------------------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- START WAL LOCATION: 0/42000028 (file 000000010000000000000042)+
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- CHECKPOINT LOCATION: 0/42000060 +
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- BACKUP METHOD: streamed +
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- BACKUP FROM: master +
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- START TIME: 2021-01-18 18:17:16 CET +
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- LABEL: demo +
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- START TIMELINE: 1 +
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Une autre méthode nous permet de retrouver facilement le contenu du fichier,
d&amp;rsquo;autant plus si l&amp;rsquo;archivage est en place sur l&amp;rsquo;instance. En effet, à l&amp;rsquo;annonce
de la fin d&amp;rsquo;une sauvegarde, les éléments précédents sont écrits dans un fichier
d&amp;rsquo;historique &lt;code&gt;.backup&lt;/code&gt; au sein des journaux de transactions et un fichier &lt;code&gt;.ready&lt;/code&gt;
est ajouté dans le répertoire &lt;code&gt;archive_status&lt;/code&gt; à destination du processus
d&amp;rsquo;archivage. Une recherche rapide sur le dépôt des archives plus tard, et nous
sommes en possession du fichier prêt à l&amp;rsquo;emploi pour une restauration.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ find archives -type f -not -size 16M
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;archives/000000010000000000000016.00000028.backup
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;$ grep -iv ^stop archives/000000010000000000000016.00000028.backup
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;START WAL LOCATION: 0/42000028 (file 000000010000000000000042)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;CHECKPOINT LOCATION: 0/42000060
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;BACKUP METHOD: streamed
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;BACKUP FROM: master
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;START TIME: 2021-01-18 18:17:16 CET
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;LABEL: demo
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;START TIMELINE: 1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La venue d&amp;rsquo;une brique complète pour la sauvegarde concurrente a permis l&amp;rsquo;émergence
de nouvelles solutions de sauvegardes, plus performantes et plus modulaires que
&lt;code&gt;pg_basebackup&lt;/code&gt;. Dans le paysage des outils tiers, vous entendriez peut-être parler
de &lt;a href="https://pgbackrest.org/" target="_blank" rel="noopener"&gt;pgBackRest&lt;/a&gt; écrit en C, &lt;a href="https://www.pgbarman.org/" target="_blank" rel="noopener"&gt;Barman&lt;/a&gt; écrit en Python ou &lt;a href="https://dalibo.github.io/pitrery/" target="_blank" rel="noopener"&gt;pitrery&lt;/a&gt; écrit en Bash.
En outre, ces outils soulagent l&amp;rsquo;administrateur de la rédaction de scripts devenus
trop complexes et loin d&amp;rsquo;être immuable dans les années à venir.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="morale-de-lhistoire"&gt;Morale de l&amp;rsquo;histoire&lt;/h2&gt;
&lt;p&gt;Au fil des versions, le fichier &lt;code&gt;backup_label&lt;/code&gt; a enduré de nombreuses tempêtes
et rebondissements pour aboutir à une forme plus aboutie de la sauvegarde et de
la restauration physique dans PostgreSQL.&lt;/p&gt;
&lt;p&gt;Si vous êtes responsable de la maintenance d&amp;rsquo;instances, particulièrement dans
un environnement virtualisé, je ne peux que vous recommander de contrôler vos
politiques de sauvegarde et l&amp;rsquo;outillage associé. Il n&amp;rsquo;est pas rare de voir des
hyperviseurs réaliser des instantanées des machines virtuelles avec des appels de
la méthode &lt;code&gt;pg_start_backup()&lt;/code&gt; en mode exclusif.&lt;/p&gt;
&lt;p&gt;Les outils spécialisés cités plus haut peuvent/doivent être étudiés. S&amp;rsquo;ils ne
correspondent pas très bien à vos besoins, il est toujours possible de
bénéficier des mécanismes de la sauvegarde concurrente à l&amp;rsquo;aide d&amp;rsquo;un &lt;a href="https://www.commandprompt.com/blog/postgresql-non-exclusive-base-Backup-bash/" target="_blank" rel="noopener"&gt;fichier
temporaire&lt;/a&gt; sous Linux et sa commande &lt;code&gt;mkfifo&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;La décision de supprimer définitivement la sauvegarde exclusive n&amp;rsquo;est actuellement
plus débattue et a été retirée du &lt;em&gt;backlog&lt;/em&gt; de développement lors du Commitfest
de &lt;a href="https://commitfest.postgresql.org/28/1913/" target="_blank" rel="noopener"&gt;juillet 2020&lt;/a&gt;. Lors des derniers échanges, le contributeur David Steele
(auteur de pgBackRest notamment) &lt;a href="https://www.postgresql.org/message-id/d4da3456-06a0-b790-fb07-036d0bd4bf0d%40pgmasters.net" target="_blank" rel="noopener"&gt;annonçait&lt;/a&gt; qu&amp;rsquo;une sauvegarde exclusive pourrait
stocker son fichier &lt;code&gt;backup_label&lt;/code&gt; directement en mémoire partagée plutôt que sur
le disque et ainsi corriger sa principale faiblesse :&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It might be easier/better to just keep the one exclusive slot in shared
memory and store the backup label in it. We only allow one exclusive
backup now so it wouldn&amp;rsquo;t be a loss in functionality.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;La suite au prochain épisode !&lt;/p&gt;</description></item><item><title>Construire une instance standby avec pgBackRest</title><link>https://fljd.in/2019/11/07/construire-une-instance-standby-avec-pgbackrest/</link><pubDate>Thu, 07 Nov 2019 16:00:00 +0200</pubDate><author>Florent Jardin</author><guid>https://fljd.in/2019/11/07/construire-une-instance-standby-avec-pgbackrest/</guid><description>&lt;p&gt;Pour cette démonstration, j&amp;rsquo;utilise le système Debian et dispose de deux instances
en version 12, d&amp;rsquo;un serveur de sauvegarde et du paquet &lt;code&gt;pgbackrest&lt;/code&gt; pour mettre
en place une réplication et observer les nouveautés concernant la &lt;a href="https://paquier.xyz/postgresql-2/postgres-12-recovery-change/" target="_blank" rel="noopener"&gt;disparition&lt;/a&gt;
du fichier &lt;code&gt;recovery.conf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Pour faciliter le transfert des WAL et des sauvegardes PITR, j&amp;rsquo;ajoute un compte
utilisateur &lt;code&gt;pgbr&lt;/code&gt; sur le serveur de sauvegarde, accessible à partir des deux
instances avec un partage de clé SSH. &lt;em&gt;(Conseil : toujours externaliser les
sauvegardes de bases de données sur un système et un stockage indépendant de
l&amp;rsquo;infrastructure de production PostgreSQL…)&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo useradd -s /bin/bash -md /etc/pgbackrest pgbr
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo mv /etc/pgbackrest.conf /etc/pgbackrest/
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo chown pgbr: /etc/pgbackrest/pgbackrest.conf &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; /var/log/pgbackrest /var/lib/pgbackrest
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La réplication par flux (&lt;em&gt;streaming&lt;/em&gt;) est assurée par un compte dédié nommé
&lt;code&gt;streamer&lt;/code&gt;, autorisé à se connecter sur les instances PostgreSQL du sous-réseau
grâce à l&amp;rsquo;ajout d&amp;rsquo;une entrée dans le fichier &lt;code&gt;pg_hba.conf&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u postgres createuser --replication --pwprompt streamer
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# pg_hba.conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Allow replication connections from trusted subnet, by a user with the&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# replication privilege.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;host replication streamer 10.1.0.0/28 md5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;Le fichier &lt;code&gt;.pgpass&lt;/code&gt; est déposé sur chaque serveur pour le compte &lt;code&gt;postgres&lt;/code&gt;,
afin d&amp;rsquo;assurer la connexion du compte &lt;code&gt;streamer&lt;/code&gt; sans saisie de mot de passe.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Dans ce scénario, les archives générées par l&amp;rsquo;instance primaire seront déplacées
sur le serveur de sauvegarde et l&amp;rsquo;instance standby les consultera au besoin. La
planification des sauvegardes sera sous la responsabilité de l&amp;rsquo;utilisateur &lt;code&gt;pgbr&lt;/code&gt;
avec une administration distante. La configuration fine se découpe dans les
fichiers suivants.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-ini" data-lang="ini"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# /etc/pgbackrest/bkp1.conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[lab]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;pg1-host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;lab1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;pg2-host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;lab2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;pg1-host-user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;pg2-host-user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;postgres&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;pg1-path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/var/lib/postgresql/12/lab1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;pg2-path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/var/lib/postgresql/12/lab2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;pg1-host-config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/etc/pgbackrest/lab1.conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;pg2-host-config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/etc/pgbackrest/lab2.conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[global]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;start-fast&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;y&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;log-level-console&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;info&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;repo1-retention-full&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;repo1-path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/var/lib/pgbackrest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# /etc/pgbackrest/lab1.conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[lab]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;pg1-path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/var/lib/postgresql/12/lab1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[global]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;repo1-host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;bkp1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;repo1-host-user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;pgbr&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# /etc/pgbackrest/lab2.conf&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[lab]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;pg1-path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/var/lib/postgresql/12/lab2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;recovery-option&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;recovery_target_timeline=latest&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;recovery-option&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;primary_conninfo=host=lab1 port=5432 user=streamer&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;[global]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;repo1-host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;bkp1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;repo1-host-user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;pgbr&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Avant de pouvoir créer la stanza, il est nécessaire de démarrer l&amp;rsquo;instance secondaire
en mode &lt;code&gt;standby&lt;/code&gt; ; il suffit de positionner un fichier &lt;code&gt;standby.signal&lt;/code&gt; dans
le répertoire de données et de redémarrer l&amp;rsquo;instance :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo pg_ctlcluster stop &lt;span class="m"&gt;12&lt;/span&gt; lab2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u postgres touch /var/lib/postgresql/12/lab1/standby.signal
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo pg_ctlcluster start &lt;span class="m"&gt;12&lt;/span&gt; lab2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;À partir de ce moment, et même si les deux instances ne partagent pas les mêmes
données, je peux créer la stanza avec l&amp;rsquo;outil &lt;code&gt;pgbackrest&lt;/code&gt; sur mon serveur de
sauvegarde avec l&amp;rsquo;utilisateur dédié.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u pgbr pgbackrest stanza-create &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --stanza&lt;span class="o"&gt;=&lt;/span&gt;lab --config&lt;span class="o"&gt;=&lt;/span&gt;/etc/pgbackrest/bkp1.conf
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Dès ce moment, mon instance, consciente de l&amp;rsquo;espace de stockage distant, peut
envoyer ses archives de WAL &lt;em&gt;via&lt;/em&gt; la commande &lt;code&gt;archive-push&lt;/code&gt; de &lt;code&gt;pgbackrest&lt;/code&gt;.
Un redémarrage est requis pour activer le mode archive.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SYSTEM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;archive_mode&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;on&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SYSTEM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;SET&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;archive_command&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;pgbackrest archive-push %p --stanza=lab --config=/etc/pgbackrest/lab1.conf&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Et pour finir, une première sauvegarde complète peut être lancée sur le serveur
de sauvegarde pour assurer la construction de l&amp;rsquo;instance standby.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u pgbr pgbackrest backup --stanza&lt;span class="o"&gt;=&lt;/span&gt;lab --config&lt;span class="o"&gt;=&lt;/span&gt;/etc/pgbackrest/bkp1.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u pgbr pgbackrest info
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# stanza: lab&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# status: ok&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# cipher: none&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# db (current)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# wal archive min/max (12-1): 000000010000000000000008/000000010000000000000008&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# full backup: 20191107-103443F&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# timestamp start/stop: 2019-11-07 10:34:43 / 2019-11-07 10:35:09&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# wal start/stop: 000000010000000000000008 / 000000010000000000000008&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# database size: 23.5MB, backup size: 23.5MB&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# repository size: 2.8MB, repository backup size: 2.8MB&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La sauvegarde de l&amp;rsquo;instance primaire peut être restaurée sur la seconde instance
avec les options &lt;code&gt;--delta&lt;/code&gt; et &lt;code&gt;--type=standby&lt;/code&gt; pour écraser les fichiers erronés
et ajouter le descripteur &lt;code&gt;standby.signal&lt;/code&gt; dans le répertoire de données. pgBackRest
se charge de configurer les options de réplication dans le fichier
&lt;code&gt;postgresql.auto.conf&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo pg_ctlcluster stop &lt;span class="m"&gt;12&lt;/span&gt; lab2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u postgres pgbackrest restore --stanza&lt;span class="o"&gt;=&lt;/span&gt;lab &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --delta --type&lt;span class="o"&gt;=&lt;/span&gt;standby --config&lt;span class="o"&gt;=&lt;/span&gt;/etc/pgbackrest/lab2.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo pg_ctlcluster start &lt;span class="m"&gt;12&lt;/span&gt; lab2
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Tadaa ! Une connexion est alors établie entre les deux nœuds et l&amp;rsquo;on constate
que l&amp;rsquo;utilisateur &lt;code&gt;streamer&lt;/code&gt; rejoue en asynchrone les transactions de l&amp;rsquo;instance
primaire vers l&amp;rsquo;instance standby.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;select&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;pg_stat_replication&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- -[ RECORD 1 ]----+------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- pid | 8893
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- usesysid | 16384
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- usename | streamer
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- application_name | 12/lab2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- client_addr | 10.1.0.1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- client_hostname |
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- client_port | 38820
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- backend_start | 2019-11-07 10:50:22.424464+00
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- backend_xmin |
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- state | streaming
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- sent_lsn | 0/A000060
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- write_lsn | 0/A000060
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- flush_lsn | 0/A000060
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- replay_lsn | 0/A000060
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- write_lag | 00:00:00.001095
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- flush_lag | 00:00:00.004415
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- replay_lag | 00:00:00.004696
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- sync_priority | 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- sync_state | async
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;-- reply_time | 2019-11-07 12:39:59.595595+00
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="message"&gt;&lt;p&gt;Pour la rédaction de cet article, je n&amp;rsquo;ai pas véritablement utilisé trois serveurs,
mais bien un seul en réalité. L&amp;rsquo;astuce pour faire tourner deux instances sur le
même port 5432 consiste à ajouter des IP virtuelles sur l&amp;rsquo;interface du serveur
et de faire résoudre les noms de machines par le fichier &lt;code&gt;/etc/hosts&lt;/code&gt; local.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ip add add 10.1.0.1/28 dev ens6
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ip add add 10.1.0.2/28 dev ens6
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ip add add 10.1.0.3/28 dev ens6
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Les instances doivent ensuite être installées/configurées avec les bons paramètres
&lt;code&gt;listen_addresses&lt;/code&gt; et &lt;code&gt;unix_socket_directories&lt;/code&gt; comme suivent :&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install -y postgresql-common
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo vim /etc/postgresql-common/createcluster.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install -y postgresql-12
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo -u postgres mkdir -p /var/run/postgresql/lab{1,2}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo pg_createcluster 12 lab1 \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --pgoption listen_addresses=&amp;#39;10.1.0.1&amp;#39; --pgoption port=5432 \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --pgoption unix_socket_directories=/var/run/postgresql/lab1
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo pg_createcluster 12 lab2 \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --pgoption listen_addresses=&amp;#39;10.1.0.2&amp;#39; --pgoption port=5432 \
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --pgoption unix_socket_directories=/var/run/postgresql/lab2
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo pg_ctlcluster 12 lab1 start
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo pg_ctlcluster 12 lab2 start
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Quelques ajustements de droits sur le répertoire &lt;code&gt;/tmp/pgbackrest&lt;/code&gt; pour les
fichiers de verrous (paramètre &lt;code&gt;--lock-path&lt;/code&gt;) et le tour est joué !&lt;/p&gt;
&lt;/div&gt;</description></item></channel></rss>