Инкрементални резервни копия на postgresql с pgbackrest — курс за начинаещи от разработчика

Дисклеймер

Аз съм разработчик. Пиша код, а взаимодействието ми с базата данни е само като потребител. Никак не претендирам за длъжността системен администратор, а още по-малко за DBA. Но...

Случи се да трябва да организирам резервно копиране на PostgreSQL база данни. Никакви облаци — просто използвай SSH и накарай всичко да работи, без да иска пари. Какво правим в такива случаи? Правилно, слагаме pg_dump в cron, правим архив всеки ден и ако нещата станат сериозни — изпращаме този архив на някое друго място.

Този път трудността беше в това, че по план базата трябваше да расте с около +- 100 МБ на ден. Разбира се, след няколко седмици желанието да правя резервни копия с pg_dump ще отпадне. Тук на помощ идват инкременталните бекъпи.

Интересно? Добре дошли в дълбочина.

Инкременталният бекъп е вид резервно копие, при което се копират не всички файлове от източника, а само новите и променените от създаването на предишното копие.

Както всеки разработчик, КОЙТО не желаеше (в момента) да се задълбочава в тънкостите на Postgres, исках да намеря зеления бутон. Знаете, като в AWS, DigitalOcean: натискаш един бутон — получаваш репликация, натискаш втори — настрявай бекъпи, трети — връщаш всичко назад с няколко часа. Не намерих нито бутони, нито красив GUI инструмент. Ако знаете такъв (безплатен или евтин) — напишете ми в коментарите.

След известно търсене намерих два инструмента pgbarman и pgbackrest. С първия просто не се получи (много оскъдна документация, опитвах се да всичко да накарам по остарели ръководства), а при втория документацията беше на ниво, но и не без недостатъци. За да улесня работата на тези, които ще се сблъскат с подобна задача, написах тази статия.

След прочитането на тази статия ще научите как да правите инкрементални бекъпи, да ги запазвате на отдалечен сървър (репозитория с бекъпи) и да ги възстановявате при загуба на данни или други проблеми на основния сървър.

Подготовка

За да пресъздадете ръководството, ще ви трябват два VPS. Първият ще бъде хранилище (репозиториум, на което ще съхранявате бекъпите), а вторият, съответно, сървърът с PostgreSQL (в моя случай версия 11 на PostgreSQL).

Предполага се, че на сървъра с postgres имате root, sudo потребител, postgres потребител и самият postgres е инсталиран (потребителят postgres се създава автоматично при инсталацията на postgresql), а на сървъра-репозитория има root и sudo потребител (в ръководството ще се използва името на потребителя pgbackrest).

За да имате по-малко проблеми при повторението на инструкциите — курсивом съм описал къде, с какъв потребител и с какви права изпълнявах командата по време на писането и проверката на статията.

Инсталация на pgbackrest

Репозиторий (потребител pgbackrest):

1. Сваляме архива с pgbackrest и преместваме съдържанието му в папката /build:

sudo mkdir /build
sudo wget -q -O - 
       https://github.com/pgbackrest/pgbackrest/archive/release/2.18.tar.gz | 
       sudo tar zx -C /build

2. Инсталираме необходимите зависимости за компилация:

sudo apt-get update
sudo apt-get install build-essential libssl-dev libxml2-dev libperl-dev zlib1g-dev 
       libpq-dev

3. Компилираме pgbackrest:

cd /build/pgbackrest-release-2.18/src && sudo ./configure
sudo make -s -C /build/pgbackrest-release-2.18/src

4. Копираме изпълнимия файл в директорията /usr/bin:

sudo cp /build/pgbackrest-release-2.18/src/pgbackrest /usr/bin
sudo chmod 755 /usr/bin/pgbackrest

5. Pgbackrest изисква наличието на perl. Инсталираме:

sudo apt-get install perl

6. Създаваме директории за логовете, даваме им определени права:

