W celu prostego wyjaśnienia jak cały mechanizm działa posłużę się prostym diagramem:
O godzinie 1 w nocy zrobiony został pełny backup narzędziem pg_basebackup. Następnie baza pracowała poprawnie aż do godziny 11:15. Z całego tego czasu czyli od godziny 01:00 do 12:00 do dedykowanego katalog odkładały się również Wal_logi. Wal log zawiera wektor zmian bazodanowych który pozwala na odtworzenie każdej transacji. (można to porównać do SQLi uruchamianych na bazie ale w rzeczywistości jest za zapis wartości które się pozmianiały np. jak zmieniły się rekordy w tabeli). Nie wchodząć głębiej w szczegóły mając pełny backup można uzupełnić go zapisami z wal_logów tak aby otrzymać spójny stan bazy na godzinę np. 11:00 - w sumie to na dowolną godzinę z zakresu normalnego funkcjonowania bazy.
Czyli backup zrobiony narzędziem pg_basebackup + wal_logi (archive) = spójne odtworzenie bazy danych do określonego punktu w czasie.
W bazie postgres można zdefiniować kilka poziomów szczegółowości Wal_logów (poniżej kilka jest opisanych ale to nie są wszystkie typy).
minimum - domyślna wartość - zawiera minimalną ilość wpisów niezbędną do funkcjonowania bazy danych
archive - zawiera odpowiednią ilość wpisów aby można było użyć wal_logów do odtworzenia bazy do określonego punktu w czasie.
replica - zawiera wszystko to co archive oraz dodatkowo zawiera informacje ktore są wykorzystywane przy replikacji
Przystępujemy do konfiguracji Postgresa 10
Tworzymy odpowiednią strukturę katalogów:
mkdir
/opt/pg_backupmkdir
/opt/pg_backup_archivemkdir
/opt/wal_archivemkdir
/opt/manage_postgreschown -R
postgres: /opt/pg_backupchown -R
postgres: /opt/pg_backup_archivechown -R
postgres: /opt/wal_archiveNastępnie zmieniamy w pliku /etc/postgresql/10/main/postgresql.conf parametry:
archive_mode =
on archive_command
= 'test ! -f /opt/wal_archive/%f && cp %p
/opt/wal_archive/%f'
wal_level =
archive # minimal, replica, or logicalModyfikujemy plik pg_hba.conf - dodajemy następującą linię aby można było się połączyć za pomocą pg_databasebackup. Gdzie pg_bkp to nazwa użytkownika bazodanowego używanego do backupu /etc/postgresql/10/main/pg_hba.conf
host replication pg_bkp 127.0.0.1/32 md5
Tworzymy użytkownika do backupu:
su - postgrespsql CREATE USER
pg_bkp REPLICATION LOGIN ENCRYPTED PASSWORD 'Backup321';\q
exit;
Restartujemy postgresa
systemctl postgresql restart
W kolejnym kroku konfigurujemy podłączenie się do bazy z użyciem hasła z pliku .pgpass:
Tworzymy plik .pgpass o zawartości takiej jak poniżej gdzie:
127.0.0.1 nazwa hosta
* oznacza port
* oznacza nazwę bazy danych (* oznacza wszystkie)
pg_bkp - nazwa usera którym się łączymy do bazy
Backup321 - nasze hasło
su - postgres
127.0.0.1:*:*:
pg_bkp:Backup321I finalnie tworzymy pierwszy pełny backup bazy danych:
pg_basebackup --checkpoint=fast -U
pg_bkp -h127.0.0.1 --progress -D /opt/pg_backup/W celu automatyzacji procesu backupu można użyć następującego skryptu:
backup.sh
POSTGRES_DB_DIR=/var/lib/postgresql/10/main
PG_DB_BACKUP_DIR=/opt/pg_backup
PG_WAL_BACKUP_DIR=/opt/wal_archive
PG_BACKUP_ARCHIVE=/opt/pg_backup_archive
PG_REPLICATION_USER=replica
echo "Tar current full backup to archive $PG_BACKUP_ARCHIVE"
tar --remove-files -czf $PG_BACKUP_ARCHIVE/wal_$(hostname)_$(date +%Y-%m-%d_%H%M).tgz $PG_WAL_BACKUP_DIR/*
tar --remove-files -czf $PG_BACKUP_ARCHIVE/pg_db_full_$(hostname)_$(date +%Y-%m-%d_%H%M).tgz $PG_DB_BACKUP_DIR/*
echo "Creating full backup to $PG_DB_BACKUP_DIR"
pg_basebackup --checkpoint=fast -U$PG_REPLICATION_USER -h127.0.0.1 --progress -D $PG_DB_BACKUP_DIR
Powyższy skrypt robi tar z ostatniego full backupu oraz z plików z wal logami.
Proces odtworzenia bazy danych sprowadza się do:
1. Usunięcia istniejącej bazy danych
2. Odtworzenie pełnego backupu bazy danych - na tym przykładzie za pomocą polecenia cp
3. Utworzenia pliku recovery.conf który to spowoduje że do pełnego backupu zostaną dograne zmiany z wal logów - aż do określonego punktu w czasie - czyli do recovery_target_time.
Sam proces odtwarzania bazy danych również można zautomatyzować i wykorzystać następujący skrypt. W skrypcie należy ustawić tylko datę do której się odtwarzamy - oraz oczywiście poprawne ścieżki
restore.sh
#SET VARIABLES
POSTGRES_DB_DIR=/var/lib/postgresql/10/main
PG_DB_BACKUP_DIR=/opt/pg_backup
PG_WAL_BACKUP_DIR=/opt/wal_archive
#SET POINT IN TIME TO RECOVER DATABASE
RECOVER_DATE="2018-10-04 08:00:00"
systemctl stop postgresql
echo "Postgress stopped"
sleep 3
echo "Cleaning old postgres directory"
rm -rf $POSTGRES_DB_DIR/*
cp -r $PG_DB_BACKUP_DIR/* $POSTGRES_DB_DIR/
rm -rf $POSTGRES_DB_DIR/pg_wal/*
#create restore file
echo "Creating restore file"
echo "restore_command = 'cp $PG_WAL_BACKUP_DIR/%f \"%p\"'
#recovery_target = 'immediate'
recovery_target_time='$RECOVER_DATE'
recovery_target_action = 'promote'
" > $POSTGRES_DB_DIR/recovery.conf
chown -R postgres: $POSTGRES_DB_DIR/*
echo "start postgres"
sleep 3
systemctl start postgresql

Brak komentarzy:
Prześlij komentarz