PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Validierung Ihrer PostgreSQL-Sicherungen auf Docker

Backups sind der lebenswichtige und wichtige Teil jedes Notfallwiederherstellungsplans, das Erstellen von Backups der Produktionsdatenbank ist auch ein grundlegender und wichtiger Teil der PostgreSQL-Administration. DBAs bestätigen jedoch nicht oft, dass diese Sicherungen zuverlässig sind.

Jede Organisation erstellt Backups von PostgreSQL-Datenbanken in unterschiedlicher Form, einige können ein (physisches) Dateisystem-Backup der PostgreSQL-Datenverzeichnisse erstellen (unter Verwendung von Tools wie Barman, PGBackRest), während andere möglicherweise nur logische Backups erstellen (unter Verwendung von pg_dump), und sogar andere können mit Tools wie EBS oder VMWare-Snapshots Snapshots auf Blockebene erstellen.

In diesem Blog zeigen wir Ihnen, wie Sie Ihr PostgreSQL-Backup validieren, indem Sie das Backup mit dem Tool pgBackRest zum Erstellen und Wiederherstellen des Backups in einem Docker-Container wiederherstellen. Wir gehen davon aus, dass Sie bereits über Kenntnisse im Umgang mit PostgreSQL, Docker und pgBackRest verfügen.

Warum sollten Sie Docker verwenden?

Docker vereinfacht die Automatisierung und vereinfacht auch die Integration unserer PostgreSQL-Backup-Validierungsaufgabe in CI/CD-Tools wie CircleCI, Travis, GitLab oder Jenkins. Die Verwendung von Docker vermeidet die Zeit und die Ressourcen, die wir aufwenden müssen, um die neue Umgebung zum Testen der Sicherung bereitzustellen.

Demo-Setup

Host 

Rolle

Installiert

Pakete 

Crontab

node-1 192.168.0.111

CentOS-7

Primäre Instanz von Posgresql-11.

Benutzer und Datenbank „pgbench“ erstellt und mit pgbench-Tabellen initialisiert.

postgresql-11, pgbackrest-2.15

Pgbench alle 5 Minuten ausführen, um die Arbeitslast zu simulieren.

node-2
192.168.0.112
CentOS-7

Testmaschine - wir werden unsere Docker-Validierung auf diesem Host ausführen.

docker-ce-18.06, pgbackrest-2.15

 

Knoten-3

192.168.0.113

CentOS-7

pgBackRest-Repository-Host

pgbackrest-2.15

pgbackrest ausführen, um alle 4 Stunden eine Incr-Sicherung zu erstellen

Diff-Backup jeden Tag

Wöchentliche vollständige Sicherung 

Damit pgbackrest funktioniert, habe ich einen passwortlosen SSH-Zugriff zwischen diesen Knoten eingerichtet.

Benutzer „postgres“ auf Knoten-1 und Knoten-2 können sich passwortlos bei Benutzer „pgbackrest“ auf Knoten-3 anmelden.

[[email protected] ~]$ sudo -u postgres ssh [email protected] uptime

 13:31:51 up  7:00, 1 user,  load average: 0.00, 0.01, 0.05

[[email protected] ~]$ sudo -u postgres ssh [email protected] uptime

 13:31:27 up  7:00, 1 user,  load average: 0.00, 0.01, 0.05

Benutzer „pgbackrest“ auf Knoten-3 kann sich passwortlos bei Benutzer „postgres“ auf Knoten-1 und Knoten-2 anmelden.

[[email protected] ~]$ sudo -u pgbackrest ssh [email protected] uptime 

 13:32:29 up  7:02, 1 user,  load average: 1.18, 0.83, 0.58

[[email protected] ~]$ sudo -u pgbackrest ssh [email protected] uptime 

 13:32:33 up  7:01, 1 user,  load average: 0.00, 0.01, 0.05

Überblick über die Backup-Validierung

Nachstehend finden Sie eine kurze Übersicht über die Schritte, die wir für unsere PostgreSQL-Backup-Validierung befolgen werden.

  1. Mit dem Befehl pgbackrest restore holen wir die neueste Sicherung vom pgBackRest-Repository-Host (Knoten 3) in das Verzeichnis /var/lib/pgsql/11/data der Testmaschine (Knoten 2)
  2. Während des Docker-Laufs mounten wir das Verzeichnis /var/lib/pgsql des Host-Rechners (Knoten-2) im Docker-Container und starten den postgres/postmaster-Daemon aus dem gemounteten Verzeichnis. Wir würden auch den Port 5432 vom Container für den Port 15432 des Hostcomputers verfügbar machen. 
  3. Sobald der Docker-Container gestartet wurde, verbinden wir uns über node-2:15432 mit der PostgreSQL-Datenbank und überprüfen, ob alle Tabellen und Zeilen wiederhergestellt sind. Wir würden auch die PostgreSQL-Protokolle überprüfen, um sicherzustellen, dass es während der Wiederherstellung keine ERROR-Meldung gibt und die Instanz auch den konsistenten Zustand erreicht hat.

