Database

PostgreSQL Replica: Monitora il Ritardo tra Sedi

PostgreSQL Replica: Monitora il Ritardo tra Sedi

La gestione di database critici in ambienti enterprise richiede soluzioni di alta disponibilità e disaster recovery robuste. Tra queste, la replica continua di PostgreSQL tra sedi geograficamente distanti è una pratica fondamentale per garantire la continuità operativa e minimizzare la perdita di dati. Tuttavia, una replica asincrona, pur offrendo flessibilità e prestazioni, introduce il rischio di un ritardo (lag) che, se non monitorato e gestito, può compromettere seriamente il Recovery Point Objective (RPO) in caso di failover. Ho visto scenari dove un RPO di pochi secondi si trasformava in minuti, o addirittura ore, a causa di un ritardo di replica sottovalutato, con conseguenze disastrose per il business. Questo articolo esplora come configurare e, soprattutto, monitorare efficacemente il ritardo di replica di PostgreSQL, basandosi su un’esperienza reale di implementazione e gestione in un ambiente critico.

Testato su: PostgreSQL 15 · Ubuntu 22.04 LTS · Settembre 2026

Prerequisiti / Ambiente di test

Per implementare la replica continua e il relativo monitoraggio, è necessario disporre di due server PostgreSQL, uno configurato come master (primario) e l’altro come standby (replica), preferibilmente su reti e data center distinti. Assicurati che i due server possano comunicare sulla porta di PostgreSQL (tipicamente 5432) e che il traffico sia sicuro (es. tramite VPN o tunnel SSH). Per questo setup, useremo due istanze PostgreSQL 15 su Ubuntu 22.04 LTS. È fondamentale avere un utente dedicato alla replica con privilegi adeguati e che i filesystem dei server abbiano spazio sufficiente per i Write-Ahead Logs (WAL).

1. Configurazione del server Master (Primario)

Il primo passo è configurare il server master per consentire la replica. Modifica il file postgresql.conf (solitamente in /etc/postgresql/15/main/postgresql.conf) con i seguenti parametri:

wal_level = replica
archive_mode = on
archive_command = 'cp %p /mnt/pg_wal_archive/%f'
max_wal_senders = 10
listen_addresses = '*'
  • wal_level = replica: abilita la scrittura delle informazioni necessarie per la replica nei WAL.
  • archive_mode = on: abilita l’archiviazione dei segmenti WAL completati. archive_command specifica come archiviare i file. In un ambiente di produzione, si userebbe un sistema di storage remoto (NFS, S3, ecc.) o uno strumento come pg_basebackup o barman per l’archiviazione e il recupero. Per il nostro test, useremo una semplice copia locale.
  • max_wal_senders = 10: definisce il numero massimo di processi walsender che possono essere avviati. Ogni standby richiede un walsender.
  • listen_addresses = '*': permette a PostgreSQL di accettare connessioni da qualsiasi indirizzo IP. In produzione, è consigliabile specificare indirizzi IP specifici o subnet per motivi di sicurezza.

Successivamente, modifica il file pg_hba.conf per consentire alla replica di connettersi. Aggiungi una riga simile a questa:

host    replication     all             <IP_STANDBY>/32         md5

Sostituisci con l’indirizzo IP del tuo server standby. Crea un utente di replica:

CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'your_secure_password';

Riavvia il servizio PostgreSQL sul master per applicare le modifiche:

sudo systemctl restart postgresql@15-main

2. Preparazione del server Standby (Replica)

Prima di configurare lo standby, è necessario creare una base di partenza (base backup) dal master. Questo può essere fatto con pg_basebackup direttamente dal server standby:

sudo -u postgres pg_basebackup -h <IP_MASTER> -D /var/lib/postgresql/15/main -U replicator -P -v -R
  • -h : indirizzo IP del server master.
  • -D /var/lib/postgresql/15/main: directory dei dati di PostgreSQL sul server standby.
  • -U replicator: utente di replica creato in precedenza.
  • -P: mostra il progresso.
  • -v: output verboso.
  • -R: crea automaticamente un file standby.signal e aggiunge le configurazioni necessarie a postgresql.auto.conf per avviare lo standby. Questo sostituisce il vecchio recovery.conf nelle versioni recenti di PostgreSQL.

Se utilizzi una versione più vecchia di PostgreSQL che richiede recovery.conf, il comando -R genererà un file recovery.conf con il seguente contenuto (o simile):

standby_mode = 'on'
primary_conninfo = 'host=<IP_MASTER> port=5432 user=replicator password=your_secure_password application_name=standby1'
primary_slot_name = 'standby_slot'

Assicurati che primary_conninfo contenga l’indirizzo IP corretto del master e la password dell’utente replicator.

Avvia il servizio PostgreSQL sullo standby:

sudo systemctl start postgresql@15-main

Verifica lo stato della replica sul master con ps aux | grep walsender e sullo standby con ps aux | grep walreceiver. Dovresti vedere i processi attivi. Leggi anche: PostgreSQL: Trova la Query Killer con pg_stat_statements

3. Monitoraggio del ritardo di replica

Il monitoraggio del ritardo di replica è cruciale. PostgreSQL fornisce funzioni built-in per questo scopo. Connettiti al database sul server standby e usa la seguente query:

SELECT pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn(),
       (pg_wal_lsn_diff(pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn())) AS byte_lag,
       (EXTRACT(EPOCH FROM now() - pg_last_xact_replay_timestamp())) AS time_lag_seconds;
  • pg_last_wal_receive_lsn(): l’LSN (Log Sequence Number) dell’ultimo record WAL ricevuto dallo standby.
  • pg_last_wal_replay_lsn(): l’LSN dell’ultimo record WAL applicato (replay) dallo standby.
  • byte_lag: la differenza in byte tra i WAL ricevuti e quelli applicati. Un valore maggiore indica un ritardo in termini di dati.
  • time_lag_seconds: il ritardo in secondi basato sul timestamp dell’ultima transazione replayata. Questo è spesso il dato più rilevante per l’RPO.

Un ritardo byte_lag o time_lag_seconds costantemente superiore a zero indica che la replica è asincrona. Se questi valori aumentano in modo significativo, significa che lo standby non riesce a tenere il passo con il master. Leggi anche: Oracle DBA Checklist: 10 Verifiche Quotidiane per un Database in Produzione (2026)

È possibile creare una tabella e una funzione per registrare il ritardo nel tempo, per analisi storiche e per integrare con sistemi di monitoraggio come Prometheus o Zabbix:

CREATE TABLE replica_lag_history (
    timestamp TIMESTAMPTZ DEFAULT now(),
    byte_lag BIGINT,
    time_lag_seconds INT
);

CREATE OR REPLACE FUNCTION record_replica_lag()
RETURNS VOID AS $$
DECLARE
    current_byte_lag BIGINT;
    current_time_lag_seconds INT;
BEGIN
    SELECT (pg_wal_lsn_diff(pg_last_wal_receive_lsn(), pg_last_wal_replay_lsn())) INTO current_byte_lag;
    SELECT (EXTRACT(EPOCH FROM now() - pg_last_xact_replay_timestamp())) INTO current_time_lag_seconds;

    INSERT INTO replica_lag_history (byte_lag, time_lag_seconds)
    VALUES (current_byte_lag, current_time_lag_seconds);
END;
$$ LANGUAGE plpgsql;

-- Esegui ogni minuto
SELECT cron.schedule('record_replica_lag', '* * * * *', 'SELECT record_replica_lag();');

Leggi anche: Ansible vs Script: Gestire 200 Server

Errori comuni e troubleshooting

  • Connessione rifiutata: Controlla pg_hba.conf sul master e le regole del firewall. Assicurati che la porta 5432 sia aperta e che l’utente replicator abbia i permessi corretti.
  • Standby non si avvia: Verifica i log di PostgreSQL sul server standby (/var/log/postgresql/postgresql-15-main.log). Errori comuni includono primary_conninfo errato, directory dati non vuota prima di pg_basebackup, o problemi di permessi.
  • Ritardo di replica elevato: Questo può essere causato da diverse fattori: insufficiente I/O sul server standby, rete lenta tra master e standby, carico eccessivo sul master che genera troppi WAL, o risorse insufficienti sullo standby per applicare i WAL. Controlla le metriche di I/O, CPU e network su entrambi i server. Un link esterno utile per approfondire è la documentazione ufficiale di PostgreSQL sulla Streaming Replication.

FAQ — Domande Frequenti

La replica asincrona garantisce zero perdita di dati?

No, la replica asincrona non garantisce RPO zero. C’è sempre un potenziale ritardo tra il momento in cui una transazione viene commessa sul master e quando viene applicata sullo standby. In caso di crash improvviso del master, le transazioni non ancora replicate sullo standby andranno perse. Per RPO zero, è necessaria la replica sincrona, che però introduce latenza nelle scritture sul master.

Come posso ridurre il ritardo di replica?

Per ridurre il ritardo, assicurati che il server standby abbia risorse hardware (CPU, RAM, I/O) adeguate per elaborare i WAL. Ottimizza la rete tra master e standby per ridurre la latenza e aumentare la banda. Sul master, valuta l’ottimizzazione delle query per ridurre la quantità di WAL generati. Se il ritardo è persistente e inspiegabile, potrebbe essere necessario scalare orizzontalmente o verticalmente.

Posso usare lo standby per letture?

Sì, uno dei vantaggi principali della replica è la possibilità di utilizzare il server standby come server di sola lettura (read-only) per bilanciare il carico delle query. Questo è noto come Read Replica. Assicurati di indirizzare le query di lettura al server standby per alleggerire il carico sul master e migliorare le performance complessive del sistema.

Cosa succede se il master va giù?

Se il master fallisce, dovrai promuovere manualmente (o automaticamente con strumenti come pg_auto_failover o Patroni) uno degli standby a nuovo master. Il processo di promozione applicherà tutti i WAL ricevuti e non ancora applicati, e poi lo standby inizierà ad accettare scritture. È fondamentale avere un processo di failover ben documentato e testato.

Conclusioni con takeaway operativi

La replica continua di PostgreSQL è un pilastro della resilienza infrastrutturale per i database. L’implementazione di una replica asincrona tra due sedi, come descritto, offre un buon equilibrio tra performance e protezione dei dati. Tuttavia, il valore reale di questa configurazione emerge solo se il ritardo di replica viene costantemente monitorato. Ignorare questo aspetto significa operare con un RPO sconosciuto, una scommessa troppo rischiosa per qualsiasi ambiente di produzione. Integrare le metriche di ritardo con il sistema di monitoraggio centrale e impostare alert automatici è un’azione non negoziabile per garantire che il tuo piano di disaster recovery sia sempre allineato alle aspettative.

Fonti

Condividi questo articolo:

Scritto da

Rosario Giordano

Rosario Giordano è System Administrator e consulente IT specializzato in cybersecurity e cloud, con oltre 20 anni di esperienza nella gestione di infrastrutture Linux enterprise. Le sue aree di competenza includono hardening di SSH, piattaforme Kubernetes, database PostgreSQL, ambient i virtualizzati VMware e Proxmox, nonché la conformità ai framework di sicurezza NIS2 e ISO 27001.