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 /build2. 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-dev3. Budujemy pgbackrest:
cd /build/pgbackrest-release-2.18/src && sudo ./configure
sudo make -s -C /build/pgbackrest-release-2.18/src4. Kopiujemy plik wykonywalny do katalogu /usr/bin:
sudo cp /build/pgbackrest-release-2.18/src/pgbackrest /usr/bin
sudo chmod 755 /usr/bin/pgbackrest5. Pgbackrest wymaga obecności perla. Instalujemy:
sudo apt-get install perl6. 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.conf7. Sprawdzamy:
pgbackrest versionSerwer 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.confna:
sudo chown postgres:postgres /var/log/pgbackrest
sudo chown postgres:postgres /etc/pgbackrest/pgbackrest.confKonfiguracja 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_keysNa 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 md5gdzie:
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ła2. 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 = replica3. 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 restartKonfiguracja 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-archivingTworzenie 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 checkRepozytorium (użytkownik pgbackrest):
Sprawdzamy na serwerze repozytorium:
sudo -u pgbackrest pgbackrest --stanza=main --log-level-console=info checkUpewniamy 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 backupJeśli chcesz uzyskać szczegółowe wyjście w konsoli, dodaj również:
sudo -u pgbackrest pgbackrest --stanza=main --type=full --log-level-console=info backupPrzywracamy kopię zapasową
Serwer Postgres (użytkownik sudo lub root):
1. Zatrzymujemy działający klaster:
sudo pg_ctlcluster 11 main stop2. Przywracamy z kopii zapasowej:
sudo -u postgres pgbackrest --stanza=main --delta restore3. Uruchamiamy klaster:
sudo pg_ctlcluster 11 main startPo przywróceniu kopii zapasowej musimy wykonać ponownie kopię zapasową:
Repozytorium (użytkownik pgbackrest):
sudo pgbackrest --stanza=main backupTo 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