Die meisten Backup-Validierungsschritte werden auf Host-Knoten-2 durchgeführt.

Erstellen des Docker-Images

Erstellen Sie auf node-2 Dockerfile und erstellen Sie das Docker-Image „postgresql:11“. In der Docker-Datei unten werden wir die folgenden Änderungen am Basis-Image von centos:7 anwenden.

  1. Installation von postgresql-11, pgbackrest und openssh-clients. Openssh-Clients werden für pgbackrest benötigt.
  2. Konfigurieren von pgbackrest - Wir benötigen die pgbackrest-Konfiguration im Image, um PITR zu testen, ohne die pgbackrest-Konfiguration würde der Wiederherstellungsbefehl fehlschlagen. Als Teil der pgbackrest-Konfiguration
    1. Wir fügen die Host-IP des pgbackrest-Repositorys (192.168.0.113) in der Konfigurationsdatei /etc/pgbackrest.conf hinzu.
    2. Wir brauchen auch passwortlosen SSH-Zugriff zwischen dem Docker-Container und dem pgbackrest-Repository-Host. Dazu kopiere ich SSH_PRIVATE_KEY, das ich bereits generiert habe, und ich habe auch seinen öffentlichen Schlüssel zum pgbackrest-Repository-Host ( [email protected] ) hinzugefügt.
  3. VOLUME ["${PGHOME_DIR}"] - Definiert das Containerverzeichnis /var/lib/pgsql als Einhängepunkt. Während wir den Befehl docker run ausführen, geben wir das host-Verzeichnis node-2 für diesen Einhängepunkt an.
  4. USER postgres - Alle Befehle, die auf dem Container ausgeführt werden, werden als postgres-Benutzer ausgeführt.
$ cat Dockerfile
FROM  centos:7

ARG PGBACKREST_REPO_HOST
ARG PGHOME_DIR=/var/lib/pgsql

## Adding Postgresql Repo for CentOS7
RUN yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

## Installing PostgreSQL
RUN yum -y install postgresql11 postgresql11-server postgresql11-devel postgresql11-contrib postgresql11-libs pgbackrest openssh-clients

## Adding configuration for pgbackrest, needed for WAL recovery and replication.
RUN echo -ne "[global]\nrepo1-host=${PGBACKREST_REPO_HOST}\n\n[pgbench]\npg1-path=/var/lib/pgsql/11/data\n" > /etc/pgbackrest.conf

## Adding Private Key to the Docker. Docker container would use this private key for pgbackrest wal recovery.
RUN mkdir -p ${PGHOME_DIR}/.ssh &&  chmod 0750 ${PGHOME_DIR}/.ssh
COPY --chown=postgres:postgres ./SSH_PRIVATE_KEY  ${PGHOME_DIR}/.ssh/id_rsa
RUN chmod 0600 ${PGHOME_DIR}/.ssh/id_rsa
RUN echo -ne "Host ${PGBACKREST_REPO_HOST}\n\tStrictHostKeyChecking no\n" >> ${PGHOME_DIR}/.ssh/config

## Making "/var/lib/pgsql" as a mountable directory in the container
VOLUME ["${PGHOME_DIR}"]

## Setting postgres as the default user for any remaining commands
USER postgres

Wir haben jetzt zwei Dateien, Dockerfile, die vom Docker-Build verwendet werden, und SSH_PRIVATE_KEY, die wir in das Docker-Image kopieren werden.

$ ls

Dockerfile  SSH_PRIVATE_KEY

Führen Sie den folgenden Befehl auf node-2 aus, um unser Docker-Image zu erstellen. Ich habe die IP des pgbackrest-Repository-Hosts im Befehl erwähnt und diese IP wird im pgbackrest-Parameter „repo-host“ verwendet.

$ docker build --no-cache -t postgresql:11 --build-arg PGBACKREST_REPO_HOST=192.168.0.113 .

Sending build context to Docker daemon  230.4kB

Step 1/12 : FROM  centos:7

 ---> 9f38484d220f

Step 2/12 : ARG PGBACKREST_REPO_HOST

 ---> Running in 8b7b36c6f151

Removing intermediate container 8b7b36c6f151

 ---> 31510e46e286

Step 3/12 : ARG PGHOME_DIR=/var/lib/pgsql

...

Step 4/12 : RUN yum -y install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

...

...

Step 12/12 : USER postgres

 ---> Running in c91abcf46440

Removing intermediate container c91abcf46440

 ---> bebce78df5ae

Successfully built bebce78df5ae

Successfully tagged postgresql:11

Stellen Sie sicher, dass das Image erfolgreich erstellt wurde, und überprüfen Sie, ob das Image „postgresql:11“ kürzlich erstellt wurde, wie unten gezeigt.

$ docker image ls postgresql:11

REPOSITORY          TAG IMAGE ID            CREATED SIZE

postgresql          11 2e03ed2a5946        3 minutes ago 482MB

Wiederherstellen der PostgreSQL-Sicherung

Wir werden jetzt unsere PostgreSQL-Sicherung wiederherstellen, die im pgbackrest-Sicherungs-Repository-Host-Knoten-3 verwaltet wird.

Unten ist die pgbackrest-Konfigurationsdatei, die auf Host node-2 vorhanden ist, und ich habe node-3 als pgbackrest-Repository-Host erwähnt. Das im Parameter pg1-Pfad erwähnte Verzeichnis ist der Ort, an dem das PostgreSQL-Datenverzeichnis wiederhergestellt wird.

[[email protected] ~]$ cat /etc/pgbackrest.conf 

[global]

log-level-file=detail

repo1-host=node-3



[pgbench]

pg1-path=/var/lib/pgsql/11/data

Mit dem folgenden pgbackrest restore-Befehl wird das Postgresql-Datenverzeichnis unter node-2:/var/lib/pgsql/11/data wiederhergestellt.

Um PITR mit dem pgbackrest-Backup zu validieren, habe ich --type=time --target='2019-07-30 06:24:50.241352+00' eingestellt, damit die WAL-Wiederherstellung vor dem stoppt genannte Zeit.

[[email protected] ~]$ sudo -u postgres bash -c "/usr/bin/pgbackrest --type=time --target='2019-07-30 06:24:50.241352+00' --target-action=promote --recovery-option='standby_mode=on' --stanza=pgbench restore"

Der obige Befehl kann je nach Sicherungsgröße und Netzwerkbandbreite einige Zeit in Anspruch nehmen. Überprüfen Sie nach der Wiederherstellung die Größe des Datenverzeichnisses und überprüfen Sie auch recovery.conf.

[[email protected] ~]$ sudo -u postgres du -sh /var/lib/pgsql/11/data 

2.1G    /var/lib/pgsql/11/data



[[email protected] ~]$ sudo -u postgres cat /var/lib/pgsql/11/data/recovery.conf

standby_mode = 'on'

restore_command = '/usr/bin/pgbackrest --stanza=pgbench archive-get %f "%p"'

recovery_target_time = '2019-07-30 06:24:50.241352+00'

Archivierungsmodus für PostgreSQL-Docker-Container deaktivieren.

[[email protected] ~]$ sudo -u postgres bash -c "echo 'archive_mode = off' >> /var/lib/pgsql/11/data/postgresql.auto.conf"

Starten Sie den Docker-Container mit dem Image „postgresql:11“. Im Befehl sind wir 

  1. Festlegen des Containernamens als „pgbench“

  2. Laden des Docker-Host-Verzeichnisses (Knoten-2) /var/lib/psql in das Docker-Container-Verzeichnis /var/lib/psql 

  3. Container-Port 5432 für Port 15432 auf Knoten-2 verfügbar machen.

  4. Starten des Postgres-Daemons mit dem Befehl /usr/pgsql-11/bin/postmaster -D /var/lib/pgsql/11/data

[[email protected] ~]$ docker run --rm --name "pgbench" -v /var/lib/pgsql:/var/lib/pgsql -p 15432:5432 -d postgresql:11  /usr/pgsql-11/bin/postmaster -D /var/lib/pgsql/11/data

e54f2f65afa13b6a09236a476cb1de3d8e499310abcec2b121a6b35611dac276

Stellen Sie sicher, dass der „pgbench“-Container erstellt wurde und ausgeführt wird.

[[email protected] ~]$ docker ps -f name=pgbench

CONTAINER ID        IMAGE COMMAND                  CREATED STATUS PORTS                     NAMES

e54f2f65afa1        postgresql:11 "/usr/pgsql-11/bin/p…"   34 seconds ago Up 33 seconds 0.0.0.0:15432->5432/tcp   pgbench

PostgreSQL validieren 

Da das Hostverzeichnis /var/lib/pgsql mit dem Docker-Container geteilt wird, sind die vom PostgreSQL-Dienst generierten Protokolle auch von node-2 aus sichtbar. Überprüfen Sie das heutige Protokoll, um sicherzustellen, dass PostgreSQL ohne FEHLER gestartet wurde, und stellen Sie sicher, dass die folgenden Protokollzeilen vorhanden sind.

