Kurs młodego bojownika na temat inkrementalnych kopii zapasowych PostgreSQL z pgbackrest

Wyłączenie odpowiedzialności

Jestem deweloperem. Piszę kod, a z bazą danych współpracuję jedynie jako użytkownik. Nie aspiruję w żadnym wypadku do roli administratora systemu, a tym bardziej DBA. Ale...

Tak się złożyło, że musiałem zorganizować kopie zapasowe bazy danych PostgreSQL. Żadne chmury — korzystaj z SSH i spraw, aby wszystko działało i nie wymagało pieniędzy. Co robimy w takich przypadkach? Odpowiedź jest prosta, wsadzamy pg_dump do cron'a, codziennie robimy kopię zapasową do archiwum, a jeśli sytuacja się pogarsza — wysyłamy to archiwum gdzieś daleko.

Tym razem trudność polegała na tym, że według planów baza powinna rosnąć o około +- 100 MB dziennie. Oczywiście, już po kilku tygodniach chęć robienia wszystkich kopii za pomocą pg_dump odpadnie. Tutaj z pomocą przychodzą kopie inkrementalne.

Interesujące? Zapraszam do lektury.

Kopia inkrementalna to rodzaj kopii zapasowej, w której nie kopiowane są wszystkie pliki źródłowe, lecz tylko nowe i zmienione od momentu utworzenia poprzedniej kopii.

Jak każdy deweloper, ZUPEŁNIE nie chcąc (w tamtym momencie) zagłębiać się w subtelności Postgresa, chciałem znaleźć zielony przycisk. Wiecie, jak w AWS, DigitalOcean: nacisnąłeś jeden przycisk — uzyskałeś replikację, drugi — skonfigurowałeś kopie zapasowe, trzeci — wszystko przywróciłeś sprzed kilku godzin. Przycisków i ładnego narzędzia GUI nie znalazłem. Jeśli znasz takie (darmowe lub tanie) — napisz o tym w komentarzach.

Szukając w Internecie, znalazłem narzędzia pgbarman i pgbackrest. Z pierwszym po prostu nie miałem szczęścia (bardzo uboga dokumentacja, próbowałem wszystko skonfigurować według starych poradników), natomiast w przypadku drugiego dokumentacja okazała się na przyzwoitym poziomie, ale również nie bez wad. Aby uprościć pracę tym, którzy napotkają podobne zadanie, napisano ten artykuł.

Po przeczytaniu tego artykułu nauczysz się tworzyć kopie inkrementalne, przechowywać je na zdalnym serwerze (repozytorium kopii zapasowych) i przywracać je w przypadku utraty danych lub innych problemów z głównym serwerem.

Przygotowanie

Aby odtworzyć ten poradnik, będziesz potrzebował dwóch VPS. Pierwszy będzie magazynem (repozytorium, w którym będą przechowywane kopie zapasowe), a drugi, to sam serwer z PostgreSQL (w moim przypadku wersja 11 PostgreSQL).

Zakłada się, że na serwerze z postgres masz użytkownika root, użytkownika sudo, użytkownika postgres oraz sam postgres zainstalowany (użytkownik postgres jest tworzony automatycznie podczas instalacji postgresql), a na serwerze-repozytorium są użytkownik root i użytkownik sudo (w dokumentacji używane będzie imię użytkownika pgbackrest).

Aby zminimalizować problemy podczas reprodukcji instrukcji — kursywą zapisuję gdzie, jakim użytkownikiem i z jakimi uprawnieniami wykonywałem polecenie podczas pisania i sprawdzania artykułu.

Instalacja pgbackrest

Repozytorium (użytkownik pgbackrest):

1. Pobieramy archiwum z pgbackrest i przenosimy jego zawartość do folderu /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. Instalujemy niezbędne zależności do budowy:

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

3. Budujemy pgbackrest:

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

4. Kopiujemy plik wykonywalny do katalogu /usr/bin:

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

5. Pgbackrest wymaga obecności perla. Instalujemy:

sudo apt-get install perl

6. Tworzymy katalogi dla logów, nadajemy im odpowiednie uprawnienia:

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. Sprawdzamy:

pgbackrest version

Serwer Postgres (użytkownik sudo lub root):

Proces instalacji pgbackrest na serwerze z postgres jest analogiczny do procesu instalacji na repozytorium (tak, pgbackrest powinien być zainstalowany na obu serwerach), ale w punkcie 6 zmieniamy drugie i ostatnie polecenia:

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

na:

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

Konfiguracja interakcji między serwerami za pomocą SSH bez hasła

Aby pgbackrest działał poprawnie, konieczne jest skonfigurowanie interakcji między serwerem postgres a repozytorium za pomocą pliku klucza.

Repozytorium (użytkownik pgbackrest):

Tworzymy parę kluczy:

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

Uwaga! Powyższe polecenia wykonujemy bez sudo.

Serwer Postgres (użytkownik sudo lub root):

Tworzymy parę kluczy:

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

Repozytorium (użytkownik sudo):

Kopiujemy publiczny klucz serwera postgres na serwer-repozytorium:

