Backup postgresql incrementali con pgbackrest: un corso per un giovane combattente dello sviluppatore

Disclaimer

Sono uno sviluppatore. Scrivo codice e interagisco con il database solo come utente. Non pretendo in alcun modo di essere un amministratore di sistema, tanto meno un dba. Ma…

È successo che avevo bisogno di organizzare un backup del database postgresql. Niente cloud: usa semplicemente SSH e assicurati che tutto funzioni senza chiedere soldi. Cosa facciamo in questi casi? Esatto, inseriamo pgdump in cron, eseguiamo il backup di tutto nell'archivio ogni giorno e, se siamo completamente persi, inviamo questo archivio da qualche parte lontano.

Questa volta la difficoltà era che secondo i piani il database avrebbe dovuto crescere di circa +- 100 MB al giorno. Naturalmente, dopo un paio di settimane, la voglia di eseguire il backup di tutto con pgdump scomparirà. È qui che i backup incrementali vengono in soccorso.

Interessante? Benvenuto al gatto.

Il backup incrementale è un tipo di backup in cui non vengono copiati tutti i file di origine, ma solo quelli nuovi e quelli modificati dalla creazione della copia precedente.

Come ogni sviluppatore ASSOLUTAMENTE riluttante (a quel tempo) a comprendere le complessità di Postgres, volevo trovare il pulsante verde. Beh, sai, come in AWS, DigitalOcean: hai premuto un pulsante - hai ottenuto la replica, hai premuto il secondo - hai impostato i backup, il terzo - hai ripristinato tutto un paio d'ore. Non ho trovato un pulsante o un bellissimo strumento GUI. Se ne conosci uno (gratuito o economico), scrivilo nei commenti.

Dopo aver cercato su Google ho trovato due strumenti pgbarman и pgbackrest. Con il primo semplicemente non ci sono riuscito (documentazione molto scarsa, ho cercato di capire tutto secondo vecchi manuali), ma con il secondo la documentazione si è rivelata all'altezza, ma non priva di difetti. Per semplificare il lavoro di chi si trova ad affrontare un compito simile, è stato scritto questo articolo.

Dopo aver letto questo articolo imparerai come eseguire backup incrementali, salvarli su un server remoto (repository con backup) e ripristinarli in caso di perdita di dati o altri problemi sul server principale.

Formazione

Per riprodurre il manuale avrete bisogno di due VPS. Il primo sarà lo storage (il repository su cui verranno archiviati i backup), e il secondo, appunto, il server stesso con postgres (nel mio caso, la versione 11 di postgres).

Si presuppone che sul server con postgres siano presenti root, utente sudo, utente postgres e postgres stesso (l'utente postgres viene creato automaticamente durante l'installazione di postgresql), e sul server repository ci siano root e utente sudo (nel manuale verrà utilizzato il nome utente pgbackrest).

Per avere meno problemi nella riproduzione delle istruzioni, scrivo in corsivo dove, con quale utente e con quali diritti ho eseguito il comando mentre scrivo e controllo l'articolo.

Installazione di pgbackrest

Repository (utente pgbackrest):

1. Scarica l'archivio da pgbackrest e trasferisci il suo contenuto nella cartella /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. Installa le dipendenze necessarie per l'assemblaggio:

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

3. Assemblaggio dello schienale:

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

4. Copia il file eseguibile nella directory /usr/bin:

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

5. Pgbackrest richiede perl. Installare:

sudo apt-get install perl

6. Crea directory per i log, concedi loro determinati diritti:

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

pgbackrest version

Server Postgres (utente sudo o root):

Il processo di installazione di pgbackrest su un server con postgres è simile al processo di installazione sul repository (sì, pgbackrest deve essere installato su entrambi i server), ma nel 6° paragrafo il secondo ed ultimo comando:

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

sostituirlo con:

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

Configurazione dell'interazione tra server tramite SSH senza password

Affinché pgbackrest funzioni correttamente è necessario configurare l'interazione tra il server postgres e il repository utilizzando il file chiave.

Repository (utente pgbackrest):

Crea una coppia di chiavi:

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

Attenzione! Eseguiamo i comandi precedenti senza sudo.

Server Postgres (utente sudo o root):

Crea una coppia di chiavi:

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

Repository (utente sudo):

Copia la chiave pubblica del server postgres sul server del repository:

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

A questo punto ti verrà richiesta la password per l'utente root. Devi inserire la password dell'utente root del server postgres!

Server Postgres (utente sudo):

Copia la chiave pubblica del repository sul server con postgres:

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

A questo punto ti verrà richiesta la password per l'utente root. Devi inserire esattamente la password dell'utente root del repository!

Controlliamo:

Repository (utente root, per la purezza dell'esperimento):

sudo -u pgbackrest ssh postgres@<postgres_server_ip>

Server Postgres (utente root, per la purezza dell'esperimento):

sudo -u postgres ssh pgbackrest@<repository_server_ip>

Ci assicuriamo di ottenere l'accesso senza problemi.

Configurazione di un server Postgres

Server Postgres (utente sudo o root):

1. Permettiamo di bussare al server Postgres da IP esterni. Per fare ciò, modifica il file postgresql.conf (situato nella cartella /etc/postgresql/11/main), aggiungendovi la riga:

listen_addresses = '*'

Se tale riga esiste già, decommentala o imposta il valore del parametro come '*'.

In archivio pg_hba.conf (si trova anche nella cartella /etc/postgresql/11/main) aggiungere le seguenti righe:

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

dove:

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

2. Effettuiamo le impostazioni necessarie postgresql.conf (è nella cartella /etc/postgresql/11/main) affinché pgbackrest funzioni:

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

3. Effettuiamo le impostazioni necessarie nel file di configurazione pgbackrest (/etc/pgbackrest/pgbackrest.conf):

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

[global]
log-level-file=detail
repo1-host=<repository_server_ip>

4. Ricarica postgresql:

sudo service postgresql restart

Configurazione di un server di archivio

Repository (utente pgbackrest):

Effettuiamo le impostazioni necessarie nel file di configurazione pgbackrest
(/etc/pgbackrest/pgbackrest.conf):

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

[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=2 # Параметр, указывающий сколько хранить полных бэкапов. Т.е. если у вас есть два полных бэкапа и вы создаете третий, то самый старый бэкап будет удален. Можно произносить как "хранить не более двух бэкапов" - по аналогии с ротациями логов. Спасибо @Aytuar за исправление ошибки.
start-fast=y # Начинает резервное копирование немедленно, прочитать про этот параметр можно тут https://postgrespro.ru/docs/postgrespro/9.5/continuous-archiving

Creazione di un deposito

Repository (utente pgbackrest):

Crea un nuovo spazio di archiviazione per il cluster principale:

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

Проверка

Server Postgres (utente sudo o root):

Controlliamo sul server Postgres:

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

Repository (utente pgbackrest):

Controlliamo sul server del repository:

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

Ci assicuriamo che nell'output vediamo la riga "check command end: completato con successo".

Stanco? Passiamo alla parte più interessante.

Fare un backup

Repository (utente pgbackrest):

1. Eseguire un backup:

sudo -u pgbackrest pgbackrest --stanza=main backup

2. Assicurati che sia stato creato un backup:

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

Pgbackrest creerà il primo backup completo. Se lo desideri, puoi eseguire nuovamente il comando backup e assicurarti che il sistema crei un backup incrementale.

Se desideri eseguire nuovamente un backup completo, specifica un flag aggiuntivo:

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

Se desideri un output della console dettagliato, specifica anche:

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

Ripristino di un backup

Server Postgres (utente sudo o root):

1. Arrestare il cluster in esecuzione:

sudo pg_ctlcluster 11 main stop

2. Ripristino dal backup:

sudo -u postgres pgbackrest --stanza=main --log-level-console=info --delta --recovery-option=recovery_target=immediate restore

Per ripristinare il database allo stato dell'ultimo backup COMPLETO, utilizzare il comando senza specificare recovery_target:

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

Importante! Dopo il ripristino, può accadere che il database rimanga bloccato in modalità di ripristino (si verificheranno errori come ERROR: impossibile eseguire DROP DATABASE in una transazione di sola lettura). Ad essere sincero, non ho ancora capito a cosa sia collegato. La soluzione è la seguente (dovrai attendere un po' dopo l'esecuzione del comando):

sudo -u postgres psql -c "select pg_wal_replay_resume()"

È infatti possibile ripristinare un backup specifico tramite il suo nome. Eccomi solo Fornirò un collegamento alla descrizione di questa funzionalità nella documentazione. Gli sviluppatori consigliano di utilizzare questa opzione con cautela e spiegano il perché. Posso aggiungere da solo che l'ho usato. Se proprio necessario, assicurati che dopo il ripristino il database esca dalla modalità di ripristino (seleziona pg_is_in_recovery() dovrebbe mostrare "f") e, per ogni evenienza, esegui un backup completo dopo il ripristino.

3. Avvia il cluster:

sudo pg_ctlcluster 11 main start

Dopo aver ripristinato il backup, dobbiamo eseguire un secondo backup:

Repository (utente pgbackrest):

sudo pgbackrest --stanza=main backup

È tutto. In conclusione, vorrei ricordarvi che non sto cercando in alcun modo di fingere di essere un dba senior e utilizzerò le nuvole alla minima occasione. Attualmente io stesso sto iniziando a studiare vari argomenti come backup, replica, monitoraggio, ecc. e scrivo piccoli resoconti sui risultati per dare un piccolo contributo alla comunità e lasciare piccoli foglietti illustrativi per me.

Nei seguenti articoli cercherò di parlare di funzionalità aggiuntive: ripristino dei dati su un cluster pulito, crittografia dei backup e pubblicazione su S3, backup tramite rsync.

Fonte: habr.com

Aggiungi un commento