Архивните копия са жизненоважна и важна част от всеки план за възстановяване при бедствия, правенето на резервни копия на производствената база данни също е основна и важна част от администрацията на PostgreSQL. Въпреки това, DBA не потвърждават често, че тези архиви са надеждни.
Всяка организация взема резервни копия на PostgreSQL база данни в различна форма, някои може да вземат резервно копие на файлова система (физическо) на директориите с данни на PostgreSQL (използвайки инструменти като Barman, PGBackRest), докато други могат да вземат само логически архиви (използвайки pg_dump), и дори други могат да правят моментни снимки на ниво блок, като използват инструменти като EBS или VMWare моментна снимка.
В този блог ще ви покажем как да потвърдите резервното си копие на PostgreSQL, като възстановите архива в Docker контейнер с помощта на инструмента pgBackRest за вземане и възстановяване на архива. Предполагаме, че вече имате познания как да използвате PostgreSQL, Docker и pgBackRest.
Защо трябва да използвате Docker?
Docker улеснява автоматизацията, той също така улеснява работата по интегрирането на нашата задача за проверка на архивиране на PostgreSQL в инструменти за CI/CD като CircleCI, Travis, GitLab или Jenkins. Използването на Docker избягва времето и ресурсите, които трябва да похарчим за въвеждане на новата среда за тестване на архива.
Настройка на демонстрация
Хост | Роля | Инсталиран Пакети | Crontab |
възел-1 192.168.0.111 CentOS-7 | Основен екземпляр на Posgresql-11. Създаден потребител и база данни „pgbench“ и инициализиран с pgbench таблици. | postgresql-11, pgbackrest-2.15 | Изпълнение на pgbench на всеки 5 минути за симулиране на натоварването. |
node-2 | Тестова машина - ще изпълним нашата проверка на Docker на този хост. | docker-ce-18.06, pgbackrest-2.15 | |
възел-3 192.168.0.113 CentOS-7 | хост на хранилище pgBackRest | pgbackrest-2.15 | Изпълнение на pgbackrest за вземане на архив на Incr на всеки 4 часа Различно архивиране всеки ден Пълно архивиране всяка седмица |
За да работи pgbackrest, настроих SSH достъп без парола между тези възли.
Потребител „postgres“ на node-1 и node-2 може да влезе без парола до потребителя „pgbackrest“ на възел-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
Потребителят „pgbackrest“ на възел-3 може да влезе без парола до потребител „postgres“ на възел-1 и възел-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
Общ преглед на проверката на архивиране
По-долу е даден кратък преглед на стъпките, които ще следваме за нашата проверка на резервно копие на PostgreSQL.
- С помощта на командата pgbackrest restore ще извлечем най-новото архивно копие от хоста на pgBackRest Repository (възел-3) в директорията на тестовата машина (node-2) /var/lib/pgsql/11/data
- По време на изпълнение на docker, ние монтираме директорията на хост машината (node-2) /var/lib/pgsql в контейнера за докер и стартираме демона postgres/postmaster от монтираната директория. Ще изложим също порт 5432 от контейнер към порт 15432 на хост машината.
- След като докер контейнерът започне да работи, ще се свържем с базата данни PostgreSQL чрез node-2:15432 и ще проверим дали всички таблици и редове са възстановени. Ще проверим също регистрационните файлове на PostgreSQL, за да се уверим, че няма съобщение за ГРЕШКА по време на възстановяването и екземплярът също е достигнал последователното състояние.
Повечето стъпки за валидиране на резервното копие ще бъдат извършени на хост възел-2.
Изграждане на изображението на Docker
На node-2 създайте Dockerfile и изградете изображението на docker „postgresql:11“. В долния Dockerfile ще приложим следните промени върху основното изображение centos:7.
- Инсталиране на postgresql-11, pgbackrest и openssh-clients. Openssh-clients са необходими за pgbackrest.
- Конфигуриране на pgbackrest – Нуждаем се от конфигурация на pgbackrest в изображението, за да тестваме PITR, без конфигурацията на pgbackrest командата restore_command би се провалила. Като част от конфигурацията на pgbackrest
- Добавяме ip ip на хоста на хранилището pgbackrest (192.168.0.113) в конфигурационния файл /etc/pgbackrest.conf.
- Също така се нуждаем от SSH достъп без парола между докер контейнера и хоста на хранилището на pgbackrest. За това копирам SSH_PRIVATE_KEY, който вече генерирах и също така добавих публичния му ключ към хоста на хранилището на pgbackrest ( [email protected] ) .
- VOLUME ["${PGHOME_DIR}"] - Дефинира директорията на контейнера /var/lib/pgsql като точка за монтиране. Докато изпълняваме командата за изпълнение на docker, ние ще посочим хост директория на node-2 към тази точка на монтиране.
- USER postgres – Всяка команда, изпълнявана в контейнера, ще бъде изпълнена като потребител на postgres.
$ 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
Вече имаме два файла, Dockerfile, използван от docker build и SSH_PRIVATE_KEY, който ще бъдем копирани в изображението на docker.
$ ls
Dockerfile SSH_PRIVATE_KEY
Изпълнете командата по-долу на node-2, за да изградите изображението на Docker. Споменах IP хоста на pgbackrest в командата и този IP ще се използва в параметъра на pgbackrest „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
Уверете се, че изображението е изградено успешно и проверете дали изображението „postgresql:11“ е създадено наскоро, както е показано по-долу.
$ docker image ls postgresql:11
REPOSITORY TAG IMAGE ID CREATED SIZE
postgresql 11 2e03ed2a5946 3 minutes ago 482MB
Възстановяване на архива на PostgreSQL
Сега ще възстановим нашия PostgreSQL архив, поддържан в pgbackrest backup хранилище хост възел-3.
По-долу е конфигурационният файл на pgbackrest, присъстващ на хост node-2 и споменах node-3 като хост на pgbackrest хранилище. Директорията, спомената в param pg1-path, е мястото, където директорията с данни на PostgreSQL ще бъде възстановена.
[[email protected] ~]$ cat /etc/pgbackrest.conf
[global]
log-level-file=detail
repo1-host=node-3
[pgbench]
pg1-path=/var/lib/pgsql/11/data
Използвайки по-долу командата pgbackrest restore, директорията с данни на postgresql ще бъде възстановена на node-2:/var/lib/pgsql/11/data.
За да потвърдя PITR с архива на pgbackrest, зададох --type=time --target='2019-07-30 06:24:50.241352+00', така че възстановяването на WAL да спре преди споменато време.
[[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"
Горената команда може да отнеме време в зависимост от размера на резервното копие и мрежовата честотна лента. След възстановяване проверете размера на директорията с данни и също проверете 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'
Деактивирайте режима на архивиране за PostgreSQL докер контейнера.
[[email protected] ~]$ sudo -u postgres bash -c "echo 'archive_mode = off' >> /var/lib/pgsql/11/data/postgresql.auto.conf"
Стартирайте докер контейнера с изображението „postgresql:11“. В командата сме
-
Задаване на името на контейнера като „pgbench“
-
Монтиране на директория на docker host(node-2) /var/lib/psql към директорията на контейнера на docker /var/lib/psql
-
Излагане на порт на контейнера 5432 на порт 15432 на възел-2.
-
Стартиране на демона postgres с помощта на командата /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
Проверете дали контейнерът „pgbench“ е създаден и работи.
[[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
Тъй като хост директорията /var/lib/pgsql е споделена с докер контейнера, регистрационните файлове, генерирани от услугата PostgreSQL, също се виждат от node-2. Проверете днешния дневник, за да се уверите, че PostgreSQL е стартирал добре без ГРЕШКИ и се уверете, че присъстват редове по-долу.
[[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",,,,,,,,,""
Съобщението „достигнато последователно състояние на възстановяване при E/CE000210“ показва, че с директорията с архивни данни pgbackrest успяхме да достигнем последователно състояние.
Съобщението „Възстановяването на архива е завършено“, показва, че можем да възпроизведем отново WAL файла, архивиран от pgbackrest и да можем да го възстановим без проблем.
Свържете се с екземпляр на postgresql чрез локален порт 15432 и проверете таблиците и броя на редовете.
[[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)
Вече възстановихме резервното си копие на PostgreSQL в докер контейнер и също така потвърдихме PITR. След като потвърдим архива, можем да спрем контейнера и да премахнем директорията с данни.
[[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"
Заключение
В този блог демонстрирах валидирането на архивиране с помощта на малка база данни на малка виртуальна машина VirtualBox. Поради това валидирането на резервното копие беше завършено само за няколко минути. Важно е да се отбележи, че в производството ще трябва да изберете подходяща виртуална машина с достатъчно памет, процесор и диск, за да позволите успешното потвърждаване на архивирането. Можете също така да автоматизирате целия процес на валидиране в bash скрипт или дори чрез интегриране с CI/CD конвейер, така че да можете редовно да валидирате нашите резервни копия на PostgreSQL.