(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

Na tym etapie zostaniesz poproszony o hasło użytkownika root. Wprowadź hasło użytkownika root serwera postgres!

Serwer Postgres (użytkownik sudo):

Kopiujemy publiczny klucz repozytorium na serwer z 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

Na tym etapie zostaniesz poproszony o hasło użytkownika root. Wprowadź hasło użytkownika root repozytorium!

Sprawdzamy:

Repozytorium (użytkownik root, dla czystości eksperymentu):

sudo -u pgbackrest ssh postgres@

Serwer Postgres (użytkownik root, dla czystości eksperymentu):

sudo -u postgres ssh pgbackrest@

Upewniamy się, że uzyskujemy dostęp bez problemów.

Konfiguracja serwera postgres

Serwer Postgres (użytkownik sudo lub root):

1. Zezwólmy na dostęp do serwera postgres z zewnętrznych adresów IP. W tym celu edytujemy plik postgresql.conf (znajduje się w folderze /etc/postgresql/11/main), dodając do niego linię:

listen_addresses = '*'

Jeśli taka linia już istnieje — albo ją odkomentuj, albo ustaw wartość parametru na ‘*’.

W pliku pg_hba.conf (również znajduje się w folderze /etc/postgresql/11/main) dodajemy następujące linie:

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

gdzie:

hostssl/host - łączymy się przez SSL (lub nie)
all - zezwalamy na połączenia ze wszystkimi bazami
all - nazwa użytkownika, któremu zezwalamy na połączenie (wszystkim)
0.0.0.0/0 - maska sieci, z której można się łączyć
md5 - sposób szyfrowania hasła

2. Wprowadzimy niezbędne ustawienia w postgresql.conf (znajduje się w folderze /etc/postgresql/11/main) do pracy pgbackrest:

archive_command = 'pgbackrest --stanza=main archive-push %p' # Gdzie main - nazwa klastra. Podczas instalacji postgres automatycznie tworzy klaster main.
archive_mode = on
max_wal_senders = 3
wal_level = replica

3. Wprowadzimy niezbędne ustawienia w pliku konfiguracyjnym pgbackrest (/etc/pgbackrest/pgbackrest.conf):

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

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

4. Zrestartuj postgresql:

sudo service postgresql restart

Konfiguracja serwera repozytorium

Repozytorium (użytkownik pgbackrest):

Wprowadzimy niezbędne ustawienia w pliku konfiguracyjnym 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 # Parametr określający, ile pełnych kopii zapasowych przechowywać. To znaczy, jeśli masz dwie pełne kopie zapasowe i tworzysz trzecią - pierwsze dwie zostaną usunięte razem z inkrementami.
start-fast=y # Rozpoczyna natychmiastową kopię zapasową, można przeczytać o tym parametrze tutaj https://postgrespro.ru/docs/postgrespro/9.5/continuous-archiving

Tworzenie repozytorium

Repozytorium (użytkownik pgbackrest):

Tworzymy nowe repozytorium dla klastra main:

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

Weryfikacja

Serwer Postgres (użytkownik sudo lub root):

Sprawdzamy na serwerze postgres:

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

Repozytorium (użytkownik pgbackrest):

Sprawdzamy na serwerze repozytorium:

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

Upewniamy się, że w wyjściu widzimy linię „check command end: completed successfully.”

Zmęczony? Przechodzimy do najciekawszego.

Wykonujemy kopię zapasową

Repozytorium (użytkownik pgbackrest):

1. Wykonujemy proces tworzenia kopii zapasowej:

sudo -u pgbackrest pgbackrest --stanza=main backup

2. Upewniamy się, że kopia zapasowa została utworzona:

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

Pgbackrest utworzy pierwszą pełną kopię zapasową. Jeśli chcesz, możesz ponownie uruchomić polecenie tworzenia kopii zapasowej, aby upewnić się, że system utworzy kopię inkrementalną.

Jeśli chcesz ponownie wykonać pełną kopię zapasową, dodaj dodatkowy flag:

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

Jeśli chcesz uzyskać szczegółowe wyjście w konsoli, dodaj również:

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

Przywracamy kopię zapasową

Serwer Postgres (użytkownik sudo lub root):

1. Zatrzymujemy działający klaster:

sudo pg_ctlcluster 11 main stop

2. Przywracamy z kopii zapasowej:

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

3. Uruchamiamy klaster:

sudo pg_ctlcluster 11 main start

Po przywróceniu kopii zapasowej musimy wykonać ponownie kopię zapasową:

Repozytorium (użytkownik pgbackrest):

sudo pgbackrest --stanza=main backup

To wszystko. Na koniec chciałbym przypomnieć, że w żadnym wypadku nie próbuję udawać senior dba i przy każdej możliwości będę korzystać z chmur. Obecnie sam zaczynam uczyć się różnych tematów, takich jak tworzenie kopii zapasowych, replikacje, monitorowanie itp., i a o wynikach piszę krótkie raporty, aby wnieść niewielki wkład w społeczność i zostawić dla siebie małe ściągi.

W kolejnych artykułach postaram się opisać dodatkowe funkcje — przywracanie danych na czysty klaster, szyfrowanie kopii zapasowych i publikację na S3, kopie zapasowe przez rsync.

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster