Dans le cadre de ce tutoriel, vous allez créer une base de données de démonstration et exécuter une charge de travail d'application. Ensuite, vous configurerez les procédures d'archivage et de sauvegarde. Puis vous apprendrez à valider les procédures de sauvegarde, d'archivage et de récupération. Enfin, vous apprendrez comment effectuer la récupération de la base de données à un moment précis.
Ce tutoriel est destiné aux administrateurs de bases de données, aux opérateurs système, aux professionnels DevOps et aux architectes cloud souhaitant configurer une stratégie de sauvegarde et de récupération pour les bases de données PostgreSQL.
Dans ce tutoriel, nous partons du principe que vous connaissez les conteneurs Docker et que vous maîtrisez les commandes Linux, les moteurs de base de données PostgreSQL ainsi que Compute Engine.
Objectifs
- Configurer une procédure de sauvegarde et d'archivage
- Réaliser une récupération PITR
- Surveiller votre sauvegarde
- Valider une récupération
Coûts
Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :
Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût.
Une fois que vous avez terminé les tâches décrites dans ce document, vous pouvez éviter de continuer à payer des frais en supprimant les ressources que vous avez créées. Pour en savoir plus, consultez la section Effectuer un nettoyage.
Avant de commencer
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine and Cloud Storage APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Compute Engine and Cloud Storage APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
Concepts
Avant de commencer ce tutoriel, révisez les concepts PostgreSQL suivants :
- Archivage continu : la base de données enregistre en continu des transactions séquentielles dans un fichier.
- Journaux de transaction (journaux WAL ou "write ahead log") : les modifications apportées aux fichiers de données sont enregistrées dans les journaux de transaction avant d'être appliquées au fichier.
- Enregistrement WAL : chaque transaction appliquée à la base de données est mise en forme et stockée sous la forme d'un enregistrement WAL.
- Fichiers segments : les fichiers segments portent des noms incrémentés de manière monotone et contiennent autant d'enregistrements WAL que possible. La taille de fichier peut être configurée et présente une valeur par défaut de 16 Mio. Vous pouvez choisir une taille supérieure si vous prévoyez des transactions dont le nombre ou le volume est élevé, afin de réduire le nombre total de fichiers segments générés et de minimiser la charge de gestion des fichiers.
Pour en savoir plus, consultez la section Fiabilité et journaux de transaction.
Le schéma suivant illustre la conservation en deux étapes des journaux de transaction.
Dans le schéma précédent, la première étape des journaux de transaction persistants consiste en l'enregistrement des transactions d'écriture dans le tampon WAL par le moteur de base de données, simultanément à l'écriture dans une table. Lorsque la transaction est validée, le tampon WAL est écrit (vidé) sur le disque au cours de la deuxième étape, par le biais d'un ajout au fichier segment WAL.
Opter pour la récupération PITR
La récupération PITR convient aux scénarios suivants :
- Minimiser l'objectif de point de récupération (RPO) : Il s'agit de la durée maximale tolérée pour une perte de données avant que celle-ci n'ait un impact significatif sur les processus métier. L'enregistrement de toutes les transactions dans les journaux WAL entre deux instantanés de sauvegarde réduit considérablement la quantité de données perdues, car vous disposez ainsi de toutes les transactions réalisées depuis la dernière sauvegarde complète, que vous pouvez appliquer à la base de données.
- Minimiser l'objectif de délai de récupération (RTO) : Le RTO correspond au délai nécessaire à la récupération d'une base de données en cas d'événement destructeur. Une fois que vous avez configuré les sauvegardes binaires et l'archivage des journaux, le temps nécessaire à la récupération de la base de données peut être minimal.
- Résoudre un bug de corruption des données ou une erreur d'administration : Si une version de code entraîne une corruption catastrophique des données ou si une erreur irrécupérable est commise lors d'une opération de maintenance de routine, vous pouvez effectuer la récupération à un état antérieur à la date de l'événement.
Certaines architectures applicatives, telles qu'une architecture de microservices, peuvent reposer sur des bases de données parallèles, qui nécessitent alors des récupérations indépendantes. Par exemple, une application de vente au détail peut héberger les données client dans une base de données et les détails des commandes et informations d'inventaire dans d'autres bases de données distinctes. Suivant l'état général des données, une, deux ou la totalité des bases de données peuvent nécessiter une récupération en parallèle.
La récupération PITR n'est pas adaptée aux scénarios suivants :
- Le RPO est élevé : Si votre stratégie de reprise après sinistre peut tolérer la perte des transactions reçues après le dernier instantané, vous pouvez vous épargner des étapes supplémentaires et vous focaliser sur la réduction du délai de récupération de vos données.
- Une récupération complète de la base de données est nécessaire : Si votre objectif est de récupérer la transaction la plus récente, votre cible de récupération est l'horodatage de la dernière transaction persistante. Ce scénario est un cas spécifique de récupération PITR, mais d'un point de vue sémantique, cet objectif est désigné par le terme de récupération complète.
Considérations sur les performances
La procédure d'archivage soumet votre serveur de base de données à une charge d'E/S supplémentaire. Cette charge supplémentaire dépend des caractéristiques de votre charge de travail, car elle est proportionnelle au volume de transactions d'écriture, de mise à jour et de suppression.
Si vous souhaitez réduire l'impact potentiel de l'activité d'archivage WAL en termes d'E/S sur votre base de données principale, vous pouvez réaliser les archives WAL périodiques à l'aide d'une instance dupliquée en lecture seule.
Cette configuration isole la base de données principale des activités d'E/S par lot liées au transfert des fichiers WAL. Les transactions destinées à l'instance dupliquée en lecture seule sont transmises en un flux constant émanant de la base de données principale, ce qui réduit nettement l'impact sur le débit à l'état stable.
De plus, si votre topologie de base de données de production inclut déjà une instance dupliquée en lecture seule, cette configuration n'entraîne aucune charge supplémentaire, que ce soit en termes de gestion ou de coûts.
Architecture de référence
Le schéma suivant illustre l'architecture que vous allez mettre en œuvre dans ce tutoriel.
Dans ce tutoriel, vous allez créer une infrastructure cloud afin d'observer une récupération PITR utilisant les composants suivants :
- Un serveur de base de données PostgreSQL s'exécutant sur Compute Engine
- Cloud Storage pour le stockage des instantanés et des journaux de transactions
Le schéma suivant illustre les deux conteneurs Docker lancés sur la machine virtuelle (VM) de base de données PostgreSQL. Pour assurer la séparation des problèmes, le serveur de base de données s'exécute dans l'un des deux conteneurs et l'archiveur WAL, dans l'autre conteneur.
Ce diagramme montre comment les volumes Docker de chaque conteneur sont mappés sur des points d'installation Persistent Disk sur la VM hôte.
Configurer les variables d'environnement
Les scripts et commandes utilisés dans ce tutoriel reposent sur des variables d'environnement de shell.
Dans Cloud Shell, utilisez les commandes ci-dessous pour définir les variables d'environnement associées à votre projet, au nom de l'instance et à la base de données PostgreSQL de démonstration.
export PROJECT_ID=your-gcp-project export PG_INSTANCE_NAME=instance-pg-pitr export POSTGRES_PASSWORD=PasswordIsThis export POSTGRES_PITR_DEMO_DBNAME=pitr_demo
Remplacez l'élément suivant :
your-gcp-project
: nom du projet que vous avez créé pour ce tutorielPasswordIsThis
: mot de passe sécurisé de la base de données PostgreSQL
Définissez la variable d'environnement correspondant à la zone Google Cloud. Remplacez
choose-an-appropriate-zone
par une zone Google Cloud.export ZONE=choose-an-appropriate-zone export REGION=${ZONE%-[a-z]}
Définissez la variable d'environnement correspondant au sous-réseau VPC (Virtual Private Cloud) par défaut pour la région associée à votre zone :
export SUBNETWORK_URI=$(gcloud compute networks subnets \ describe default --format=json --region=$REGION | \ jq --raw-output '.ipCidrRange')
Définissez la variable d'environnement associée au bucket Cloud Storage. Remplacez
archive-bucket
par le nom unique du bucket Cloud Storage devant héberger les journaux WAL.export ARCHIVE_BUCKET=archive-bucket
Créer un bucket Cloud Storage
Créez un bucket Cloud Storage servant à archiver les fichiers WAL à partir de la base de données PostgreSQL :
gcloud storage buckets create gs://${ARCHIVE_BUCKET}
Autoriser l'accès aux instances dotées d'adresses IP privées
Pour les instances utilisées dans ce tutoriel, comme dans de nombreux cas d'utilisation de production, il n'est pas nécessaire que les instances de VM obtiennent des adresses IP publiques. Cependant, les instances ont besoin d'avoir accès à l'Internet public pour en extraire les exemples d'images de conteneurs, et vous-même devez pouvoir vous y connecter à l'aide d'une interface système sécurisée. Vous configurez une passerelle NAT (Network Address Translation) ainsi qu'un proxy IAP (Identity-Aware Proxy) pour le transfert TCP.
Créer une passerelle NAT
Comme les instances de VM que vous créez n'ont pas d'adresses IP publiques, vous devez créer une passerelle NAT afin qu'elles puissent extraire des images de conteneurs à partir de Docker Hub.
Dans Cloud Shell, créez un routeur Cloud :
export CLOUD_ROUTER_NAME=${PROJECT_ID}-nat-router gloud compute routers create $CLOUD_ROUTER_NAME \ --network=default --region=$REGION
Créez la passerelle NAT :
gcloud compute routers nats create ${PROJECT_ID}-nat-gateway \ --region=$REGION \ --router=$CLOUD_ROUTER_NAME \ --auto-allocate-nat-external-ips \ --nat-all-subnet-ip-ranges
Configurer IAP pour le transfert TCP
IAP contrôle l'accès à vos applications cloud et à vos VM exécutées sur Google Cloud. IAP vérifie l'identité de l'utilisateur et le contexte de la requête pour déterminer si cet utilisateur est autorisé à accéder à une VM donnée.
Dans Cloud Shell, autorisez le trafic émanant du bloc réseau de transfert TCP vers les instances de votre projet :
export IAP_FORWARDING_CIDR=35.235.240.0/20 gcloud compute --project=$PROJECT_ID firewall-rules create \ cloud-iap-tcp-forwarding --direction=INGRESS \ --priority=1000 --network=default \ --action=ALLOW --rules=all \ --source-ranges=$IAP_FORWARDING_CIDR
Pour vous connecter à l'aide d'un tunnel de transfert TCP, ajoutez une liaison de stratégie de gestion de l'authentification et des accès (IAM). Remplacez
your-email-address
par l'adresse e-mail que vous utilisez pour vous connecter à la console Google Cloud.export GRANT_EMAIL_ADDRESS=your-email-address gcloud projects add-iam-policy-binding $PROJECT_ID \ --member=user:$GRANT_EMAIL_ADDRESS \ --role=roles/iap.tunnelResourceAccessor
Créer l'infrastructure de base de données PostgreSQL
Dans Cloud Shell, clonez le dépôt source contenant les scripts de configuration puis, dans l'interface système, déplacez le contexte vers le dépôt local :
git clone https://github.com/GoogleCloudPlatform/gcs-postgresql-recovery-tutorial cd gcs-postgresql-recovery-tutorial
Pour créer et configurer l'instance de VM de base de données, exécutez le script suivant :
cd bin ./create_postgres_instance.sh
Pour ce tutoriel, ce script démarre une instance de VM située dans la zone choisie, et dotée du système d'exploitation optimisé pour les conteneurs et de deux nouveaux disques persistants associés. Dans ce contexte, vous pouvez ignorer le message d'avertissement renvoyé par l'API au sujet des performances d'E/S médiocres et dû au fait que les scripts créent des disques persistants de petite taille.
Examiner la configuration de cloud-init
Cloud-init est un package multidistribution qui initialise une instance cloud.
Examinez l'exemple de code cloud-init suivant :
Dans le cadre de ce tutoriel, cloud-init est utilisé pour effectuer les opérations suivantes :
- Créer deux périphériques de stockage de blocs à base de disques persistants
- Créer les systèmes de fichiers sur ces deux périphériques, un pour les données et un autre pour les journaux d'archive
- Installer les périphériques sur des points d'installation logiques de l'instance de VM qui sont partagés avec les conteneurs Docker
- Créer, puis lancer un service
systemd
(postgres.service
), qui démarre un conteneur Docker PostgreSQL comportant les éléments suivants :- Les disques persistants installés en tant que volumes
- Le port PostgreSQL (
5432
) publié sur la VM hôte
- Créer un fichier
/var/tmp/docker-entrypoint-initdb.d/init-pitr-demo-db.sql
afin de générer un ensemble simple de tables dans une base de données et un schéma de démonstration - Créer, puis lancer un deuxième service
systemd
(wal_archive.service
) qui exécute un conteneur Docker Google Cloud CLI avec les disques WAL installés en tant que volume (Ce service sauvegarde les fichiers WAL archivés dans Cloud Storage.) - Créer, activer, puis démarrer un minuteur
systemd
(wal_archive.timer
) qui exécute régulièrement le servicewal_archive.service
- Vérifier que le port PostgreSQL (
5432
) est ouvert pour le sous-réseau VPC afin que le générateur de transactions puisse atteindre le port de la base de données
Modifier la configuration de l'instance de base de données
Le serveur de base de données est en cours d'exécution, mais vous devez configurer l'accès au réseau et démarrer la procédure d'archivage WAL.
Se connecter à l'instance de VM de base de données
Dans Google Cloud Console, accédez à la page Instances de VM.
Pour ouvrir une interface système de terminal, cliquez sur l'élément SSH qui figure à côté de l'instance
instance-pg-pitr
que vous avez créée.Dans l'interface système du terminal, vérifiez que le conteneur Docker a bien démarré :
docker ps
Le résultat ressemble à ce qui suit :
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8bb65d8c1197 postgres:11-alpine "docker-entrypoint.s…" About a minute ago Up About a minute postgres-db
Si le conteneur n'est pas encore en cours d'exécution, patientez quelques instants, puis utilisez la même commande pour vérifier à nouveau.
Autoriser les connexions réseau entrantes vers la base de données
Dans l'interface système du terminal de l'instance
instance-pg-pitr
, ouvrez le fichier de configuration de l'authentification basée sur l'hôte pour PostgreSQL afin d'en modifier le contenu :sudoedit /mnt/disks/data/pgdata/pg_hba.conf
Pour supprimer l'accès par défaut à la base de données (accordé à toute adresse IP), ajoutez la ligne suivante à la fin du fichier, en veillant à ajouter le caractère
#
en début de ligne. La ligne figurant dans le fichier se présente comme suit :#host all all all md5
Pour autoriser les connexions protégées par un mot de passe émanant des hôtes du bloc CIDR
10.0.0.0/8
, ajoutez la ligne suivante à la fin du fichier :host all all 10.0.0.0/8 md5
Cette entrée active la connectivité à partir du sous-réseau VPC où sera ultérieurement créé le générateur de transactions.
Enregistrez le fichier, puis fermez-le.
Configurer l'archivage WAL
Dans l'interface système du terminal de l'instance
instance-pg-pitr
, modifiez le fichierpostgresql.conf
:sudoedit /mnt/disks/data/pgdata/postgresql.conf
Remplacez les lignes
archive_mode
,archive_command
etarchive_timeout
existantes, qui sont commentées, par les lignes suivantes :archive_mode=on archive_command = '( ARCHIVE_PATH=/var/lib/postgresql/wal/pg_wal_archive; test ! -f $ARCHIVE_PATH/%f && cp %p $ARCHIVE_PATH/%f.cp && mv $ARCHIVE_PATH/%f.cp $ARCHIVE_PATH/%f ) ' archive_timeout = 120
Une fois que vous avez remplacé les lignes du fichier modifié, celui-ci ressemble à l'extrait de code suivant :
Enregistrez le fichier, puis fermez-le.
Appliquer les modifications de configuration et les vérifier
Dans l'interface système du terminal de l'instance
instance-pg-pitr
, redémarrez le conteneur pour appliquer les modifications :sudo systemctl restart postgres
Vérifiez l'existence de fichiers segments WAL :
sudo ls -l /mnt/disks/wal/pg_wal
Le résultat ressemble à ce qui suit :
total 16388 -rw------- 1 postgres 70 16777216 Sep 5 23:07 000000010000000000000001 drwx------ 2 postgres 70 4096 Sep 5 23:05 archive_status
Vérifiez la connectivité réseau vers la base de données :
export LOCAL_IP=127.0.0.1 docker exec postgres-db psql -w --host=$LOCAL_IP \ --command='SELECT 1'
Le résultat ressemble à ce qui suit :
?column? ---------- 1 (1 row)
Fermez la connexion SSH à l'instance.
Démarrer le générateur de transactions afin de remplir la base de données
Les étapes ci-dessous démarrent un programme Go qui génère des transactions pour ce tutoriel. Le programme s'exécute dans un conteneur hébergé sur une instance de VM.
L'image du conteneur est créée et prête à l'emploi. Elle est hébergée dans un projet associé à un registre Container Registry public.
Dans Cloud Shell, accédez au répertoire du générateur de transactions :
cd ~/gcs-postgresql-recovery-tutorial/bin
Définissez les variables d'environnement :
export TRANS_GEN_INSTANCE_NAME=instance-trans-gen export POSTGRES_HOST_IP=$(gcloud compute instances describe \ --format=json --zone=${ZONE} ${PG_INSTANCE_NAME} | \ jq --raw-output '.networkInterfaces[0].networkIP')
Pour exécuter le générateur de transactions, démarrez l'instance :
./run_trans_gen_instance.sh
Ignorez le message d'avertissement concernant le risque de performances d'E/S médiocres.
Attendez quelques instants, puis vérifiez que des transactions atteignent la base de données PostgreSQL :
gcloud compute ssh $PG_INSTANCE_NAME \ --tunnel-through-iap \ --zone=$ZONE \ --command="docker exec postgres-db psql \ --dbname=$POSTGRES_PITR_DEMO_DBNAME \ --command='SELECT COUNT(*) FROM pitr_db_schema.customer;'"
La sortie contient un nombre supérieur à 0 dès que des enregistrements sont insérés dans la base de données par le générateur de transactions :
count ------- 413 (1 row)
Configurer le planning de sauvegarde des instantanés binaires
Vous pouvez sauvegarder les disques persistants selon un planning donné et conserver ces sauvegardes pendant une durée définie dans la stratégie de ressources.
Créer la programmation des instantanés
Dans Cloud Shell, définissez les variables d'environnement suivantes :
export ZONE=zone-of-your-instance export SNAPSHOT_SCHEDULE_NAME=pg-disk-schedule export REGION=${ZONE%-[a-z]} export SNAPSHOT_WINDOW_START=$(TZ=":GMT" date "+%H:00") export SNAPSHOT_RETENTION_DAYS=2 export SNAPSHOT_FREQUENCY_HOURS=1
Remplacez zone-of-your-instance par la zone Google Cloud dans laquelle vous avez précédemment démarré la VM de base de données.
Créez la programmation d'instantanés :
gcloud compute resource-policies create snapshot-schedule \ $SNAPSHOT_SCHEDULE_NAME \ --region=$REGION \ --max-retention-days=$SNAPSHOT_RETENTION_DAYS \ --on-source-disk-delete=apply-retention-policy \ --hourly-schedule=$SNAPSHOT_FREQUENCY_HOURS \ --start-time=$SNAPSHOT_WINDOW_START \ --storage-location=$REGION
Associer la programmation d'instantanés aux disques
Lorsque vous avez exécuté le script de création d'instance, le volume de données et le volume WAL ont été créés sous la forme de deux disques persistants indépendants. Pour créer des instantanés de disques persistants selon un programme défini, vous devez associer une stratégie de ressources à chaque disque persistant. Dans le cadre de ce tutoriel, vous souhaitez que les instantanés de disque aient lieu simultanément. Vous devez donc utiliser la même stratégie pour les deux disques persistants associés à la VM Compute Engine.
Dans Cloud Shell, définissez les variables d'environnement suivantes :
export SNAPSHOT_SCHEDULE_NAME=pgdata-disk-schedule export PG_INSTANCE_NAME=instance-pg-pitr export ZONE=zone-of-your-instance
Associez la stratégie de programmation au disque persistant dédié aux données :
gcloud beta compute disks add-resource-policies ${PG_INSTANCE_NAME}-data \ --resource-policies $SNAPSHOT_SCHEDULE_NAME \ --zone $ZONE
Associez la stratégie de programmation au disque persistant dédié aux journaux WAL :
gcloud beta compute disks add-resource-policies ${PG_INSTANCE_NAME}-wal \ --resource-policies $SNAPSHOT_SCHEDULE_NAME \ --zone $ZONE
Exécuter manuellement un instantané
(Facultatif) Les instantanés programmés se produisent au cours de la fenêtre de programmation. Il est donc peu probable qu'un instantané soit pris immédiatement après la création du programme. Si vous ne souhaitez pas attendre l'exécution programmée, vous pouvez exécuter manuellement l'instantané initial.
Dans Cloud Shell, définissez les variables d'environnement suivantes :
export ZONE=zone-of-your-instance export PG_INSTANCE_NAME=instance-pg-pitr export REGION=${ZONE%-[a-z]}
Créez un instantané des deux disques persistants de l'instance PostgreSQL :
gcloud compute disks snapshot \ ${PG_INSTANCE_NAME}-data ${PG_INSTANCE_NAME}-wal \ --snapshot-names=${PG_INSTANCE_NAME}-data-`date+%s`,${PG_INSTANCE_NAME}-wal-`date +%s` \ --zone=$ZONE --storage-location=$REGION
Affichez les instantanés que vous venez de créer :
gcloud compute snapshots list
Le résultat ressemble à ce qui suit :
NAME DISK_SIZE_GB SRC_DISK STATUS instance-pg-pitr-data-1578339767 200 us-central1-f/disks/instance-pg-pitr-data READY instance-pg-pitr-wal-1578339767 100 us-central1-f/disks/instance-pg-pitr-wal READY
Effectuer une récupération PITR
Souvent, une récupération PITR est utilisée pour récupérer les données perdues en raison d'une erreur opérationnelle ou programmatique.
Dans cette section du tutoriel, vous allez mettre à jour une base de données pour simuler un incident de perte de données. Vous simulerez ensuite une réponse de type panique, avant de lancer une récupération au moment précis où la commande erronée a été exécutée.
S'assurer qu'une récupération PITR est possible
Avant d'effectuer une récupération PITR, vous devez laisser suffisamment de temps s'écouler pour que les éléments suivants s'exécutent :
- Les sauvegardes binaires (instantanés de disque)
- L'archivage WAL
Pour ce tutoriel, la valeur de archive_timeout
a été définie sur une durée anormalement faible de 120 secondes afin de forcer une rotation fréquente des fichiers WAL. Vous devez également attendre qu'un instantané de disque programmé au moins ait été exécuté ; une autre solution consiste à créer manuellement un instantané du disque.
Vérifiez qu'un instantané au moins a été exécuté :
Dans la console Google Cloud, accédez à la page Instantanés.
Vérifiez qu'il existe au moins deux instantanés : un pour le volume de données et un autre pour le volume WAL, par exemple,
instance-pg-pitr--us-central1-a-20190805023535-i3hpw7kn
.
Vérifiez que les fichiers segments sont archivés dans Cloud Storage :
Dans la console Google Cloud, accédez à la page du Navigateur Cloud Storage.
Cliquez sur
archive-bucket
.
Endommager les données
Pour simuler une perte de données, ouvrez une interface de ligne de commande vers la base de données PostgreSQL et endommagez les données figurant dans la table remplie par le générateur de transactions.
Dans Google Cloud Console, accédez à la page Instances de VM.
Cliquez sur l'élément SSH correspondant à l'instance
instance-pg-pitr
.Dans le terminal SSH, exécutez l'interface PostgreSQL de type terminal dans le conteneur Docker :
docker exec -it postgres-db psql --dbname=pitr_demo
Envoyez dans l'interface système PostgreSQL une instruction LMD SQL visant à modifier une ligne de la table des clients et comportant une faute de frappe intentionnelle :
UPDATE pitr_db_schema.customer SET name = 'New Name for customer id=1'; WHERE id = 1;
Le résultat ressemble à ce qui suit :
UPDATE 999 pitr_demo=# WHERE id = 1; ERROR: syntax error at or near "WHERE" LINE 1: WHERE id = 1; ^
Dans cet exemple, l'erreur est due à un point-virgule superflu inséré avant la clause
WHERE
. Toutes les lignes de la base de données ont été mises à jour. Vous pouvez maintenant effectuer une récupération PITR afin de restaurer les lignes modifiées par l'instruction erronée.
Déterminer l'heure cible de la récupération
La première étape d'une récupération PITR consiste à déterminer l'heure cible de la récupération. Cette heure est déterminée grâce à un examen de vos données visant à identifier un point légèrement antérieur à l'événement ayant causé les dégâts.
Dans l'interface système du terminal de l'instance
instance-pg-pitr
, obtenez l'horodatage maximal des lignes endommagées :SELECT MAX(create_timestamp)::timestamptz FROM pitr_db_schema.customer WHERE name = 'New Name for customer id=1';
Le résultat ressemble à ce qui suit :
max . ------------------------------- 2019-08-05 18:14:58.226511+00 (1 row)
Dans une base de données de production, la requête permettant de déterminer la cible de récupération est plus complexe. C'est plus particulièrement le cas lorsque la table concernée est volumineuse et que la colonne indicative n'est pas indexée.
Copiez le résultat : vous utiliserez la valeur renvoyée par cette requête à l'étape suivante.
Récupérer la base de données
Dans le cadre de ce tutoriel, un script de récupération automatise la récupération PITR. Nous vous recommandons de mettre en place une procédure automatisée de récupération de la base de données et de la tester régulièrement.
Dans Cloud Shell, déplacez le répertoire de travail courant vers l'emplacement du script de récupération :
cd ~/gcs-postgresql-recovery-tutorial/bin
Définissez les variables d'environnement requises par le script. Remplacez
YYYY-MM-DD HH:MM:SS.999999+00
par le résultat de la requête, que vous avez copié précédemment.export PROJECT_ID=$(gcloud config get-value project) export PG_INSTANCE_NAME=instance-pg-pitr export POSTGRES_PASSWORD=PasswordIsThis export PG_INSTANCE_NAME=instance-pg-pitr export RECOVER_BUCKET=archive-bucket export PIT_RECOVERY_TARGET="YYYY-MM-DD HH:MM:SS.999999+00" export ZONE=zone-of-your-instance
Exécutez le script de récupération :
./recover_to_point_in_time.sh
Comprendre le script de récupération
Cette section fournit des détails sur les paramètres d'entrée du script et les étapes qui le constituent.
Le script nécessite la définition des variables d'environnement suivantes :
PIT_RECOVERY_TARGET
: heure cible pour la récupérationPROJECT_ID
: projet contenant l'instancePG_INSTANCE_NAME
ZONE
: zone où se trouve l'instancePG_INSTANCE_NAME
PG_INSTANCE_NAME
: instance sur laquelle s'exécute l'instance PostgreSQL productionRECOVER_BUCKET
: bucket Cloud Storage où sont archivés les fichiers segments WALPOSTGRES_PASSWORD
: mot de passe pour l'utilisateur de la base de données PostgreSQL
Le script exécute les tâches suivantes :
- Il détermine les instantanés de disque les plus récents en fonction de la date et de l'heure de la cible de récupération.
Il crée un fichier
cloud-init.yaml
transmis à une VM de stockage optimisée pour les conteneurs, qui exécute la base de données de récupération à un moment précis. Le fichiercloud-init.yaml
crée les fichiers de configuration et exécute un certain nombre de commandes système afin d'établir l'environnement suivant :- Un conteneur
gcsfuse
qui installe en tant que volume le bucket d'archivage des fichiers segments WAL, qui est ensuite mis à la disposition de l'hôte à travers un montage lié Docker. Un conteneur
postgres-db
dans lequel le moteur de base de données exécute les éléments suivants :- Le système de fichiers hôte auquel les disques persistants sont associés en tant que volumes.
- Le système de fichiers hôte auquel le bucket Cloud Storage est associé en tant que volume.
Un fichier de récupération
recovery.conf
hébergé dans le répertoire de données PostgreSQL et comportant les informations suivantes :- La date cible.
- La commande
restore
: commande de copie paramétrée, utilisée par la base de données pour copier les fichiers segments WAL requis à partir du système de fichiers d'archive.%f
est le fichier segment et%p
correspond au chemin utilisé par la base de données pour le traitement des fichiers lors de la récupération.
Les paramètres
archive_
sont commentés dans le fichier de paramètrespostgresql.conf
afin d'éviter de corrompre le répertoire d'archives WAL.
- Un conteneur
Il démarre l'instance de récupération PITR avec les informations suivantes :
- Un nom créé en combinant la variable d'environnement
$PG_INSTANCE_NAME
avec les valeurs alphanumériques de la variable d'environnement$PIT_RECOVERY_TARGET
. - Des disques persistants créés à partir des instantanés de disque identifiés précédemment.
- Un nom créé en combinant la variable d'environnement
Voici un exemple de fichier recovery.conf
:
restore_command = '(test -d /var/lib/postgresql/wal/pg_wal_recover && cp /var/lib/postgresql/wal/pg_wal_recover/%f %p ) '
recovery_target_time='YYYY-MM-DD HH:MM:SS UTC'
recovery_target_inclusive=true
Valider la récupération
Dans Google Cloud Console, accédez à la page Instances de VM.
Cliquez sur l'élément SSH correspondant à l'instance
instance-pg-pitr-YYYYMMDDHHMMSS
.Dans le terminal SSH, exécutez l'interface PostgreSQL de type terminal dans le conteneur Docker :
docker exec -it postgres-db psql --dbname=pitr_demo
Si vous obtenez l'erreur suivante, attendez quelques instants que le conteneur PostgreSQL démarre, puis exécutez à nouveau la commande :
Error: No such container: postgres-db
Vérifiez les données figurant dans la table des clients :
SELECT * FROM pitr_db_schema.customer WHERE id > (SELECT MAX(id)-10 FROM pitr_db_schema.customer);
Le résultat ressemble à ce qui suit :
id | name | create_timestamp ------+---------------------------+---------------------------- 711 | customer_name_from_golang | 2019-12-06 18:03:51.229444 712 | customer_name_from_golang | 2019-12-06 18:03:52.531755 713 | customer_name_from_golang | 2019-12-06 18:03:53.555441 714 | customer_name_from_golang | 2019-12-06 18:03:54.581872 715 | customer_name_from_golang | 2019-12-06 18:03:55.607459 716 | customer_name_from_golang | 2019-12-06 18:03:56.633362 717 | customer_name_from_golang | 2019-12-06 18:03:57.658523 718 | customer_name_from_golang | 2019-12-06 18:03:58.685469 719 | customer_name_from_golang | 2019-12-06 18:03:59.706939
La colonne des noms présente une valeur créée par le générateur de transactions. L'horodatage de la dernière ligne est antérieur à la cible de récupération (que vous avez fournie au script de récupération dans une variable d'environnement). Suivant le nombre d'enregistrements à récupérer, vous devrez peut-être patienter quelques instants pour que la totalité des lignes soient mises à jour.
Effectuer un nettoyage
Le moyen le plus simple d'éviter la facturation consiste à supprimer le projet Google Cloud que vous avez créé pour le tutoriel. Vous pouvez également supprimer les différentes ressources.
Supprimer le projet
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
Étape suivante
- Découvrez-en davantage sur le système d'exploitation optimisé pour les conteneurs.
- Apprenez-en plus sur cloud-init.
- Renseignez-vous sur Cloud Storage Fuse.
- Découvrez des architectures de référence, des schémas et des bonnes pratiques concernant Google Cloud. Consultez notre Centre d'architecture cloud. .