sudo mkdir -p -m 770 /var/log/pgbackrest
sudo chown pgbackrest:pgbackrest /var/log/pgbackrest
sudo mkdir -p /etc/pgbackrest
sudo mkdir -p /etc/pgbackrest/conf.d
sudo touch /etc/pgbackrest/pgbackrest.conf
sudo chmod 640 /etc/pgbackrest/pgbackrest.conf
sudo chown pgbackrest:pgbackrest /etc/pgbackrest/pgbackrest.conf

7. Проверяваме:

pgbackrest версия

Postgres сървър (sudo потребител или root):

Процесът на инсталиране на pgbackrest на сървър с postgres е аналогичен на процеса на инсталация на репозиторий (да, pgbackrest трябва да бъде инсталиран на двата сървъра), но в 6-та точка заменяме втората и последната команда:

sudo chown pgbackrest:pgbackrest /var/log/pgbackrest
sudo chown pgbackrest:pgbackrest /etc/pgbackrest/pgbackrest.conf

с:

sudo chown postgres:postgres /var/log/pgbackrest
sudo chown postgres:postgres /etc/pgbackrest/pgbackrest.conf

Настройка на взаимодействието между сървърите чрез SSH без парола

За да работи pgbackrest коректно, необходимо е да се настрои взаимодействието между сървъра на postgres и репозитория по файл-ключ.

Репозиторий (потребител pgbackrest):

Създаваме двойка ключове:

mkdir -m 750 /home/pgbackrest/.ssh
ssh-keygen -f /home/pgbackrest/.ssh/id_rsa 
       -t rsa -b 4096 -N ""

Внимание! По-горе посочените команди се изпълняват без sudo.

Postgres сървър (sudo потребител или root):

Създаваме двойка ключове:

sudo -u postgres mkdir -m 750 -p /var/lib/postgresql/.ssh
sudo -u postgres ssh-keygen -f /var/lib/postgresql/.ssh/id_rsa 
       -t rsa -b 4096 -N ""

Репозиторий (sudo потребител):

Копираме публичния ключ от сървъра postgres на сървъра-репозиторий:

(echo -n 'no-agent-forwarding,no-X11-forwarding,no-port-forwarding,' && 
       echo -n 'command="/usr/bin/pgbackrest ${SSH_ORIGINAL_COMMAND#* }" ' && 
       sudo ssh root@ cat /var/lib/postgresql/.ssh/id_rsa.pub) | 
       sudo -u pgbackrest tee -a /home/pgbackrest/.ssh/authorized_keys

На тази стъпка ще поиска паролата на root потребителя. Трябва да въведете именно паролата на root потребителя на postgres сървъра!

Postgres сървър (sudo потребител):

Копираме публичния ключ на репозитория на сървъра с postgres:

(echo -n 'no-agent-forwarding,no-X11-forwarding,no-port-forwarding,' && 
       echo -n 'command="/usr/bin/pgbackrest ${SSH_ORIGINAL_COMMAND#* }" ' && 
       sudo ssh root@ cat /home/pgbackrest/.ssh/id_rsa.pub) | 
       sudo -u postgres tee -a /var/lib/postgresql/.ssh/authorized_keys

На тази стъпка ще поиска паролата на root потребителя. Трябва да въведете именно паролата на root потребителя на репозитория!

Проверяваме:

Репозитория (root потребител, за чистота на експеримента):

sudo -u pgbackrest ssh postgres@

Postgres сървър (root потребител, за чистота на експеримента):

sudo -u postgres ssh pgbackrest@

Убедете се, че получавате достъп без проблеми.

Настройка на postgres сървъра

Postgres сървър (sudo потребител или root):

1. Ще разрешим „достъп“ до postgres сървъра от външни IP адреси. За целта ще редактираме файла postgresql.conf (намира се в папката /etc/postgresql/11/main), добавяйки реда:

listen_addresses = '*'

Ако такъв ред вече съществува — или го разкоментирайте, или задайте параметъра на ‘*’.

В файла pg_hba.conf (също се намира в папката /etc/postgresql/11/main) добавяме следните редове:

hostssl  all  all  0.0.0.0/0  md5
host  all  all  0.0.0.0/0  md5

където:

hostssl/host - свързваме се чрез SSL (или не)
all - разрешаваме свързване към всички бази данни
all - името на потребителя, на когото разрешаваме свързване (всички)
0.0.0.0/0 - маска на мрежата, от която е разрешено свързване
md5 - метод за криптиране на паролата

2. Ще направим необходимите настройки в postgresql.conf (намира се в папката /etc/postgresql/11/main) за работа с pgbackrest:

archive_command = 'pgbackrest --stanza=main archive-push %p' # Където main е името на кластера. При инсталацията на postgres автоматично се създава кластер main.
archive_mode = on
max_wal_senders = 3
wal_level = replica

3. Ще направим необходимите настройки в конфигурационния файл на pgbackrest (/etc/pgbackrest/pgbackrest.conf):

[main]
pg1-path=/var/lib/postgresql/11/main

[global]
log-level-file=detail
repo1-host=

4. Ще рестартираме postgresql:

sudo service postgresql restart

Настройка на сървъра-репозиторий

Репозитория (pgbackrest потребител):

Ще направим необходимите настройки в конфигурационния файл pgbackrest
(/etc/pgbackrest/pgbackrest.conf):

[main]
pg1-host=
pg1-path=/var/lib/postgresql/11/main

[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2 # Параметър, който показва колко пълни резервни копия да се съхраняват. Тоест, ако имате две пълни резервни копия и създадете трето - първите две ще бъдат изтрити заедно с инкременталните.
start-fast=y # Започва резервното копиране незабавно, информация за този параметър можете да намерите тук https://postgrespro.ru/docs/postgrespro/9.5/continuous-archiving

Създаване на хранилище

Репозитория (pgbackrest потребител):

Създаваме ново хранилище за клъстера main:

sudo mkdir -m 770 /var/lib/pgbackrest
sudo chown -R pgbackrest /var/lib/pgbackrest/
sudo -u pgbackrest pgbackrest --stanza=main stanza-create

Проверка

Postgres сървър (sudo потребител или root):

Проверяваме на postgres сървъра:

sudo -u postgres pgbackrest --stanza=main --log-level-console=info check

Репозитория (pgbackrest потребител):

Проверяваме на репозиторния сървър:

sudo -u pgbackrest pgbackrest --stanza=main --log-level-console=info check

Убедете се, че в изхода виждате реда «check command end: completed successfully».

Уморени ли сте? Преминаваме към най-интересното.

Правим резервно копие

Репозитория (pgbackrest потребител):

1. Извършваме резервно копиране:

sudo -u pgbackrest pgbackrest --stanza=main backup

2. Убедете се, че резервното копие е създадено:

ls /var/lib/pgbackrest/backup/main/

Pgbackrest ще създаде първото пълно резервно копие. Ако желаете, можете да стартирате командата за резервно копиране отново и да се уверите, че системата ще направи инкрементално резервно копие.

Ако искате да направите пълно резервно копие повторно, посочете допълнителния флаг:

sudo -u pgbackrest pgbackrest --stanza=main --type=full backup

Ако искате подробен изход в конзолата, посочете също:

sudo -u pgbackrest pgbackrest --stanza=main --type=full --log-level-console=info backup

Възстановяване на резервно копие

Postgres сървър (sudo потребител или root):

1. Спираме работещия клъстер:

sudo pg_ctlcluster 11 main stop

2. Възстановяваме се от резервното копие:

sudo -u postgres pgbackrest --stanza=main --delta restore

3. Стартираме клъстера:

sudo pg_ctlcluster 11 main start

След възстановяването на резервното копие е необходимо да направим повторно резервно копие:

Репозитория (pgbackrest потребител):

sudo pgbackrest --stanza=main backup

На това е всичко. В заключение искам да напомня, че не се опитвам да се представям за senior dba и при най-малката възможност ще използвам облачни услуги. В момента започвам да изучавам различни теми като резервни копия, репликации, мониторинг и т.н. и пиша малки отчети за резултатите, за да направя малък принос към общността и да оставя свои шпаргалки.

В следващите статии ще се постарая да разкажа за допълнителни функции — възстановяване на данни на чист клъстер, шифриране на резервни копия и публикуване на S3, резервни копия чрез rsync.

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster