Sauvegardes incrémentielles postgresql avec pgbackrest - un cours pour un jeune combattant du développeur

Avertissement

Je suis développeur. J'écris du code et j'interagis avec la base de données uniquement en tant qu'utilisateur. Je ne prétends en aucun cas être un administrateur système, et encore moins un dba. Mais…

Il se trouve que j'ai dû organiser une sauvegarde de la base de données postgresql. Pas de cloud : utilisez simplement SSH et assurez-vous que tout fonctionne sans demander d'argent. Que faisons-nous dans de tels cas ? C'est vrai, nous poussons pgdump dans cron, sauvegardons tout dans l'archive tous les jours, et si nous sommes complètement perdus, nous envoyons cette archive quelque part au loin.

Cette fois, la difficulté était que, selon les plans, la base de données était censée croître d'environ +- 100 Mo par jour. Bien sûr, après quelques semaines, le désir de tout sauvegarder avec pgdump disparaîtra. C'est là que les sauvegardes incrémentielles viennent à la rescousse.

Intéressant? Bienvenue au chat.

La sauvegarde incrémentielle est un type de sauvegarde dans lequel tous les fichiers sources ne sont pas copiés, mais uniquement les nouveaux et ceux modifiés depuis la création de la copie précédente.

Comme tout développeur qui n'était ABSOLUMENT pas disposé (à cette époque) à comprendre les subtilités de Postgres, je voulais trouver le bouton vert. Eh bien, vous savez, comme dans AWS, DigitalOcean : vous avez appuyé sur un bouton - vous avez obtenu la réplication, vous avez appuyé sur le deuxième - vous avez configuré des sauvegardes, le troisième - vous avez tout annulé de quelques heures. Je n'ai pas trouvé de bouton ni de bel outil graphique. Si vous en connaissez un (gratuit ou pas cher), écrivez-le dans les commentaires.

Après avoir cherché sur Google, j'ai trouvé deux outils pgbarman и pgdossier. Je n'ai tout simplement pas réussi avec le premier (documentation très clairsemée, j'ai essayé de tout comprendre d'après d'anciens manuels), mais avec le second la documentation s'est avérée à la hauteur, mais non sans défauts. Pour simplifier le travail de ceux qui sont confrontés à une tâche similaire, cet article a été rédigé.

Après avoir lu cet article, vous apprendrez comment effectuer des sauvegardes incrémentielles, les enregistrer sur un serveur distant (référentiel avec sauvegardes) et les restaurer en cas de perte de données ou d'autres problèmes sur le serveur principal.

Formation

Pour reproduire le manuel, vous aurez besoin de deux VPS. Le premier sera le stockage (le référentiel sur lequel les sauvegardes seront stockées), et le second, en fait, le serveur lui-même avec postgres (dans mon cas, la version 11 de postgres).

On suppose que sur le serveur avec postgres, vous avez root, l'utilisateur sudo, l'utilisateur postgres et postgres lui-même est installé (l'utilisateur postgres est créé automatiquement lors de l'installation de postgresql), et sur le serveur de référentiel il y a l'utilisateur root et sudo (dans le manuel le nom d'utilisateur pgbackrest sera utilisé).

Pour que vous ayez moins de problèmes lors de la reproduction des instructions, j'écris en italique où, avec quel utilisateur et avec quels droits ai-je exécuté la commande en écrivant et en vérifiant l'article.

Installation de pgbackrest

Dépôt (utilisateur pgbackrest) :

1. Téléchargez l'archive depuis pgbackrest et transférez son contenu dans le dossier /build :

sudo mkdir /build
sudo wget -q -O - 
       https://github.com/pgbackrest/pgbackrest/archive/release/2.18.tar.gz | 
       sudo tar zx -C /build

2. Installez les dépendances nécessaires à l'assemblage :

sudo apt-get update
sudo apt-get install build-essential libssl-dev libxml2-dev libperl-dev zlib1g-dev 
       libpq-dev

3. Assemblage du dossier :

cd /build/pgbackrest-release-2.18/src && sudo ./configure
sudo make -s -C /build/pgbackrest-release-2.18/src

4. Copiez le fichier exécutable dans le répertoire /usr/bin :

sudo cp /build/pgbackrest-release-2.18/src/pgbackrest /usr/bin
sudo chmod 755 /usr/bin/pgbackrest

5. Pgbackrest nécessite Perl. Installer:

sudo apt-get install perl

6. Créez des répertoires pour les logs, accordez-leur certains droits :

sudo mkdir -p -m 770 /var/log/pgbackrest
sudo chown pgbackrest:pgbackrest /var/log/pgbackrest
sudo mkdir -p /etc/pgbackrest
sudo mkdir -p /etc/pgbackrest/conf.d
sudo touch /etc/pgbackrest/pgbackrest.conf
sudo chmod 640 /etc/pgbackrest/pgbackrest.conf
sudo chown pgbackrest:pgbackrest /etc/pgbackrest/pgbackrest.conf

7. Vérifiez :

pgbackrest version

