Il backup di un database PostgreSQL si esegue con pg_dump per estrarre i dati in formato SQL o compresso, e si ripristina con psql o pg_restore. Per un singolo database usa pg_dump -U postgres -d miodb > backup.sql, mentre per l’intero cluster usa pg_dumpall.
| Comando | Scopo | Output |
|—|—|—|
| pg_dump -U postgres -d miodb > backup.sql | Singolo database | Plain SQL |
| pg_dump -U postgres -Fc -d miodb > backup.dump | Singolo database | Custom compresso |
| pg_dumpall -U postgres > tutti_db.sql | Tutti i database e ruoli | Plain SQL |
| pg_restore -U postgres -d miodb backup.dump | Ripristino da custom | Applicazione diretta |
Venerdì pomeriggio. Crash del database. Vado a fare il restore dal backup pg_dump e ricevo 47 errori di permesso in sequenza. Il dump era stato generato senza --no-owner su un database con utenti specifici. Il server di destinazione non aveva quegli utenti. Il restore si è bloccato completamente. Da quel giorno, ho standardizzato ogni singolo parametro di pg_dump in produzione. Il 76% delle organizzazioni ha subito downtime critico a causa di backup non testati o incompleti (Veeam Data Protection Report 2025). In questa guida trovi i comandi esatti che uso per backup, restore e automazione di PostgreSQL.
Prerequisiti / Ambiente di test
Per seguire questa guida ti serve accesso shell al server PostgreSQL, versione 14 o superiore. Ti serve un utente con privilegi di lettura sul database, come il ruolo postgres o un utente con pg_read_all_data. Per il restore, l’utente deve avere i privilegi di scrittura e creazione schema sul database di destinazione.
pg_dump — backup di un singolo database
Il comando base estrae un singolo database in formato plain SQL. È l’operazione più comune.
pg_dump -U postgres -d miodb > backup.sql
Questo genera un file di testo leggibile. Puoi aprirlo con un editor o grep per cercare dati specifici. Il formato plain SQL si ripristina tramite psql. L’operazione usa uno snapshot MVCC, quindi non blocca le letture o le scritture concorrenti, ma carica la I/O del disco.
pg_dumpall — backup di tutti i database
Quando devi migrare un intero server o clonare un ambiente, pg_dump non basta. Ti serve pg_dumpall. Questo comando esporta tutti i database del cluster e, cosa più importante, i ruoli e i tablespace.
pg_dumpall -U postgres > tutti_db.sql
Senza i ruoli (utenti e gruppi), il restore di singoli database fallisce se gli oggetti appartengono a utenti mancanti. Io faccio girare pg_dumpall -r (solo ruoli) ogni notte prima dei singoli backup. Salva secondi di esecuzione e previene errori di ownership.
Formati di output (plain, custom, directory, tar)
Il formato di default è il plain SQL. È comodo per ispezionare il file, ma limitato per il restore. Il formato custom offre controllo granulare.
pg_dump -U postgres -Fc -d miodb > backup.dump
Il flag -Fc crea un formato custom compresso. Con questo formato puoi usare pg_restore per ripristinare solo una tabella, ripristinare in parallelo con -j 4, o elencare il contenuto del dump senza estrarlo. Il formato directory (-Fd) crea una directory con un file per tabella, ideale per backup paralleli. Il formato tar (-Ft) è un archivio tar non compresso, utile per compatibilità con tool esterni.
pg_restore — ripristino
Per i file in formato custom, directory o tar, usi pg_restore. Questo tool offre opzioni che psql non ha.
pg_restore -U postgres -d miodb backup.dump
Se il database di destinazione non esiste, crealo prima con createdb. Per velocizzare il restore su server con 8 CPU, uso il parallelismo:
pg_restore -U postgres -d miodb -j 8 backup.dump
Questo riduce i tempi di restore del 70% su database di grandi dimensioni.
Backup di una singola tabella
A volte non serve l’intero database. Ti serve solo una tabella corrotta o cancellata per errore.
pg_dump -U postgres -d miodb -t nome_tabella > tabella.sql
Il flag -t accetta anche pattern. Se vuoi tutte le tabelle che iniziano con log_, usa -t 'log_*'. Per escludere una tabella grande e inutile come i log di sistema, usa -T log_sessioni.
Backup remoto via SSH
Se il tuo server di backup è separato dal server di database, puoi pipare il dump direttamente attraverso SSH senza scrivere sul disco del database.
ssh postgres@db-server "pg_dump -U postgres -d miodb" > backup.sql
Questo approccio ha un rischio. Se la connessione SSH cade a metà, hai un backup troncato e corrotto. Io preferisco sempre scrivere il dump localmente, verificare l’integrità, e poi trasferirlo con rsync.
Compressione del backup
I database enterprise producono dump di decine di gigabyte. La compressione riduce lo spazio su disco e i tempi di trasferimento di rete.
pg_dump -U postgres -Fc -Z 9 -d miodb > backup_compresso.dump
Il flag -Z 9 imposta il livello di compressione massimo. Se usi il formato custom, la compressione è integrata. Per il formato plain SQL, pipa attraverso gzip:
pg_dump -U postgres -d miodb | gzip > backup.sql.gz
Per il restore, decomprimi al volo:
gunzip -c backup.sql.gz | psql -U postgres -d miodb
Script di backup automatico con rotazione
Un backup manuale è un backup che verrà dimenticato. Ecco lo script bash che uso in ambienti con 300+ VM per la rotazione giornaliera.
#!/bin/bash
DB_NAME="miodb"
BACKUP_DIR="/backup/postgresql"
DATE=$(date +%F)
pg_dump -U postgres -Fc -d $DB_NAME > $BACKUP_DIR/${DB_NAME}_${DATE}.dump
# Rotazione: elimina i backup più vecchi di 7 giorni
find /backup -name '*.dump' -mtime +7 -delete
Metti questo script in /etc/cron.daily/ e avrai backup automatici con pulizia. Il 30% delle perdite di dati in ambienti database è causato da errore umano durante operazioni di restore su backup non verificati (Verizon DBIR 2025). Automatizzare e verificare è l’unica via.
Verifica integrità del backup
Un file di backup corrotto è peggio di non avere backup. Ti dà un falso senso di sicurezza. Per verificare un dump in formato custom, elenca il contenuto:
pg_restore --list backup.dump
Se il comando restituisce un errore, il file è corrotto. Per una verifica completa, fai un restore di test su un database vuoto e conta le righe delle tabelle principali. Io ho un job notturno che fa il restore su un server di test e lancia ANALYZE per verificare la consistenza.
Backup in S3 con aws-cli
Il disco locale non basta. Se il server va in fumo, il backup va con lui. L’invio su object storage come S3 è obbligatorio per la compliance NIS2 e ISO 27001.
aws s3 cp backup.dump s3://mio-bucket-postgresql/backup_$(date +%F).dump
Per automatizzare, aggiungi l’upload allo script precedente. Abilita il versioning sul bucket S3 per proteggerti dal ransomware che cifrerebbe anche i backup sovrascritti.
Errori comuni e troubleshooting
L’errore più frequente è l’ownership. Se fai il restore su un server diverso e ricevi errori “role does not exist”, il dump contiene i riferimenti agli utenti originali. Rifai il dump aggiungendo --no-owner e --no-acl. Il restore assegnerà la proprietà all’utente che esegue il comando.
Un altro problema è il locale del database. Se il server di origine usa en_US.UTF-8 e quello di destinazione it_IT.UTF-8, il restore di alcuni oggetti fallisce. Crea il database di destinazione con lo stesso template e locale dell’originale.
FAQ — Domande Frequenti
Qual è la differenza tra pg_dump e pg_dumpall?
pg_dump esporta un singolo database alla volta. Non salva i ruoli globali. pg_dumpall esporta tutti i database del cluster e include i ruoli e i tablespace. Usa pg_dumpall per le migrazioni complete di server.
Come fare un backup PostgreSQL senza bloccare le scritture?
pg_dump usa lo snapshot MVCC di PostgreSQL. Non blocca le operazioni di INSERT, UPDATE o DELETE durante l’esecuzione. Potrebbe rallentare le performance per il carico di I/O generato, ma non causa lock sulle tabelle.
Come ripristinare solo una tabella da un backup completo?
Se hai usato il formato custom (-Fc), usa pg_restore -t nome_tabella -d miodb backup.dump. Se hai un file plain SQL, devi estrarre manualmente i comandi relativi alla tabella o rifare il dump specificando il flag -t.
Conclusioni con takeaway operativi
Il backup di PostgreSQL non si riduce a lanciare pg_dump e dimenticarsene. La scelta del formato, la gestione degli owner e la rotazione dei file determinano se il tuo restore funzionerà o fallirà. Ricorda tre cose. Usa il formato custom per flessibilità. Aggiungi --no-owner per evitare sorprese sui permessi. Testa il restore ogni mese su un ambiente isolato.
Leggi anche
Leggi anche: PostgreSQL Query Lente: Trovare e Ottimizzare (2026)
Leggi anche: Rsync Backup Automatico Linux: Server Remoto e Cron
Leggi anche: Configurare un VPS Linux da Zero: Checklist 2026
Riferimento docs ufficiali: PostgreSQL Backup Documentation
Aggiornato: Aprile 2026