sql >> Databasteknik >  >> RDS >> PostgreSQL

Validera dina PostgreSQL-säkerhetskopier på Docker

Säkerhetskopiering är den vitala och viktiga delen av alla katastrofåterställningsplaner, att ta säkerhetskopior av produktionsdatabasen är också en grundläggande och en viktig del av PostgreSQL-administrationen. DBA:er validerar dock inte ofta att dessa säkerhetskopior är tillförlitliga.

Varje organisation tar säkerhetskopior av PostgreSQL-databas i olika former, vissa kan ta en filsystem (fysisk) säkerhetskopia av PostgreSQL-datakatalogerna (med hjälp av verktyg som Barman, PGBackRest) medan andra kan ta bara logiska säkerhetskopior (med hjälp av pg_dump), och även andra kan ta ögonblicksbilder på blocknivå med hjälp av verktyg som EBS eller VMWare ögonblicksbild.

I den här bloggen kommer vi att visa dig hur du validerar din PostgreSQL-säkerhetskopia genom att återställa säkerhetskopian till en Docker-behållare med hjälp av verktyget pgBackRest för att ta och återställa säkerhetskopian. Vi antar att du redan har kunskap om hur du använder PostgreSQL, Docker och pgBackRest.

Varför ska du använda Docker?

Docker gör automatisering enklare, det underlättar också arbetet med att integrera vår PostgreSQL Backup Validation-uppgift i ett CI/CD-verktyg som CircleCI, Travis, GitLab eller Jenkins. Genom att använda Docker undviker vi den tid och de resurser vi måste lägga på att ta med den nya miljön för att testa säkerhetskopieringen.

Demoinställningar

Värd 

Roll

Installerad

Paket 

Crontab

nod-1 192.168.0.111

CentOS-7

Posgresql-11 primära instans.

Skapade användar- och databas "pgbench" och initierades med pgbench-tabeller.

postgresql-11, pgbackrest-2.15

Kör pgbench var 5:e minut för att simulera arbetsbelastningen.

nod-2
192.168.0.112
CentOS-7

Testmaskin - vi kommer att köra vår Docker-validering på denna värd.

docker-ce-18.06, pgbackrest-2.15

 

nod-3

192.168.0.113

CentOS-7

pgBackRest Repository Host

pgbackrest-2.15

Kör pgbackrest för att ta Incr backup var fjärde timme

Diff backup varje dag

Fullständig säkerhetskopiering varje vecka 

För att pgbackrest ska fungera har jag ställt in lösenordslös SSH-åtkomst mellan dessa noder.

Användaren "postgres" på nod-1 och nod-2 kan logga in lösenordslöst till användaren "pgbackrest" på nod-3.

[[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

Användaren "pgbackrest" på nod-3 kan logga in lösenordslöst till användaren "postgres" på nod-1 och nod-2.

[[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

Översikt över säkerhetskopieringsvalidering

Nedan är en kort översikt över de steg vi kommer att följa för vår PostgreSQL-säkerhetskopieringsvalidering.

  1. Med hjälp av kommandot pgbackrest restore hämtar vi den senaste säkerhetskopian från pgBackRest Repository Host (nod-3) till katalogen Test Machine (nod-2) /var/lib/pgsql/11/data
  2. Under dockerkörningen monterar vi värddatorkatalogen (nod-2) /var/lib/pgsql på docker-behållaren och startar postgres/postmaster-demonen från den monterade katalogen. Vi skulle också exponera port 5432 från container till värddatorport 15432. 
  3. När docker-behållaren har börjat köras kommer vi att ansluta till PostgreSQL-databasen via nod-2:15432 och verifiera att alla tabeller och rader är återställda. Vi skulle också kontrollera PostgreSQL-loggarna för att se till att det inte finns något FEL-meddelande under återställningen och att instansen också har nått konsekvent tillstånd.

De flesta av stegen för säkerhetskopiering kommer att utföras på värdnod-2.

Bygga Docker-bilden

På nod-2, skapa Dockerfile och bygg docker-bilden "postgresql:11". I Dockerfilen nedan kommer vi tillämpa följande ändringar över centos:7 basbild.

  1. Installation av postgresql-11, pgbackrest och openssh-klienter. Openssh-klienter behövs för pgbackrest.
  2. Konfigurera pgbackrest - Vi behöver pgbackrest-konfiguration i bilden för att testa PITR, utan pgbackrest-konfigurationen skulle restore_command misslyckas. Som en del av pgbackrest-konfigurationen
    1. Vi lägger till pgbackrest-förvarets värd-ip (192.168.0.113) i inställningsfilen /etc/pgbackrest.conf.
    2. Vi behöver också lösenord mindre SSH-åtkomst mellan docker-behållaren och pgbackrest-förvaret. För detta kopierar jag SSH_PRIVATE_KEY som jag redan har genererat och jag har också lagt till dess publika nyckel till pgbackrest-förrådets värd ([email protected] ) .
  3. VOLYM ["${PGHOME_DIR}"] - Definierar behållarkatalogen /var/lib/pgsql som en monteringspunkt. När vi kör docker run-kommandot kommer vi att ange nod-2 värdkatalog till denna monteringspunkt.
  4. USER postgres - Alla kommandon som körs på behållaren kommer att köras som postgres användare.
$ 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

Vi har nu två filer, Dockerfile som används av docker build och SSH_PRIVATE_KEY som vi kommer att kopieras till docker-bilden.

$ ls

Dockerfile  SSH_PRIVATE_KEY

Kör kommandot nedan på nod-2 för att bygga vår docker-bild. Jag har nämnt pgbackrest repository host IP i kommandot och denna IP kommer att användas i pgbackrest parameter "repo-host".

$ 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

Se till att bilden är framgångsrik och kontrollera att "postgresql:11"-bilden har skapats nyligen som visas nedan.

$ docker image ls postgresql:11

REPOSITORY          TAG IMAGE ID            CREATED SIZE

postgresql          11 2e03ed2a5946        3 minutes ago 482MB

Återställer PostgreSQL-säkerhetskopian

Vi kommer nu att återställa vår PostgreSQL-säkerhetskopia som underhålls i pgbackrest backup repository host nod-3.

Nedan är pgbackrest-konfigurationsfilen som finns på värdnod-2 och jag har nämnt nod-3 som pgbackrest-förvarsvärd. Katalogen som nämns i param pg1-sökvägen är där PostgreSQL-datakatalogen skulle återställas.

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

[global]

log-level-file=detail

repo1-host=node-3



[pgbench]

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

Med hjälp av kommandot pgbackrest restore nedan kommer postgresql-datakatalogen att återställas vid nod-2:/var/lib/pgsql/11/data.

För att validera PITR med pgbackrest backup har jag ställt in --type=time --target='2019-07-30 06:24:50.241352+00', så att WAL-återställningen stoppas innan nämnda tid.

[[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"

Kommandot ovan kan ta tid beroende på säkerhetskopieringsstorleken och nätverkets bandbredd. När du har återställt, verifiera storleken på datakatalogen och kontrollera även 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'

Inaktivera arkiveringsläge för PostgreSQL docker-container.

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

Starta docker-behållaren med bilden "postgresql:11". I kommandot är vi 

  1. Ställer in behållarens namn som "pgbench"

  2. Montering av docker host(node-2)-katalogen /var/lib/psql till docker-containerkatalogen /var/lib/psql 

  3. Exponerar containerport 5432 för port 15432 på nod-2.

  4. Starta postgres-demonen med kommandot /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

Verifiera att "pgbench"-behållaren har skapats och körs.

[[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

Validerar PostgreSQL 

Eftersom värdkatalogen /var/lib/pgsql delas med docker-behållaren är loggarna som genereras av PostgreSQL-tjänsten också synliga från nod-2. Verifiera dagens logg för att se till att PostgreSQL har startat bra utan något FEL och se till att nedanstående loggrader finns.

[[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",,,,,,,,,""

Meddelande "konsekvent återställningstillstånd uppnått vid E/CE000210", indikerar att vi med pgbackrest backupdatakatalogen kunde nå ett konsekvent tillstånd.

Meddelandet "arkivåterställning klar", indikerar att vi kan spela upp WAL-filen som säkerhetskopieras av pgbackrest och kan återställa utan problem.

Anslut till postgresql-instansen via lokal port 15432 och verifiera tabeller och radantal.

[[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)

Vi har nu återställt vår PostgreSQL-säkerhetskopia på en dockningsbehållare och även verifierat PITR. När vi väl har validerat säkerhetskopian kan vi stoppa behållaren och ta bort datakatalogen.

[[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"

Slutsats

I den här bloggen demonstrerade jag säkerhetskopieringsvalideringen med en liten databas på en liten VirtualBox VM. På grund av detta slutfördes säkerhetskopieringsvalideringen på bara några minuter. Det är viktigt att notera att i produktionen måste du välja en riktig virtuell dator med tillräckligt med minne, CPU och disk för att säkerhetskopieringsvalideringen ska slutföras framgångsrikt. Du kan också automatisera hela valideringsprocessen i ett bash-skript eller till och med genom att integrera med en CI/CD-pipeline så att du regelbundet kan validera våra PostgreSQL-säkerhetskopior.


  1. SQLSTATE[HY000] [1045] Åtkomst nekad för användaren 'användarnamn'@'localhost' med CakePHP

  2. SQL-fråga för att hitta den n:e högsta lönen från en lönetabell

  3. JSON_LENGTH() – Returnera längden på ett JSON-dokument i MySQL

  4. SQLite JSON_OBJECT()