In dieser Anleitung erstellen Sie eine Demonstrationsdatenbank und führen eine Anwendungsarbeitslast aus. Anschließend konfigurieren Sie die Archivierungs- und Sicherungsprozesse. Als Nächstes erfahren Sie, wie Sie die Sicherungs-, Archivierungs- und Wiederherstellungsprozesse prüfen. Abschließend erfahren Sie, wie Sie die Datenbank zu einem bestimmten Zeitpunkt wiederherstellen.
Diese Anleitung richtet sich an Datenbankadministratoren, Systembetreiber, DevOps-Experten und Cloud-Architekten, die eine Sicherungs- und Wiederherstellungsstrategie für PostgreSQL-Datenbanken konfigurieren möchten.
In dieser Anleitung wird davon ausgegangen, dass Sie mit Docker-Containern sowie mit Linux-Befehlen, PostgreSQL-Datenbankmodulen und Compute Engine vertraut sind.
Ziele
- Einen Sicherungs- und Archivierungsprozess einrichten.
- Eine PITR ausführen.
- Ihre Datensicherung überwachen.
- Eine Wiederherstellung prüfen.
Kosten
In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:
Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen.
Nach Abschluss der in diesem Dokument beschriebenen Aufgaben können Sie weitere Kosten vermeiden, indem Sie die erstellten Ressourcen löschen. Weitere Informationen finden Sie unter Bereinigen.
Vorbereitung
- 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.
Konzepte
Lesen Sie die folgenden PostgreSQL-Konzepte, bevor Sie mit der Anleitung beginnen:
- Kontinuierliche Archivierung: Wenn die Datenbank kontinuierlich sequenzielle Transaktionen in einer Datei speichert.
- Write-Ahead-Log (WAL): Änderungen an Datendateien werden im WAL aufgezeichnet, bevor sie an der Datei vorgenommen werden.
- WAL-Eintrag: Jede auf die Datenbank angewendete Transaktion wird formatiert und als WAL-Eintrag gespeichert.
- Segmentdateien: Segmentdateien haben kontinuierlich ansteigende Dateinamen und enthalten so viele WAL-Datensätze wie möglich. Die Dateigröße ist konfigurierbar und beträgt standardmäßig 16 MiB. Sie können eine höhere Größe auswählen, wenn Sie umfangreiche Transaktionen oder eine große Anzahl von Transaktionen erwarten, um die Gesamtzahl der erstellten Segmentdateien zu verringern und die Dateiverwaltung zu reduzieren.
Weitere Informationen finden Sie unter Reliability and the Write-Ahead Log.
Das folgende Diagramm zeigt, wie WALs in zwei Phasen beibehalten werden.
Im vorherigen Diagramm besteht die erste Phase von persistenten WALs darin, dass das Datenbankmodul Schreibvorgänge im WAL-Puffer gleichzeitig mit dem Schreibvorgang in eine Tabelle aufzeichnet. Wenn die Transaktion festgelegt wird, wird der WAL-Puffer in der zweiten Phase auf das Laufwerk geschrieben (geleert), wobei ein Anfügen an die WAL-Segmentdatei erfolgt.
PITR auswählen
Eine PITR eignet sich für folgende Szenarien:
- Recovery Point Objective (RPO) minimieren. Das RPO ist die maximale Zeit des Datenverlusts, die geduldet wird, bevor er sich erheblich auf die Geschäftsprozesse auswirkt. Durch das Speichern aller Transaktionen in den WALs zwischen Sicherungs-Snapshots wird die Menge der verlorenen Daten drastisch reduziert, da die Transaktionen seit der letzten vollständigen Sicherung auf die Datenbank angewendet werden.
- Recovery Time Objective (RTO) minimieren. Das RTO ist die Zeit, die für die Wiederherstellung einer Datenbank erforderlich ist, wenn eine Datei beschädigt wird. Nachdem Sie binäre Sicherungen und die Logarchivierung eingerichtet haben, kann die Wiederherstellungszeit der Datenbank minimal sein.
- Datenkorruptionsfehler oder administrativen Fehler beheben. Wenn ein Code-Release eine schwerwiegende Datenbeschädigung verursacht oder bei der Routinewartung ein nicht behebbarer Fehler auftritt, können Sie die Wiederherstellung bis zu diesem Zeitpunkt durchführen.
In einigen Anwendungsarchitekturen wie einer Mikrodienstarchitektur können parallele Datenbanken vorhanden sein, die unabhängige Wiederherstellungen erfordern. Eine Einzelhandelsanwendung kann beispielsweise Kundendaten in einer Datenbank und Details zu Einzelhandelsaufträgen und Inventardaten in anderen Datenbanken enthalten. Abhängig vom Gesamtstatus der Daten müssen eine, zwei oder alle Datenbanken parallel wiederhergestellt werden.
Eine PITR ist in folgenden Szenarien nicht geeignet:
- RPO ist groß. Wenn Ihre Richtlinie zur Notfallwiederherstellung den Verlust von Transaktionen, die nach dem letzten Snapshot eingegangen sind, zulässt, können Sie zusätzliche Schritte vermeiden und sich auf die Wiederherstellung Ihrer Daten konzentrieren.
- Eine vollständige Datenbankwiederherstellung ist erforderlich. Wenn Sie die letzte Transaktion wiederherstellen möchten, ist Ihr Wiederherstellungsziel der Zeitstempel der letzten persistenten Transaktion. Dieses Szenario ist ein spezifischer Fall von PITR. Dieses Ziel wird jedoch semantisch als vollständige Wiederherstellung bezeichnet.
Hinweise zur Leistung
Durch die Archivierung wird Ihr Datenbankserver zusätzlich mit E/A belastet. Die zusätzliche Last hängt von den Eigenschaften Ihrer Arbeitslast ab, da sie dem Transaktionsvolumen beim Schreiben, Aktualisieren und Löschen entspricht.
Sie Können die E/A-Auswirkungen reduzieren, die die WAL-Archivaktivität auf Ihre primäre Datenbank haben kann. Führen Sie dazu die regelmäßigen WAL-Archive mit einem schreibgeschützten Replikat aus.
Durch diese Konfiguration wird die primäre Datenbank von den Batch-orientierten E/A-Aktivitäten für die Übertragung der WAL-Dateien isoliert. Transaktionen, die für das schreibgeschützte Replikat bestimmt sind, werden in einem konstanten Stream von der primären Datenbank übertragen, was sich deutlich auf den Durchsatz im stationären Zustand auswirkt.
Wenn Ihre Produktionsdatenbanktopologie bereits ein schreibgeschütztes Replikat enthält, verursacht diese Konfiguration keine zusätzliche Belastung für Verwaltung, Preis oder andere.
Referenzarchitektur
Das folgende Diagramm zeigt die Architektur, die Sie in dieser Anleitung implementieren.
In dieser Anleitung erstellen Sie eine Cloud-Infrastruktur, um eine PITR zu beobachten, die die folgenden Komponenten verwendet:
- Ein PostgreSQL-Datenbankserver, der auf Compute Engine ausgeführt wird.
- Cloud Storage zum Speichern von Snapshots und Transaktionslogs.
Das folgende Diagramm zeigt die beiden Docker-Container, die auf der PostgreSQL-Datenbank-VM gestartet werden. Als Trennung von Belangen wird der Datenbankserver in einem der Container ausgeführt und die WAL-Archivierung im anderen Container.
Dieses Diagramm zeigt, wie die Docker-Volumes in jedem Container den Bereitstellungspunkten von Persistent Disk auf der Host-VM zugeordnet werden.
Umgebungsvariablen einrichten
Die in dieser Anleitung verwendeten Skripts und Befehle basieren auf Shell-Umgebungsvariablen.
Legen Sie in Cloud Shell Umgebungsvariablen für Ihr Projekt, den Instanznamen und die PostgreSQL-Demonstrationsdatenbank fest.
export PROJECT_ID=your-gcp-project export PG_INSTANCE_NAME=instance-pg-pitr export POSTGRES_PASSWORD=PasswordIsThis export POSTGRES_PITR_DEMO_DBNAME=pitr_demo
Dabei gilt:
your-gcp-project
: Der Name des Projekts, das Sie für diese Anleitung erstellt haben.PasswordIsThis
: Ein sicheres Passwort für die PostgreSQL-Datenbank.
Legen Sie die Umgebungsvariable für die Google Cloud-Zone fest. Ersetzen Sie
choose-an-appropriate-zone
durch eine Google Cloud-Zone.export ZONE=choose-an-appropriate-zone export REGION=${ZONE%-[a-z]}
Legen Sie die Umgebungsvariable für das Standardsubnetz Virtual Private Cloud (VPC) für die Region Ihrer Zone fest:
export SUBNETWORK_URI=$(gcloud compute networks subnets \ describe default --format=json --region=$REGION | \ jq --raw-output '.ipCidrRange')
Legen Sie die Umgebungsvariable für den Cloud Storage-Bucket fest. Ersetzen Sie
archive-bucket
durch einen eindeutigen Namen für den Cloud Storage-Bucket, in dem WALs gespeichert werden.export ARCHIVE_BUCKET=archive-bucket
Cloud Storage-Bucket erstellen
Erstellen Sie einen Cloud Storage-Bucket, um die WAL-Dateien aus der PostgreSQL-Datenbank zu archivieren:
gcloud storage buckets create gs://${ARCHIVE_BUCKET}
Zugriff auf private IP-Adressinstanzen zulassen
Für die in dieser Anleitung verwendeten Instanzen müssen die VM-Instanzen wie in vielen Produktionsanwendungsfällen keine öffentlichen IP-Adressen abrufen. Die Instanzen benötigen jedoch Zugriff auf das öffentliche Internet, um die Beispiel-Container-Images abzurufen. Sie benötigen auch Zugriff, um eine Verbindung über eine sichere Shell herzustellen. Sie konfigurieren ein NAT-Gateway (Network Address Translation) und den Identity-Aware Proxy (IAP) für die TCP-Weiterleitung.
NAT-Gateway erstellen
Da die von Ihnen erstellten VM-Instanzen keine öffentlichen IP-Adressen haben, erstellen Sie ein NAT-Gateway. Damit können die Instanzen Container-Images aus dem Docker Hub abrufen.
Erstellen Sie in Cloud Shell einen Cloud Router:
export CLOUD_ROUTER_NAME=${PROJECT_ID}-nat-router gloud compute routers create $CLOUD_ROUTER_NAME \ --network=default --region=$REGION
Erstellen Sie das NAT-Gateway:
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
IAP für die TCP-Weiterleitung konfigurieren
IAP steuert den Zugriff auf Ihre Cloud-Anwendungen und VMs, die in Google Cloud ausgeführt werden. IAP prüft die Nutzeridentität und den Kontext der Anfrage, um zu bestimmen, ob ein Nutzer auf eine VM zugreifen darf.
Lassen Sie in Cloud Shell Traffic vom TCP-Weiterleitungsnetzblock zu den Instanzen in Ihrem Projekt zu:
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
Wenn Sie eine Verbindung über einen TCP-Weiterleitungstunnel herstellen möchten, fügen Sie eine Richtlinienbindung für Identity and Access Management (IAM) hinzu. Ersetzen Sie
your-email-address
durch die E-Mail-Adresse, mit der Sie sich bei der Google Cloud Console anmelden.export GRANT_EMAIL_ADDRESS=your-email-address gcloud projects add-iam-policy-binding $PROJECT_ID \ --member=user:$GRANT_EMAIL_ADDRESS \ --role=roles/iap.tunnelResourceAccessor
PostgreSQL-Datenbankinfrastruktur erstellen
Klonen Sie in Cloud Shell das Quell-Repository, das die Konfigurationsskripts enthält, und ändern Sie den Shell-Kontext in das lokale Repository:
git clone https://github.com/GoogleCloudPlatform/gcs-postgresql-recovery-tutorial cd gcs-postgresql-recovery-tutorial
Führen Sie das folgende Skript aus, um die Datenbank-VM-Instanz zu erstellen und zu konfigurieren:
cd bin ./create_postgres_instance.sh
Für diese Anleitung startet dieses Skript eine VM-Instanz in der ausgewählten Zone mit dem Container-Optimized OS und zwei neuen angehängten nichtflüchtigen Speichern. In diesem Fall können Sie die von der API zurückgegebene Warnmeldung zu schlechter E/A-Leistung ignorieren, da die Skripts kleine nichtflüchtige Speicher erstellen.
Cloud-init-Konfiguration prüfen
Cloud-init ist ein Multi-Distributionspaket, das eine Cloud-Instanz initialisiert.
Sehen Sie sich das folgende cloud-init-Codebeispiel an:
In dieser Anleitung wird "cloud-init" für Folgendes verwendet:
- Erstellen von zwei Blockspeichergeräten für Persistent Disk.
- Erstellen der Dateisysteme auf den beiden Geräten: eines für die Daten und eines für die Archivlogs.
- Bereitstellen der Geräte an logischen Bereitstellungspunkten auf der VM-Instanz, die für die Docker-Container freigegeben sind.
- Erstellen und Starten eines
systemd
-Dienstes (postgres.service
), der einen PostgreSQL-Docker-Container so startet:- Die nichtflüchtigen Speicher, die als Volumes bereitgestellt wurden.
- Der PostgreSQL-Port (
5432
), der auf dem VM-Host veröffentlicht wurde.
- Erstellen einer
/var/tmp/docker-entrypoint-initdb.d/init-pitr-demo-db.sql
-Datei, um einen einfachen Satz von Tabellen in einer Demonstrationsdatenbank und einem Schema zu erstellen. - Erstellen und Starten eines zweiten
systemd
-Dienstes (wal_archive.service
), der einen Docker-Container des Google Cloud CLI mit den als Volume bereitgestellten WAL-Laufwerken ausführt. Dieser Dienst sichert archivierte WAL-Dateien in Cloud Storage. - Erstellen, Aktivieren und Starten eines
systemd
-Timers (wal_archive.timer
), der denwal_archive.service
regelmäßig ausführt. - Darauf achten, dass der PostgreSQL-Port (
5432
) für das VPC-Subnetz geöffnet ist, damit der Transaktionsgenerator den Datenbankport erreichen kann.
Konfiguration der Datenbankinstanz ändern
Der Datenbankserver wird ausgeführt, aber Sie müssen den Netzwerkzugriff konfigurieren und den WAL-Archivierungsprozess starten.
Verbindung zu Datenbank-VM-Instanz herstellen
Rufen Sie in der Google Cloud Console die Seite VM-Instanzen auf.
Klicken Sie zum Öffnen einer Terminal-Shell neben der von Ihnen erstellten
instance-pg-pitr
-Instanz auf SSH.Prüfen Sie in der Terminal-Shell, ob der Docker-Container gestartet wurde:
docker ps
Die Ausgabe sieht etwa so aus:
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
Wenn der Container noch nicht ausgeführt wird, warten Sie einen Moment. Prüfen Sie die Ausführung dann mit demselben Befehl noch einmal.
Eingehende Netzwerkverbindungen zur Datenbank zulassen
Öffnen Sie in der Terminal-Shell der
instance-pg-pitr
-Instanz die Konfigurationsdatei für die hostbasierte PostgreSQL-Authentifizierung zur Bearbeitung:sudoedit /mnt/disks/data/pgdata/pg_hba.conf
Zum Entfernen des Standardzugriffs für alle IP-Adressen auf die Datenbank kommentieren Sie die folgende Zeile am Ende der Datei aus. Fügen Sie dazu am Anfang der Zeile
#
hinzu. Die Zeile in der Datei sieht in etwa so aus:#host all all all md5
Fügen Sie die folgende Zeile am Ende der Datei hinzu, um passwortgeschützte Verbindungen von Hosts im CIDR-Block
10.0.0.0/8
zuzulassen:host all all 10.0.0.0/8 md5
Dieser Eintrag aktiviert die Konnektivität vom VPC-Subnetz, in dem später der Transaktionsgenerator erstellt wird.
Speichern und schließen Sie die Datei.
WAL-Archivierung konfigurieren
Bearbeiten Sie in der Terminal-Shell der
instance-pg-pitr
-Instanz die Dateipostgresql.conf
:sudoedit /mnt/disks/data/pgdata/postgresql.conf
Ersetzen Sie die vorhandenen auskommentierten Zeilen
archive_mode
,archive_command
undarchive_timeout
durch folgende: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
Wenn Sie die Zeilen in der geänderten Datei ersetzen, ähnelt sie dem folgenden Code-Snippet:
Speichern und schließen Sie die Datei.
Konfigurationsänderungen anwenden und prüfen
Starten Sie den Container in der Terminal-Shell der
instance-pg-pitr
-Instanz neu, um die Änderungen zu übernehmen:sudo systemctl restart postgres
Prüfen Sie die WAL-Segmentdateien:
sudo ls -l /mnt/disks/wal/pg_wal
Die Ausgabe sieht etwa so aus:
total 16388 -rw------- 1 postgres 70 16777216 Sep 5 23:07 000000010000000000000001 drwx------ 2 postgres 70 4096 Sep 5 23:05 archive_status
Prüfen Sie die Netzwerkverbindung zur Datenbank:
export LOCAL_IP=127.0.0.1 docker exec postgres-db psql -w --host=$LOCAL_IP \ --command='SELECT 1'
Die Ausgabe sieht etwa so aus:
?column? ---------- 1 (1 row)
Trennen Sie die SSH-Verbindung zur Instanz.
Transaktionsgenerator zum Füllen der Datenbank starten
Mit den folgenden Schritten wird ein Go-Programm gestartet, das Transaktionen für diese Anleitung generiert. Das Programm wird in einem Container auf einer VM-Instanz ausgeführt.
Das Image für den Container wurde bereits in einem Projekt mit einer öffentlichen Container Registry erstellt und gehostet.
Wechseln Sie in Cloud Shell zum Verzeichnis des Transaktionsgenerators:
cd ~/gcs-postgresql-recovery-tutorial/bin
Legen Sie die Umgebungsvariablen fest:
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')
Starten Sie die Instanz, um den Transaktionsgenerator auszuführen:
./run_trans_gen_instance.sh
Ignorieren Sie die Warnmeldung zu schlechter E/A-Leistung.
Warten Sie einen Moment und prüfen Sie, ob die Transaktionen die PostgreSQL-Datenbank erreichen:
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;'"
Die Ausgabe enthält eine Anzahl größer als 0, wenn Datensätze vom Transaktionsgenerator zur Datenbank hinzugefügt werden:
count ------- 413 (1 row)
Sicherungszeitplan für binäre Snapshots konfigurieren
Sie können nichtflüchtige Speicher nach einem Zeitplan sichern und für eine in der Ressourcenrichtlinie definierte Zeit aufbewahren.
Snapshot-Zeitplan erstellen
Legen Sie in Cloud Shell Umgebungsvariablen fest:
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
Ersetzen Sie zone-of-your-instance durch die Google Cloud-Zone, in der Sie zuvor die Datenbank-VM gestartet haben.
Erstellen Sie den Snapshot-Zeitplan:
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
Snapshot-Zeitplan an Laufwerke anhängen
Wenn Sie das Skript zum Erstellen einer Instanz ausgeführt haben, wurden die Daten- und WAL-Volumes als zwei unabhängige nichtflüchtige Speicher erstellt. Zum Erstellen von Snapshots nichtflüchtiger Speicher nach einem definierten Zeitplan weisen Sie jedem nichtflüchtigen Speicher eine Ressourcenrichtlinie zu. In diesem Fall möchten Sie, dass die Laufwerk-Snapshots gleichzeitig erstellt werden, sodass Sie für beide nichtflüchtigen Speicher, die an die Compute Engine-VM angehängt sind, dieselbe Richtlinie verwenden.
Legen Sie in Cloud Shell Umgebungsvariablen fest:
export SNAPSHOT_SCHEDULE_NAME=pgdata-disk-schedule export PG_INSTANCE_NAME=instance-pg-pitr export ZONE=zone-of-your-instance
Hängen Sie die Zeitplanrichtlinie an den nichtflüchtigen Speicher an:
gcloud beta compute disks add-resource-policies ${PG_INSTANCE_NAME}-data \ --resource-policies $SNAPSHOT_SCHEDULE_NAME \ --zone $ZONE
Hängen Sie die Zeitplanrichtlinie an den nichtflüchtigen WAL-Speicher an:
gcloud beta compute disks add-resource-policies ${PG_INSTANCE_NAME}-wal \ --resource-policies $SNAPSHOT_SCHEDULE_NAME \ --zone $ZONE
Snapshot manuell ausführen
(Optional) Geplante Snapshots werden innerhalb des Zeitplanfensters erstellt. Daher ist es unwahrscheinlich, dass ein Snapshot sofort erstellt wird, wenn Sie den Zeitplan erstellt haben. Wenn Sie nicht auf den geplanten Snapshot warten möchten, können Sie den ersten Snapshot manuell ausführen.
Legen Sie in Cloud Shell Umgebungsvariablen fest:
export ZONE=zone-of-your-instance export PG_INSTANCE_NAME=instance-pg-pitr export REGION=${ZONE%-[a-z]}
Erstellen Sie einen Snapshot der beiden nichtflüchtigen Speicher der PostgreSQL-Instanz:
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
Rufen Sie die von Ihnen erstellten Snapshots auf:
gcloud compute snapshots list
Die Ausgabe sieht etwa so aus:
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
PITR ausführen
Eine PITR wird häufig verwendet, um Daten wiederherzustellen, die aufgrund eines betrieblichen oder programmatischen Fehlers verloren gegangen sind.
In diesem Abschnitt der Anleitung führen Sie eine Datenbankaktualisierung durch, um einen schwerwiegenden Datenverlust zu simulieren. Anschließend simulieren Sie eine Panikantwort, bevor Sie eine Wiederherstellung für den Zeitpunkt starten, bevor der fehlerhafte Befehl ausgegeben wurde.
Durchführung einer PITR gewährleisten
Bevor Sie eine PITR ausführen, müssen Sie genügend Zeit für die Ausführung folgender Aktionen einplanen:
- Die binären Sicherungen (Laufwerk-Snapshots)
- WAL-Archivierung
In dieser Anleitung wurde für archive_timeout
ein ungewöhnlich niedriger Wert von 120 Sekunden festgelegt, um eine häufige Rotation der WAL-Dateien zu erzwingen. Sie müssen auch warten, bis mindestens ein geplanter Laufwerk-Snapshot erstellt wurde, oder diesen manuell erstellen.
Prüfen Sie, ob mindestens ein Snapshot erstellt wurde:
Rufen Sie in der Google Cloud Console die Seite Snapshots auf.
Prüfen Sie, ob mindestens zwei Snapshots vorhanden sind: einer für das Daten-Volume und einer für das WAL-Volume, z. B.
instance-pg-pitr--us-central1-a-20190805023535-i3hpw7kn
.
Prüfen Sie, ob die Segmentdateien in Cloud Storage archiviert sind:
Wechseln Sie in der Google Cloud Console zum Cloud Storage-Browser.
Klicken Sie auf
archive-bucket
.
Daten beschädigen
Um einen schwerwiegenden Datenverlust zu simulieren, öffnen Sie eine Befehlszeilen-Shell für die PostgreSQL-Datenbank und beschädigen Sie die Daten in der vom Transaktionsgenerator gefüllten Tabelle.
Rufen Sie in der Google Cloud Console die Seite VM-Instanzen auf.
Klicken Sie für die Instanz
instance-pg-pitr
auf SSH.Führen Sie im SSH-Terminal das Terminal-basierte PostgreSQL-Frontend im Docker-Container aus:
docker exec -it postgres-db psql --dbname=pitr_demo
Zum Ändern einer Zeile in der Kundentabelle senden Sie eine SQL-DML-Anweisung mit einem absichtlichen Tippfehler in der PostgreSQL-Shell:
UPDATE pitr_db_schema.customer SET name = 'New Name for customer id=1'; WHERE id = 1;
Die Ausgabe sieht etwa so aus:
UPDATE 999 pitr_demo=# WHERE id = 1; ERROR: syntax error at or near "WHERE" LINE 1: WHERE id = 1; ^
Der Fehler wurde erzeugt, weil vor der
WHERE
-Klausel ein zusätzliches Semikolon eingefügt wurde. Alle Zeilen in der Datenbank wurden aktualisiert. Sie können jetzt eine PITR verwenden, um die Zeilen wiederherzustellen, die von der falschen Anweisung geändert wurden.
Zielzeit für die Wiederherstellung festlegen
Der erste Schritt in einer PITR besteht darin, die Zielzeit für die Wiederherstellung zu bestimmen. Diese Zeit wird ermittelt, indem Ihre Daten durchsucht werden, um einen Zeitpunkt kurz vor dem schädlichen Ereignis zu identifizieren.
Rufen Sie in der Terminal-Shell der
instance-pg-pitr
-Instanz den maximalen Zeitstempel der beschädigten Zeilen ab:SELECT MAX(create_timestamp)::timestamptz FROM pitr_db_schema.customer WHERE name = 'New Name for customer id=1';
Die Ausgabe sieht etwa so aus:
max . ------------------------------- 2019-08-05 18:14:58.226511+00 (1 row)
In einer Produktionsdatenbank ist die Abfrage zum Bestimmen des Wiederherstellungsziels komplexer, insbesondere in Fällen, in denen die betroffene Tabelle groß ist und die indikative Spalte nicht indexiert ist.
Kopieren Sie das Ergebnis. Sie verwenden im nächsten Schritt den von dieser Abfrage zurückgegebenen Wert.
Datenbank wiederherstellen
In dieser Anleitung automatisiert ein Wiederherstellungsskript die PITR. Wir empfehlen Ihnen, einen automatisierten Prozess zur Wiederherstellung der Datenbank zu verwenden und diesen Prozess regelmäßig zu testen.
Ändern Sie in Cloud Shell das aktuelle Arbeitsverzeichnis in den Speicherort des Wiederherstellungsskripts:
cd ~/gcs-postgresql-recovery-tutorial/bin
Legen Sie die erforderlichen Umgebungsvariablen für das Skript fest. Ersetzen Sie
YYYY-MM-DD HH:MM:SS.999999+00
durch die zuvor kopierte Abfrageausgabe.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
Führen Sie das Wiederherstellungsskript aus:
./recover_to_point_in_time.sh
Informationen zum Wiederherstellungsskript
Dieser Abschnitt enthält einige Details zu den Eingabeparametern und den vom Skript ausgeführten Schritten.
Für das Skript müssen die folgenden Umgebungsvariablen festgelegt sein:
PIT_RECOVERY_TARGET
: Die Zielzeit für die Wiederherstellung.PROJECT_ID
: Das Projekt, in dem sich diePG_INSTANCE_NAME
-Instanz befindet.ZONE
: Die Zone, in der sich diePG_INSTANCE_NAME
-Instanz befindet.PG_INSTANCE_NAME
: Die Instanz, auf der die PostgreSQL-Instanz production ausgeführt wird.RECOVER_BUCKET
: Der Cloud Storage-Bucket, in dem WAL-Segmentdateien archiviert werden.POSTGRES_PASSWORD
: Das Passwort für den PostgreSQL-Datenbanknutzer.
Das Skript führt die folgenden Schritte aus:
- Bestimmt die neuesten Laufwerk-Snapshots anhand des Datums und der Uhrzeit des Wiederherstellungsziels.
Erstellt eine
cloud-init.yaml
-Datei, die für eine containeroptimierte Storage-VM bereitgestellt wird, auf der die PITR-Datenbank ausgeführt wird. Die Dateicloud-init.yaml
erstellt Konfigurationsdateien und führt mehrere Systembefehle aus, um die folgende Umgebung einzurichten:- Ein
gcsfuse
-Container, der den WAL-Segment-Dateiarchiv-Bucket als Volume bereitstellt, das dann dem Host mit einem Docker-Bind-Mount bereitgestellt wird. Ein
postgres-db
-Container, in dem das Datenbankmodul Folgendes ausführt:- Das Hostdateisystem, an das die nichtflüchtigen Speicher als Volumes angehängt sind.
- Das Hostdateisystem, an das der Cloud Storage-Bucket als Volume angehängt ist.
Eine
recovery.conf
-Wiederherstellungsdatei im PostgreSQL-Datenverzeichnis mit den folgenden Informationen:- Dem Zieldatum.
- Dem Befehl
restore
: ein parametrisierter Kopierbefehl, mit dem die Datenbank WAL-Segmentdateien nach Bedarf aus dem Archivdateisystem kopiert.%f
ist die Segmentdatei und%p
der Pfad, den die Datenbank während der Wiederherstellung zur Verarbeitung von Dateien verwendet.
Die
archive_
-Einstellungen werden aus der Einstellungsdateipostgresql.conf
auskommentiert, um das WAL-Archivverzeichnis nicht zu beschädigen.
- Ein
Startet die PITR-Instanz mit den folgenden Informationen:
- Einem Namen, der durch Kombination der Umgebungsvariablen
$PG_INSTANCE_NAME
und der alphanumerischen Werte der Umgebungsvariablen$PIT_RECOVERY_TARGET
erstellt wird. - Nichtflüchtige Speicher, die aus den zuvor identifizierten Laufwerk-Snapshots erstellt wurden.
- Einem Namen, der durch Kombination der Umgebungsvariablen
Hier sehen Sie eine recovery.conf
-Beispieldatei:
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
Wiederherstellung prüfen
Rufen Sie in der Google Cloud Console die Seite VM-Instanzen auf.
Klicken Sie für die Instanz
instance-pg-pitr-YYYYMMDDHHMMSS
auf SSH.Führen Sie in den SSH-Terminals das Terminal-basierte Frontend von PostgreSQL im Docker-Container aus:
docker exec -it postgres-db psql --dbname=pitr_demo
Wenn Sie die folgende Fehlermeldung erhalten, warten Sie einen Moment, bis der PostgreSQL-Container gestartet ist. Führen Sie den Befehl dann noch einmal aus:
Error: No such container: postgres-db
Prüfen Sie die Daten in der Kundentabelle:
SELECT * FROM pitr_db_schema.customer WHERE id > (SELECT MAX(id)-10 FROM pitr_db_schema.customer);
Die Ausgabe sieht etwa so aus:
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
Der Name gibt den vom Transaktionsgenerator erstellten Wert an. Die letzte Zeile enthält einen Zeitstempel, der vor dem Wiederherstellungsziel liegt, das Sie dem Wiederherstellungsskript in einer Umgebungsvariablen bereitgestellt haben. Je nach Anzahl der wiederherzustellenden Datensätze müssen Sie möglicherweise einige Sekunden warten, bis alle Zeilen aktualisiert wurden.
Bereinigen
Am einfachsten können Sie die Abrechnung deaktivieren, wenn Sie das Google Cloud-Projekt löschen, das Sie für die Anleitung erstellt haben. Alternativ haben Sie die Möglichkeit, die einzelnen Ressourcen zu löschen.
Projekt löschen
- 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.
Nächste Schritte
- Container-Optimized OS
- cloud-init
- Cloud Storage Fuse
- Referenzarchitekturen, Diagramme und Best Practices zu Google Cloud kennenlernen. Weitere Informationen zu Cloud Architecture Center .