Sikkerhedskopier er den vitale og vigtige del af enhver katastrofegenopretningsplan, at tage backup af produktionsdatabasen er også en grundlæggende og vigtig del af PostgreSQL-administration. DBA'er validerer dog ikke ofte, at disse sikkerhedskopier er pålidelige.
Enhver organisation tager PostgreSQL-databasesikkerhedskopier i forskellige former, nogle kan tage en filsystem (fysisk) backup af PostgreSQL-datamapperne (ved hjælp af værktøjer som Barman, PGBackRest), mens andre kun tager logiske sikkerhedskopier (ved hjælp af pg_dump), og endda andre kan tage snapshots på blokniveau ved hjælp af værktøjer som EBS eller VMWare snapshot.
I denne blog vil vi vise dig, hvordan du validerer din PostgreSQL-sikkerhedskopi ved at gendanne sikkerhedskopien på en Docker-beholder ved hjælp af værktøjet pgBackRest til at tage og gendanne sikkerhedskopien. Vi antager, at du allerede har viden om, hvordan du bruger PostgreSQL, Docker og pgBackRest.
Hvorfor skal du bruge Docker?
Docker gør automatisering enklere, det letter også arbejdet med at integrere vores PostgreSQL Backup Validation-opgave i et CI/CD-værktøj som CircleCI, Travis, GitLab eller Jenkins. Brug af Docker undgår den tid og de ressourcer, vi skal bruge på at bringe det nye miljø til at teste sikkerhedskopien.
Demoopsætning
Vært | Rolle | Installeret Pakker | Crontab |
node-1 192.168.0.111 CentOS-7 | Posgresql-11 primære instans. Oprettet bruger og database "pgbench" og initialiseret med pgbench-tabeller. | postgresql-11, pgbackrest-2.15 | Kører pgbench hvert 5. minut for at simulere arbejdsbyrden. |
node-2 | Testmaskine - vi kører vores Docker-validering på denne vært. | docker-ce-18.06, pgbackrest-2.15 | |
node-3 192.168.0.113 CentOS-7 | pgBackRest Repository Host | pgbackrest-2.15 | Kører pgrygstøtte for at tage Incr backup hver 4. time Diff backup hver dag Fuld backup ugentligt |
For at pgbackrest skal fungere, har jeg konfigureret adgangskodefri SSH-adgang mellem disse noder.
Brugeren "postgres" på node-1 og node-2 kan logge ind uden adgangskode til brugeren "pgbackrest" på node-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
Brugeren "pgbackrest" på node-3 kan logge ind uden adgangskode til brugeren "postgres" på node-1 og node-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
Oversigt over sikkerhedskopieringsvalidering
Nedenfor er en kort oversigt over de trin, vi vil følge for vores PostgreSQL Backup Validering.
- Ved at bruge pgbackrest gendannelseskommandoen henter vi den seneste sikkerhedskopi fra pgBackRest Repository Host (node-3) til testmaskinens (node-2) bibliotek /var/lib/pgsql/11/data
- Under docker-kørslen monterer vi værtsmaskinens (node-2) bibliotek /var/lib/pgsql på docker-beholderen og starter postgres/postmaster-dæmonen fra den monterede mappe. Vi vil også eksponere port 5432 fra container til værtsmaskine port 15432.
- Når docker-containeren begyndte at køre, vil vi oprette forbindelse til PostgreSQL-databasen via node-2:15432 og kontrollere, at alle tabeller og rækker er gendannet. Vi ville også tjekke PostgreSQL-logfilerne for at sikre, at der ikke er nogen FEJL-meddelelse under gendannelsen, og at forekomsten også har nået den konsistente tilstand.
De fleste af sikkerhedskopieringsvalideringstrinene vil blive udført på værtsknude-2.
Opbygning af Docker-billedet
På node-2 skal du oprette Dockerfile og bygge docker-billedet "postgresql:11". I nedenstående Dockerfile anvender vi følgende ændringer over centos:7 basisbillede.
- Installation af postgresql-11, pgbackrest og openssh-clients. Openssh-klienter er nødvendige for pgbackrest.
- Konfiguration af pgbackrest - Vi har brug for pgbackrest-konfiguration i billedet for at teste PITR, uden pgbackrest-konfiguration ville restore_command mislykkes. Som en del af pgryglænskonfigurationen
- Vi tilføjer pgbackrest-lagerets værts-ip (192.168.0.113) i konfigurationsfilen /etc/pgbackrest.conf.
- Vi har også brug for adgangskode mindre SSH-adgang mellem docker-beholderen og pgbackrest-lagerværten. Til dette kopierer jeg SSH_PRIVATE_KEY, som jeg allerede har genereret, og jeg har også tilføjet dens offentlige nøgle til pgbackrest-lagerværten ([email protected] ) .
- VOLUME ["${PGHOME_DIR}"] - Definerer containerbiblioteket /var/lib/pgsql som et monteringspunkt. Mens du kører docker run-kommandoen, specificerer vi node-2 værtsmappe til dette monteringspunkt.
- USER postgres - Enhver kommando, der kører på containeren, vil blive udført som postgres-bruger.
$ 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 to filer, Dockerfile brugt af docker build og SSH_PRIVATE_KEY, som vi vil blive kopieret til docker-billedet.
$ ls
Dockerfile SSH_PRIVATE_KEY
Kør nedenstående kommando på node-2 for at bygge vores docker-billede. Jeg har nævnt pgbackrest repository host IP i kommandoen, og denne IP vil blive brugt 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
Sørg for, at billedet er bygget med succes, og kontroller, at "postgresql:11"-billedet er oprettet for nylig som vist nedenfor.
$ docker image ls postgresql:11
REPOSITORY TAG IMAGE ID CREATED SIZE
postgresql 11 2e03ed2a5946 3 minutes ago 482MB
Gendannelse af PostgreSQL-sikkerhedskopien
Vi vil nu gendanne vores PostgreSQL-sikkerhedskopi, der vedligeholdes i pgbackrest backup repository vært node-3.
Nedenfor er pgbackrest-konfigurationsfilen til stede på værtsnode-2, og jeg har nævnt node-3 som pgbackrest-lagervært. Katalog nævnt i param pg1-stien er det sted, hvor PostgreSQL databiblioteket ville blive gendannet.
[[email protected] ~]$ cat /etc/pgbackrest.conf
[global]
log-level-file=detail
repo1-host=node-3
[pgbench]
pg1-path=/var/lib/pgsql/11/data
Ved at bruge kommandoen pgbackrest restore nedenfor, vil postgresql databibliotek blive gendannet på node-2:/var/lib/pgsql/11/data.
For at validere PITR med pgbackrest backup har jeg indstillet --type=time --target='2019-07-30 06:24:50.241352+00', så WAL-gendannelsen stopper før nævnte tidspunkt.
[[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"
Ovenstående kommando kan tage tid afhængigt af sikkerhedskopieringsstørrelsen og netværksbåndbredden. Når den er gendannet, skal du kontrollere størrelsen på databiblioteket og også tjekke 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'
Deaktiver arkivtilstand for PostgreSQL docker-container.
[[email protected] ~]$ sudo -u postgres bash -c "echo 'archive_mode = off' >> /var/lib/pgsql/11/data/postgresql.auto.conf"
Start docker-beholderen med billedet "postgresql:11". I kommandoen er vi
-
Indstilling af containernavn som "pgbench"
-
Montering af docker host(node-2) bibliotek /var/lib/psql til docker container mappen /var/lib/psql
-
Eksponering af containerport 5432 for port 15432 på node-2.
-
Start af postgres-dæmonen med kommandoen /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
Bekræft at "pgbench"-containeren er oprettet og kører.
[[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
Validerer PostgreSQL
Da værtsmappen /var/lib/pgsql er delt med docker-container, er logfilerne genereret af PostgreSQL-tjenesten også synlige fra node-2. Bekræft dagens log for at sikre, at PostgreSQL er startet fint uden nogen FEJL, og sørg for, at nedenstående loglinjer er til stede.
[[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",,,,,,,,,""
Meddelelsen "konsistent gendannelsestilstand nået ved E/CE000210", angiver, at vi med pgbackrest backup-datamappen var i stand til at nå en konsistent tilstand.
Meddelelsen "arkivgendannelse fuldført", angiver, at vi er i stand til at genafspille WAL-filen, der er sikkerhedskopieret af pgbackrest og er i stand til at gendanne uden problemer.
Opret forbindelse til postgresql-instansen via lokal port 15432, og bekræft tabeller og rækkeantal.
[[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 gendannet vores PostgreSQL-sikkerhedskopi på en docker-container og også verificeret PITR. Når vi har valideret sikkerhedskopien, kan vi stoppe beholderen og fjerne databiblioteket.
[[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"
Konklusion
I denne blog demonstrerede jeg sikkerhedskopieringsvalideringen ved hjælp af en lille database på en lille VirtualBox VM. På grund af dette blev sikkerhedskopieringsvalideringen fuldført på få minutter. Det er vigtigt at bemærke, at i produktionen bliver du nødt til at vælge en ordentlig VM med nok hukommelse, CPU og disk til, at sikkerhedskopieringsvalideringen kan gennemføres med succes. Du kan også automatisere hele valideringsprocessen i et bash-script eller endda ved at integrere med en CI/CD-pipeline, så du regelmæssigt kan validere vores PostgreSQL-sikkerhedskopier.