[[email protected] ~]$ sudo -u postgres tailf /var/lib/pgsql/11/data/log/postgresql-Tue.csv

..

2019-07-30 06:38:34.633 UTC,,,7,,5d3fe5e9.7,5,,2019-07-30 06:38:33 UTC,1/0,0,LOG,00000,"consistent recovery state reached at E/CE000210",,,,,,,,,""

2019-07-30 06:38:34.633 UTC,,,1,,5d3fe5e9.1,2,,2019-07-30 06:38:33 UTC,,0,LOG,00000,"database system is ready to accept read only connections",,,,,,,,,""

2019-07-30 06:38:35.236 UTC,,,7,,5d3fe5e9.7,6,,2019-07-30 06:38:33 UTC,1/0,0,LOG,00000,"restored log file ""000000010000000E000000CF"" from archive",,,,,,,,,""

2019-07-30 06:38:36.210 UTC,,,7,,5d3fe5e9.7,7,,2019-07-30 06:38:33 UTC,1/0,0,LOG,00000,"restored log file ""000000010000000E000000D0"" from archive",,,,,,,,,""

...

2019-07-30 06:39:57.221 UTC,,,7,,5d3fe5e9.7,37,,2019-07-30 06:38:33 UTC,1/0,0,LOG,00000,"recovery stopping before commit of transaction 52181192, time 2019-07-30 06:25:01.576689+00",,,,,,,,,""

...

2019-07-30 06:40:00.682 UTC,,,7,,5d3fe5e9.7,47,,2019-07-30 06:38:33 UTC,1/0,0,LOG,00000,"archive recovery complete",,,,,,,,,""

Meldung "Konsistenter Wiederherstellungsstatus erreicht bei E/CE000210", weist darauf hin, dass wir mit dem pgbackrest-Sicherungsdatenverzeichnis einen konsistenten Status erreichen konnten.

Die Meldung "Archivwiederherstellung abgeschlossen" zeigt an, dass wir die von pgbackrest gesicherte WAL-Datei wiedergeben und ohne Probleme wiederherstellen können.

Stellen Sie über den lokalen Port 15432 eine Verbindung zur postgresql-Instanz her und überprüfen Sie die Tabellen- und Zeilenanzahl.

[[email protected] ~]$ sudo -iu postgres /usr/pgsql-11/bin/psql  -p 15432 -h localhost -U pgbench 

Password for user pgbench: 

psql (11.4)

Type "help" for help.



pgbench=> \dt

              List of relations

 Schema |       Name | Type  | Owner  

--------+------------------+-------+---------

 public | pgbench_accounts | table | pgbench

 public | pgbench_branches | table | pgbench

 public | pgbench_history  | table | pgbench

 public | pgbench_tellers  | table | pgbench

(4 rows)



pgbench=> select * from pgbench_history limit 1;

 tid | bid |   aid | delta |           mtime | filler 

-----+-----+---------+-------+----------------------------+--------

  98 |   3 | 2584617 |   507 | 2019-07-30 06:20:01.412226 | 

(1 row)



pgbench=> select max(mtime) from pgbench_history ;

            max             

----------------------------

 2019-07-30 06:22:01.402245

(1 row)



pgbench=> select count(1) from pgbench_history ;

 count 

-------

 90677

(1 row)



pgbench=> select count(1) from pgbench_accounts ;

  count   

----------

 10000000

(1 row)

Wir haben jetzt unser PostgreSQL-Backup auf einem Docker-Container wiederhergestellt und auch PITR verifiziert. Nach der Validierung des Backups können wir den Container stoppen und das Datenverzeichnis entfernen.

[[email protected] ~]$ docker stop pgbench

pgbench

[[email protected] ~]$ sudo -u postgres bash -c "rm -rf /var/lib/pgsql/11/data && mkdir -p /var/lib/pgsql/11/data && chmod 0700 /var/lib/pgsql/11/data"

Fazit

In diesem Blog habe ich die Backup-Validierung mit einer kleinen Datenbank auf einer kleinen VirtualBox-VM demonstriert. Aus diesem Grund war die Backup-Validierung in nur wenigen Minuten abgeschlossen. Es ist wichtig zu beachten, dass Sie in der Produktion eine geeignete VM mit genügend Arbeitsspeicher, CPU und Festplatte auswählen müssen, damit die Backup-Validierung erfolgreich abgeschlossen werden kann. Sie können den gesamten Validierungsprozess auch in einem Bash-Skript oder sogar durch Integration in eine CI/CD-Pipeline automatisieren, sodass Sie unsere PostgreSQL-Backups regelmäßig validieren können.