Serveur Postgres (utilisateur sudo ou root) :

Le processus d'installation de pgbackrest sur un serveur avec postgres est similaire au processus d'installation sur le référentiel (oui, pgbackrest doit être installé sur les deux serveurs), mais au 6ème paragraphe les deuxième et dernière commandes :

sudo chown pgbackrest:pgbackrest /var/log/pgbackrest
sudo chown pgbackrest:pgbackrest /etc/pgbackrest/pgbackrest.conf

remplacer par:

sudo chown postgres:postgres /var/log/pgbackrest
sudo chown postgres:postgres /etc/pgbackrest/pgbackrest.conf

Configuration de l'interaction entre les serveurs via SSH sans mot de passe

Pour que pgbackrest fonctionne correctement, il est nécessaire de configurer l'interaction entre le serveur postgres et le référentiel à l'aide du fichier de clé.

Dépôt (utilisateur pgbackrest) :

Créez une paire de clés :

mkdir -m 750 /home/pgbackrest/.ssh
ssh-keygen -f /home/pgbackrest/.ssh/id_rsa 
       -t rsa -b 4096 -N ""

Attention! Nous exécutons les commandes ci-dessus sans sudo.

Serveur Postgres (utilisateur sudo ou root) :

Créez une paire de clés :

sudo -u postgres mkdir -m 750 -p /var/lib/postgresql/.ssh
sudo -u postgres ssh-keygen -f /var/lib/postgresql/.ssh/id_rsa 
       -t rsa -b 4096 -N ""

Dépôt (utilisateur sudo) :

Copiez la clé publique du serveur postgres sur le serveur du référentiel :

(echo -n 'no-agent-forwarding,no-X11-forwarding,no-port-forwarding,' && 
       echo -n 'command="/usr/bin/pgbackrest ${SSH_ORIGINAL_COMMAND#* }" ' && 
       sudo ssh root@<postgres_server_ip> cat /var/lib/postgresql/.ssh/id_rsa.pub) | 
       sudo -u pgbackrest tee -a /home/pgbackrest/.ssh/authorized_keys

À cette étape, il vous sera demandé le mot de passe de l'utilisateur root. Vous devez saisir le mot de passe de l'utilisateur root du serveur postgres !

Serveur Postgres (utilisateur sudo) :

Copiez la clé publique du référentiel sur le serveur avec postgres :

(echo -n 'no-agent-forwarding,no-X11-forwarding,no-port-forwarding,' && 
       echo -n 'command="/usr/bin/pgbackrest ${SSH_ORIGINAL_COMMAND#* }" ' && 
       sudo ssh root@<repository_server_ip> cat /home/pgbackrest/.ssh/id_rsa.pub) | 
       sudo -u postgres tee -a /var/lib/postgresql/.ssh/authorized_keys

À cette étape, il vous sera demandé le mot de passe de l'utilisateur root. Vous devez saisir exactement le mot de passe de l'utilisateur root du référentiel !

vérifier:

Dépôt (utilisateur root, pour la pureté de l'expérience) :

sudo -u pgbackrest ssh postgres@<postgres_server_ip>

Serveur Postgres (utilisateur root, pour la pureté de l'expérience) :

sudo -u postgres ssh pgbackrest@<repository_server_ip>

Nous veillons à ce que nous ayons accès sans problèmes.

Configuration d'un serveur Postgres

Serveur Postgres (utilisateur sudo ou root) :

1. Autorisons l'accès au serveur Postgres à partir d'adresses IP externes. Pour ce faire, éditez le fichier postgresql.conf (situé dans le dossier /etc/postgresql/11/main), en y ajoutant la ligne :

listen_addresses = '*'

Si une telle ligne existe déjà, décommentez-la ou définissez la valeur du paramètre sur « * ».

En fichier pg_hba.conf (également situé dans le dossier /etc/postgresql/11/main) ajoutez les lignes suivantes :

hostssl  all  all  0.0.0.0/0  md5
host  all  all  0.0.0.0/0  md5

où:

hostssl/host - подключаемся через SSL (или нет)
all - разрешаем подключение ко всем базам
all - имя пользователя, которому разрешаем подключение (всем)
0.0.0.0/0 - маска сети с которой можно подключаться
md5 - способ шифрования пароля

2. Faisons les réglages nécessaires dans postgresql.conf (c'est dans le dossier /etc/postgresql/11/main) pour que pgbackrest fonctionne :

archive_command = 'pgbackrest --stanza=main archive-push %p' # Где main - название кластера. При установке postgres автоматически создает кластер main.
archive_mode = on
max_wal_senders = 3
wal_level = replica

3. Faisons les réglages nécessaires dans le fichier de configuration pgbackrest (/etc/pgbackrest/pgbackrest.conf) :

[main]
pg1-path=/var/lib/postgresql/11/main

[global]
log-level-file=detail
repo1-host=<repository_server_ip>

4. Rechargez postgresql :

sudo service postgresql restart

Configuration d'un serveur de référentiel

Dépôt (utilisateur pgbackrest) :

Faisons les réglages nécessaires dans le fichier de configuration pgdossier
(/etc/pgbackrest/pgbackrest.conf):

[main]
pg1-host=<postgres_server_ip>
pg1-path=/var/lib/postgresql/11/main

[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2 # Параметр, указывающий сколько хранить полных бэкапов. Т.е. если у вас есть два полных бэкапа и вы создаете третий, то самый старый бэкап будет удален. Можно произносить как "хранить не более двух бэкапов" - по аналогии с ротациями логов. Спасибо @Aytuar за исправление ошибки.
start-fast=y # Начинает резервное копирование немедленно, прочитать про этот параметр можно тут https://postgrespro.ru/docs/postgrespro/9.5/continuous-archiving

Création d'un référentiel

Dépôt (utilisateur pgbackrest) :

Créer un nouveau stockage pour le cluster principal:

sudo mkdir -m 770 /var/lib/pgbackrest
sudo chown -R pgbackrest /var/lib/pgbackrest/
sudo -u pgbackrest pgbackrest --stanza=main stanza-create

Проверка

Serveur Postgres (utilisateur sudo ou root) :

On vérifie sur le serveur postgres :

sudo -u postgres pgbackrest --stanza=main --log-level-console=info check

Dépôt (utilisateur pgbackrest) :

Nous vérifions sur le serveur du référentiel :

sudo -u pgbackrest pgbackrest --stanza=main --log-level-console=info check

Nous nous assurons que dans la sortie, nous voyons la ligne « vérifier la fin de la commande : terminée avec succès ».

Fatigué? Passons à la partie la plus intéressante.

Faire une sauvegarde

Dépôt (utilisateur pgbackrest) :

1. Effectuez une sauvegarde :

sudo -u pgbackrest pgbackrest --stanza=main backup

2. Assurez-vous qu'une sauvegarde a été créée :

ls /var/lib/pgbackrest/backup/main/

Pgbackrest créera la première sauvegarde complète. Si vous le souhaitez, vous pouvez réexécuter la commande de sauvegarde et vous assurer que le système crée une sauvegarde incrémentielle.

Si vous souhaitez refaire une sauvegarde complète, spécifiez un indicateur supplémentaire :

sudo -u pgbackrest pgbackrest --stanza=main --type=full backup

Si vous souhaitez une sortie console détaillée, spécifiez également :

sudo -u pgbackrest pgbackrest --stanza=main --type=full --log-level-console=info backup

Restaurer une sauvegarde

Serveur Postgres (utilisateur sudo ou root) :

1. Arrêtez le cluster en cours d'exécution :

sudo pg_ctlcluster 11 main stop

2. Restauration à partir d'une sauvegarde :

sudo -u postgres pgbackrest --stanza=main --log-level-console=info --delta --recovery-option=recovery_target=immediate restore

Pour restaurer la base de données à l'état de la dernière sauvegarde COMPLÈTE, utilisez la commande sans spécifier recovery_target :

sudo -u postgres pgbackrest --stanza=main --log-level-console=info --delta restore

Important! Après la récupération, il peut arriver que la base de données reste bloquée en mode de récupération (il y aura des erreurs comme ERREUR : impossible d'exécuter DROP DATABASE dans une transaction en lecture seule). Pour être honnête, je n'ai pas encore compris à quoi cela est lié. La solution est la suivante (il faudra attendre un peu après l'exécution de la commande) :

sudo -u postgres psql -c "select pg_wal_replay_resume()"

En effet, il est possible de restaurer une sauvegarde spécifique par son nom. Me voici seulement Je fournirai un lien vers la description de cette fonctionnalité dans la documentation. Les développeurs conseillent d'utiliser cette option avec prudence et expliquent pourquoi. Je peux ajouter de moi-même que je l'ai utilisé. Si vous en avez vraiment besoin, assurez-vous qu'après la récupération, la base de données quitte le mode de récupération (sélectionnez pg_is_in_recovery() devrait afficher « f ») et, juste au cas où, effectuez une sauvegarde complète après la récupération.

3. Démarrez le cluster :

sudo pg_ctlcluster 11 main start

Après avoir restauré la sauvegarde, nous devons effectuer une deuxième sauvegarde :

Dépôt (utilisateur pgbackrest) :

sudo pgbackrest --stanza=main backup

C'est tout. En conclusion, je tiens à vous rappeler que je ne cherche en aucun cas à me faire passer pour un dba senior et que j'utiliserai les nuages ​​à la moindre opportunité. Actuellement, je commence moi-même à étudier divers sujets tels que la sauvegarde, la réplication, la surveillance, etc. et j'écris de petits rapports sur les résultats afin d'apporter une petite contribution à la communauté et de me laisser de petites aide-mémoire.

Dans les articles suivants, j'essaierai de parler de fonctionnalités supplémentaires - récupération de données sur un cluster propre, chiffrement des sauvegardes et publication sur S3, sauvegardes via rsync.

Source: habr.com

Ajouter un commentaire