PostgreSQL è un sistema di gestione di database relazionali (RDBMS) potente e ricco di funzionalità. È gratuito e open source ed è in sviluppo dal 1996. Postgres offre diversi modi di archiviare e replicare i dati, uno dei quali è la replica in streaming. In questa modalità, un'istanza primaria (master) gestisce il database attivo principale ed esegue le operazioni. L'istanza secondaria (slave) copia tutte le modifiche dalla primaria, mantenendo una copia identica del database attivo. Il server secondario può anche accettare query di sola lettura. Se il server primario si guasta, il server secondario può uscire dalla modalità standby e operare come nuovo master (questo si chiama failover).
La replica PostgreSQL di solito si basa sulla registrazione write-ahead (WAL), il processo di registrazione delle modifiche ai dati prima di scriverli su disco. Questi record WAL vengono quindi copiati su un secondo nodo come file (trasmissione di log basata su file) o trasmessi direttamente tra i nodi (replica in streaming). Nella maggior parte dei casi, quest'ultimo riduce il ritardo di ricezione delle modifiche sul nodo master da parte del nodo standby.
Il problema con l'utilizzo della replica in streaming senza il log shipping basato su file è che il server secondario potrebbe perdere alcuni record WAL se il primario li elimina troppo presto. Numerosi parametri di configurazione possono ridurre questo rischio, ma spesso comportano un costo di archiviazione non necessario. La soluzione sono gli slot di replica, una funzionalità fornita da Postgres che garantisce che il server primario scarti i record WAL solo dopo che sono stati ricevuti dal nodo di standby.
Imposteremo la replica in streaming con slot di replica su due nodi Debian 10.
Requisiti
- Due istanze Debian 10 identiche.
- Accesso root a entrambe le istanze.
- La variabile d'ambiente $EDITOR dovrebbe essere impostata su entrambe le istanze.
Passaggio 1:installazione di PostgreSQL
Aggiorna e riavvia entrambi i nodi:
apt update apt upgrade -y reboot
Installa Postgres su entrambi i nodi e assicurati che PostgreSQL sia abilitato e in esecuzione:
apt install -y postgresql systemctl enable --now [email protected]
NOTA:quando si aggiorna PostgreSQL, aggiornare prima lo standby è l'opzione più sicura in base alla loro documentazione.
Fase 2:configurazione iniziale
Per impostazione predefinita, PostgreSQL è in ascolto solo sull'interfaccia di loopback e non è accessibile dall'esterno. Modifica l'indirizzo di ascolto su entrambi i nodi modificando postgresql.conf:
$EDITOR /etc/postgresql/11/main/postgresql.conf
Trova la riga seguente:
#listen_addresses = 'localhost'
Cambialo in:
listen_addresses = 'node_ip_address,127.0.0.1'
Se entrambi i nodi condividono la stessa rete locale, puoi utilizzare indirizzi privati per node_ip_address, anche se Postgres non sarà accessibile a Internet. Altrimenti, usa gli indirizzi pubblici.
Salva la modifica, quindi riavvia entrambe le istanze:
systemctl restart [email protected]
Fase 3:configurazione principale
Questo passaggio riguarda solo il server primario/master.
Apri il terminale Postgres:
sudo -u postgres psql
Il nodo di standby utilizzerà un utente per connettersi al master. Crealo:
postgres=# CREATE ROLE replicator LOGIN REPLICATION ENCRYPTED PASSWORD 'replicator_password';
Quindi crea uno slot di replica ed esci:
postgres=# SELECT * FROM pg_create_physical_replication_slot('replicator'); postgres=# \q
Per semplicità, il ruolo di replica e lo slot sono entrambi denominati "replicatore", sebbene non debbano essere identici.
Quindi, creare una voce in pg_hba.conf per consentire all'utente del replicatore di connettersi dallo standby al master. Aprilo:
$EDITOR /etc/postgresql/11/main/pg_hba.conf
Aggiungi la seguente riga alla fine:
host replication replicator standby_ip_address/32 md5
Riavvia l'istanza master:
systemctl restart [email protected]
Fase 4:backup di base
I comandi in questo passaggio devono essere eseguiti sul server secondario/slave.
Per prima cosa, ferma Postgres sul nodo secondario:
systemctl stop [email protected]
Eseguire il backup della vecchia directory dei dati:
mv /var/lib/postgresql/11/main/ /var/lib/postgresql/11/main.bak
Utilizzare il comando seguente per clonare la directory dei dati del master sullo slave:
pg_basebackup -h master_ip_address -U replicator -D /var/lib/postgresql/11/main/ -P --password --slot replicator
Ti verrà richiesta una password. Immettere la password scelta per il ruolo di replicatore durante la sua creazione sul master. Una volta completato il trasferimento, concedi la proprietà della directory dei dati all'utente postgres:
chown -R postgres:postgres /var/lib/postgresql/11/main
Fase 5:configurazione in standby
Questo passaggio riguarda solo il server secondario/slave.
Abilita la modalità hot standby in postgresql.conf:
$EDITOR /etc/postgresql/11/main/postgresql.conf
Trova e decommenta la seguente riga:
#hot_standby = on
Crea il file recovery.conf nella directory dei dati di Postgres:
$EDITOR /var/lib/postgresql/11/main/recovery.conf
Abilita modalità standby:
standby_mode = 'on'
Impostare i parametri di connessione di replica utilizzando le credenziali create sul master:
primary_conninfo = 'host=master_ip_address port=5432 user=replicator password=replicator_password'
Imposta il nome dello slot di replica che hai creato sul master:
primary_slot_name = 'replicator'
Imposta il percorso su un file di attivazione del failover:
trigger_file = '/var/lib/postgresql/11/main/failover.trigger'
Se il parametro trigger_file è impostato, Postgres uscirà dalla modalità standby e avvierà il normale funzionamento come server primario quando viene creato questo file trigger. Questo parametro non è obbligatorio.
Dopo aver creato recovery.conf, concedi la proprietà all'utente postgres:
chown postgres:postgres /var/lib/postgresql/11/main/recovery.conf
Ora puoi avviare Postgres:
systemctl start [email protected]
Ora è in modalità standby e dovrebbe replicare qualsiasi nuova transazione.
Test
Test della replica
Per testare la replica, eseguire qualsiasi azione di scrittura sul master. Ad esempio, crea un nuovo database sul master:
sudo -u postgres psql -c "CREATE DATABASE replitest"
Attendi qualche secondo, quindi elenca i database sullo slave:
sudo -u postgres psql -c "\l"
Dovresti vedere che il database più replicato è stato effettivamente replicato dal server di standby:
List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -----------+----------+----------+-------------+-------------+----------------------- postgres | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | replitest | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | template0 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres template1 | postgres | UTF8 | en_US.UTF-8 | en_US.UTF-8 | =c/postgres + | | | | | postgres=CTc/postgres (4 rows)
Failover di test
NOTA:il test del failover come mostrato qui richiederà il ripristino del server di standby dopo il failover.
Poiché Postgres è in modalità standby, non dovresti essere in grado di eseguire alcuna operazione di scrittura sul nodo secondario prima del failover. Ad esempio, eseguire il comando seguente:
sudo -u postgres psql -c "CREATE DATABASE test"
Il comando dovrebbe fallire:
ERROR: cannot execute CREATE DATABASE in a read-only transaction
Per segnalare il failover, crea il file trigger specificato in recovery.conf
touch /var/lib/postgresql/11/main/failover.trigger
Attendi qualche secondo, quindi prova a eseguire un'operazione di scrittura. Ad esempio:
sudo -u postgres psql -c "CREATE DATABASE test2"
Poiché Postgres non funziona più come standby, l'operazione avrà esito positivo. Postgres rinominerà anche il tuo file recovery.conf in recovery.done ed eliminerà il file trigger.
Per tornare in standby, ferma Postgres sul (ex) nodo secondario:
systemctl stop [email protected]
Reimposta la directory dei dati:
mv /var/lib/postgresql/11/main/ /var/lib/postgresql/11/main.2.bak pg_basebackup -h master_ip_address -U replicator -D /var/lib/postgresql/11/main/ -P --password --slot replicator chown -R postgres:postgres /var/lib/postgresql/11/main
E ricrea recovery.conf:
cp /var/lib/postgresql/11/main.2.bak/recovery.done /var/lib/postgresql/11/main/recovery.conf
Infine, riavvia Postgres:
systemctl start [email protected]
L'istanza secondaria è ora tornata in modalità standby. Potresti voler testare nuovamente la replica a questo punto.
Finitura
Rimuovere eventuali database non necessari sul nodo master, ad esempio:
sudo -u postgres psql postgres=# DROP DATABASE replitest;
Ed elimina le vecchie directory di dati sul tuo nodo di standby:
rm /var/lib/postgresql/11/main.bak -r rm /var/lib/postgresql/11/main.2.bak -r