Documentazione di PostgreSQL 9.0 > Amministrazione del server > Backup e ripristino > Archiviazione continua e Ripristino Point-In-Time (PITR)
PrecedenteBackup a livello di file systemMigrazioni fra versioniSuccessivo

24.3. Archiviazione continua e Ripristino Point-In-Time (PITR)

In ogni momento, PostgreSQL™ tiene un write ahead log (WAL) nella sottodirectory pg_xlog/ della directory dei dati del cluster. Il log registra ogni cambiamento fatto ai file dei dati del database. Questo log esiste principalmente per motivi di sicurezza rispetto ai crash: se il sistema si blocca, il database può essere ripristinato alla consistenza facendo un «replay» delle voci di log dall'ultimo punto di controllo (checkpoint). Comunque, l'esistenza del log rende possibile una terza strategia per effetuare il backup dei database: è possibile combinare un backup a livello di file system con un backup dei file WAL. Se è necessario un recupero, ripristinare il backup e successivamente fare un replay di ogni voce dai file WAL del backup per portare il sistema allo stato corrente. Questo approccio è più complesso da amministrare rispetto i precedenti approcci, ma ha alcuni vantaggi significanti:

  • Non si avrà bisogno di un backup a livello di file system perfettamente consistente come punto di partenza. Ogni inconsistenza interna nel backup verrà corretta dal replay del log (questo non è significativamente diverso da cosa accade durante un recupero da un crash). Così non si avrà bisogno di capacità di snapshot del file system, basterà tar o uno strumento di archiviazione simile.

  • Dato che è possibile combinare sequenze di file WAL indefinitamente lunghe per il replay, un backup continuo può essere realizzato semplicemente continuando ad archiviare i file WAL. Questo è particolarmente vantaggioso per grandi database, dove potrebbe non essere conveniente eseguire un backup completo frequentemente.

  • Non è necessario fare il replay delle voci WAL sempre fino alla fine. È possibile fermare il replay in qualsiasi momento e avere una snapshot consistente del database com'era in quel momento. Così, questa tecnica supporta recuperi point-in-time: è possibile ripristinare il database al suo stato in ogni momento da quando è stato effettuato il backup di base.

  • Se si alimenta continuamente un'altra macchina, che è stata caricata con lo stesso file backup di base, con la serie di file WAL, si ottiene un sistema di warm standby: in ogni istante è possibile tirare su la seconda macchina e avremo una copia del database corrente.

[Nota]

Nota

pg_dump e pg_dumpall non producono backup a livello di file system e non possono essere usati come parte si una soluzione di archiviazione continua. Quei dump sono logici e non contengono abbastanza informazioni da essere usati come replay WAL.

Come con la tecnica del backup semplice a livello di file system, questo metodo supporta il ripristino di un intero cluster, non di un sottoinsieme. Inoltre, richiede molto spazio per l'archiviazione: il backup di base potrebbe essere voluminoso, e un sistema impegnato genererà molti megabute di traffico WAL che devono essere archiviati. Inoltre, è la tecnica di backup preferita in molte situazioni dove è necessaria alta affidabilità.

Per recuperare con successo usando l'archiviazione continua (chiamata anche «backup online» da molti commercianti di database), si ha bisogno di continue sequenze di file WAL archiviati che si estendono all'indietro almeno al momento di inizio del backup. Così, per iniziare, si dovrebbe impostare e testare la procedura per l'archiviazione dei file WAL prima di effettuare il backup di base. Di conseguenza, verranno discussi prima i meccanismi di archiviazione dei file WAL.

24.3.1. Impostare l'archiviazione WAL

Parlando in senso astratto, un sistema PostgreSQL™ in esecuzione produce una sequenza di record WAL indefinitamente lunga. Il sistema fisicamente divide questa sequenza in file di segmento WAL, che normalmente sono di 16MB (anche se la dimensione del segmento può essere modificata durante la compilazione di PostgreSQL™). Ai file di segmento vengono dati nomi numerici che rispecchiano la loro posizione nella sequenza WAL astratta. Quando non si usa l'archiviazione WAL, il sistema normalmente crea solo pochi file segmento e successivamente li «ricicla» rinominando i file segmento non più necessari in numeri di segmento più alti. Si assume che i file segmento il cui contenuto precede il checkpoint precedente all'ultimo non siano di interesse e possano essere riciclati.

Quando si archiviano dati WAL, si deve catturare il contenuto di ogni file segmento una volta che è pieno, e salvare quei dati da qualche parte prima che il file segmento sia riciclato. A seconda dell'applicazione e dell'hardware disponibile, ci possono essere molti modi diversi di «salvare i dati da qualche parte»: è possibile copiare i file segmento in una directory montata con NFS in un'altra macchina, scriverli su un drive a nastro (assicurandosi che ci sia un modo per indentificare il nome originale di ogni file), o raggrupparli e scriverli su CD, o qualcos'altro, Per dare all'amministratore di database flessibità, PostgreSQL™ non tenta di prevede come l'archiviazione verrà fatta. Al contrario, PostgreSQL™ lascia che l'amministratore specifichi un comando shell da essere eseguito per copiare un file segmento completo verso ovunque debba andare. Il comando può essere semplice come un cp, o può invocare uno script shell complesso - è a vostra discrezione.

Per abilitare l'archiviazione WAL, impostare il parametro di configurazione wal_level a archive (o hot_standby), archive_mode a on, e specificare il comando shell da usare nel parametro di configurazione linkend="guc-archive-command"/>. In pratica queste impostazioni saranno sempre posizionate nel file postgresql.conf. In archive_command, %p è sostituito dal percorso del file da archiviare, mentre %f è sostituito dal nome del file. (Il percorso è relativo alla directory di lavoro corrente, per esempio, la directory dati del cluster). Usare %% se si ha necessità di includere il carattere % nel comando. Il comando più semplice è qualcosa simile a:

archive_command = 'cp -i %p /mnt/server/archivedir/%f </dev/null'

che copierà i segmenti WAL archiviabili nella directory /mnt/server/archivedir. (Questo è un esempio, non una raccomandazione, e potrebbe non funzionare su tutte le piattaforme). Dopo che i parametri %p e %f sono stati sostituiti, il comando potrebbe somigliare a questo:

cp -i pg_xlog/00000001000000A900000065 /mnt/server/archivedir/00000001000000A900000065 </dev/null

Un comando simile sarà generato per ogni nuovo file che deve essere archiviato.

Il comando archive sarà eseguito sotto la stessa proprietà dello stesso utente col quale il server PostgreSQL™ è in esecuzione. Dato che le serie di file WAL archiviate contengono effettivamente ogni cosa del database, si vorrà essere sicuri che i dati archiviati siano protetti da occhi indiscreti; per esempio, archiviarli in una directory che non ha accesso in lettura per il gruppo o per il mondo.

È importante che il comando di archiviazione restituisca zero come stato di uscita se e solo se ha successo. Se ottiene come risultato zero, PostgreSQL™ assumerà che il file è stato archiviato con successo, e lo rimuoverà o lo riciclerà. Comunque, uno stato non zero dice a PostgreSQL™ che il file non è stato archiviato; e periodicamente verrà fatto un tentativo finchè non avrà successo.

Il comando di archiviazione dovrebbe generalmente essere pensato per rifiutare di sovrascrivere i file di archivio pre-esistenti. Questa è una caratteristica importante per la sicurezza, per preservare l'integrità dell'archivio in caso di errori dell'amministratore (tipo l'invio dell'output di due differenti server alla stessa directory d'archivio). È consigliabile testare il comando d'archiviazione per assicurare che effettivamente non sovrascriva file esistenti, e che in quel caso restituisca stato non zero. Su molte piattaforme Unix, cp -i fa si che la copia chieda prima di sovrascrivere un file, e < /dev/null causa il fallimento in caso di sovrascrittura. Se la piattaforma usata non supporta questo comportamento, si dovrebbe aggiungere un comando per testare l'esistenza del file archivio. Per esempio, qualcosa simile a:

archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f'

funziona correttamente sulla maggior parte delle varianti Unix.

Quando si progetta il setup di archiviazione, considerare cosa accadrà se il comando di archiviazione fallisce ripetutamente, se per esempio qualche aspetto richiede l'intervento dell'opertore o l'archivio eccede lo spazio disponibile. Per esempio, questo puù accadere se si scrive su nastro senza un sostitutore automatico; quando il nastro è pieno, non è possibile archiviare niente finchè il nastro non viene sostituito. Ci si dovrebbe assicurare che ogni condizione d'errore o richiesta di intervento umano venga riportato appropriamente in modo che la situazione possa essere risolta ragionevolmente velocemente. La directory pg_xlog/ continuerà a riempirsi con file segmento WAL finchè la situazione non è risolta. (Se il file system contenente pg_xlog/ è pieno, PostgreSQL™ produrrà un arresto PANIC. Le transazioni che non hanno eseguito il commit saranno perse, ma il database rimarrà offline finchè non si libera un po' di spazio).

La velocità del comando di archiviazione non è impotante dato che può tenere il passo con la velocità media con la quale il server genera dati WAL. Le normali operazioni continuano anche se il processo di archiviazione resta un po' indietro. Se l'archiviazione rimane molto indietro, questo incrementerà l'ammontare dei dati che possono essere persi in caso di disastro. Questo significherà anche che la directory pg_xlog/ conterrà grandi quantità di file segmento non ancora archiviati, che eventualmente possono eccedere lo spazio su disco disponibile. È consigliabile controllare il processo di archiviazione per essere sicuri che funzioni come si vuole.

Nello scrivere il comando di archivio, si dovrebbe assumere che i nomi dei file da archiviare possano essere lunghi più di 64 caratteri e possano contenere qualsiasi combinazione di lettere ASCII, cifre, e punti. Non è necessario preservare il percorso relativo originale (%p) ma è necessario preservare il nome del file (%f).

Notare che sebbene l'archiviazione WAL permetterà il ripristino di qualsiasi modifica fatta ai dati del database PostgreSQL™, essa non ripristinerà i cambiamenti fatti ai file di configurazione (tipo, postgresql.conf, pg_hba.conf e pg_ident.conf), dato che questi file sono modificati manualmente piuttosto che attraverso operazioni SQL. Si potrebbe desiderare mantere i file di configurazione in una posizione che sarà sottoposta a backup dalle normali procedure di backup a livello di file system. Si veda Sezione 18.2, «Posizioni dei file» per capire come trasferire i file di configurazione.

Il comando di archiviazione viene invocato solo su segmenti WAL completati. Da ora, se il server genera solo poco traffico WAL (oppure ha periodi morti in cui accade), ci potrebbe essere molto ritardo tra il completamento di una transazione e la sua registrazione sicura nello spazio di archiviazione. Per mettere un limite a come possanno essere i vecchi dati non archiviati, è possibile impostare archive_timeout per forzare il server a passare a un nuovo file segmento WAL come minimo ogni tot. Notare che i file archiviati che sono archiviati prima a causa dell'opzione vista sopra sono sempre della stessa lunghezza di file completamente pieni. Non è comunque saggio impostare un archive_timeout molto piccolo -- gonfierà lo spazio di archiviazione. Impostare archive_timeout a circa un minuto di solito è ragionevole.

Inoltre, è possibile forzare un cambiamento di segmento manualmente con pg_switch_xlog se si vuole assicurare che una transazione appena terminata venga archiviata il più presto possibile. Altre funzioni utili relative alla gestione del WAL sono elencate nella Tabella 9.56, «Funzioni di controllo del backup».

Quando wal_level è minimal alcuni comandi SQL sono ottimizzati per evitare il log di WAL, come descritto in Sezione 14.4.7, «Disabilitare l'archiviazione WAL e la replica streaming». Se l'archiviazione o la replicazione streaming sono state attivate durante l'esecuzione di una di queste istruzioni, WAL non conterrebbe abbastanza informazioni per il recupero dell'archivio. (Il recupero dal crash non viene toccato). Per questa ragione, wal_level può essere cambiato solo all'avvio del server. Comunque, archive_command può essere cambiato con un ricaricamento del file di configurazione. Se si desidera fermare temporaneamente l'archiviazione, un modo di farlo è impostando archive_command a una stringa vuota (''). Questo farà si che i file WAL si accumolino in pg_xlog/ fino a che non viene stabilito un archive_command funzionante.

24.3.2. Realizzare un backup di base

La procedura per realizzare un backup di base è relativamente semplice:

  1. Assicurare che l'archiviazione WAL sia abilitata e funzionante.

  2. Connettersi al database come superurtente e immettere il comando:

    SELECT pg_start_backup('label');
    

    dove label è qualsiasi stringa si voglia usare per indentificare in modo univoco l'operazione di backup. (Una buona pratica è usare il percorso completo nel quale si intende mettere il file dump di backup). pg_start_backup crea un file etichetta di backup, chiamato backup_label, nella directory cluster, con informazioni sul backup, incluso l'orario di inizio e la stringa etichetta.

    Non importa a quale database all'interno del cluster ci si connette per lanciare questo comando. È possibile ignorare il risultato restituito dalla funzione; ma se viene riportato un errore, crercare di ricolverlo prima di procedere.

    In maniera predefinita, pg_start_backup può metterci molto tempo per finire. Questo perchè esegue un checkpoint, e l'I/O richiesto per il checkpoint sarà spalmato in un periodo di tempo significativo, automaticamente metà dell'intervallo tra i checkpoint (si veda il parametro di configurazione checkpoint_completion_target). Questo di solito è quello che vuoi, dato che minimizza l'impatto sull'elaborazione della query. Se si vuole avviare il backup appena possibile, usare:

    SELECT pg_start_backup('label', true);
    

    Questo fa sì che il checkpoint sia fatto il più velocemente possibile.

  3. Esegue il backup, usando qualsiasi strumento utile per il backup a livello di file system, come tar o cpio (non pg_dump o pg_dumpall). Non è necessario nè auspicabile fermare le normali operazioni sul database mentre lo si fà.

  4. Connettersi nuovamente al database come superutente, e lanciare il seguente comando:

    SELECT pg_stop_backup();
    

    Questo termina la modalità backup e compie un cambiamento automatico al prossimo segmento WAL. La ragione per il cambiamento è di prendere accordi che l'ultimo segmento WAL scritto durante l'intervallo di backup sia pronto per l'archiviazione.

  5. Una volta che i segmenti WAL attivi durante il backup sono archiviati, si è finito. Il file identificato dal risultato di pg_stop_backup è l'ultimo segmento richiesto per formare un insieme completo di file di backup. Se archive_mode è attivo, pg_stop_backup non restituisce niente finchè l'ultimo segmento è stato archiviato. L'archiviazione di questi file avviene automaticamente dato che si è già configurato l'archive_command. In molti casi questo avviene velocemente, ma si consiglia di controllare il sistema di archiviazione per assicurarsi che non ci siano ritardi. Se il processo di archiviazione è rimasto indietro causa fallimenti del comando d'archiviazione, continuerà a provare finchè l'archiviazione non avrà successo e il backup è completo. Se si desidera impostare un limite di tempo all'esecuzione di pg_stop_backup, specificare un valore appropriato per statement_timeout.

Alcuni strumenti di backup a livello di file system producono warning o errori se i file che stanno tentando di copiare cambiano mentre la copia procede. Quando si prende un backup base di un database attivo, questa situazione è normale e non un errore. Comunque, è necessario assicurarsi di poter distinguere queste situazioni da errori reali. Per esempio, alcune versioni di rsync restituiscono un codice di errore separato per «file sorgente spariti», ed è possibile scrivere uno script che accetti questo codice d'uscita non come un erroe. Inoltre, alcune versioni di GNU tar restituiscono un codice di errore indistinguibile da un errore fatale se un file viene troncato mentre tar lo sta copiando. Fortunatamente, le versioni di GNU tar dalla 1.6 e successive terminano con 1 se un file è cambiato durante il backup e 2 per gli altri errori.

Non è necessario preoccuparsi dell'ammontare di tempo passato tra pg_start_backup e l'inizio del backup attuale, e nemmeno tra la fine del backup e pg_stop_backup; pochi minuti di ritardo non saranno dannosi. (Comunque, se normalmente si esegue il server con full_page_writes disaiblitata, si potrebbe notare un calo delle prestazioni tra pg_start_backup e pg_stop_backup, dato che full_page_writes è effettivamente forzata a "on" durante la modilità backup). È necessario assicurare che questi passi siano svolti in sequenza, senza qualsiasi possibile sovrapposizione, o il backup sarà invalidato.

Assicurarsi che il dump di backup includa tutti i file sotto la directory cluster (per es. /usr/local/pgsql/data). Se si stanno usando tablespace che non stanno in questa directory, fare attenzione ad includerli (e assicurarsi che il dump di backup archivi link simbolici come link, altrimenti il ripristino rovinerà i tablespace).

È possibile, comunque, omettere dal dump di backup i file dentro la sottodirectory pg_xlog/ del cluster. Questo piccolo aggiustamento è utile in quanto riduce il rischio di errori durante il ripristino. Questo è facile da realizzare se pg_xlog/ è un link simbolico che punta fuori dalla directory cluster, che comunque è una pratica comune per questioni di prestazione.

Per fare uso del backup, si dovrà tenere tutti i file segmento WAL generati durante e dopo il backup a livello di file system. Per aiutarti a farlo, la funzione pg_stop_backup crea un file storico di backup che viene immediatamente immagazzinato nell'aria di archivio WAL. Questo file è nominato dopo il primo file segmento WAL di cui si ha bisogno per il backup. Per esempio, se il file WAL di partenza è 0000000100001234000055CD il file storico di backup sarà chiamato 0000000100001234000055CD.007C9330.backup. (La seconda parte del nome del file sta per l'esatta posizione all'interno del file WAL, e puà essere tranquillamente ignorata). Una volta che i file segmento WAL e quelli di backup usati durante il backup sono stati archiviati in modo sicuro (come specificato nel file storico di backup), tutti i segmenti WAL archiviati con nomi numericamente minori non sono più necessari per recuperare il backup a livello di file system e possono essere eliminati. Comunque, si dovrebbe considerare il mantenimento di diversi insiemi di backup per essere assolutamente certi che si possano recuperare i dati.

Il file storico di backup è solo un piccolo file di testo. Esso contiene l'etichetta fornita a pg_start_backup, così come gli orari di inizio e fine e i segmenti WAL del backup. Se si è usata l'etichetta per identificare il file dump associato, allora il file storico archiviato è sufficiente a dirti quale file dump ripristinare.

Dato che si sono tenuti tutti i file WAL archiviati dall'ultimo backup, l'intervallo tra i backup di base dovrebbe essere, di solito, scelto basandosi su quanto spazio di immagazzinamento di vuole dedicare ai file WAL archiviati. Si dovrebbe considerare anche il tempo che si preparati a spendere per il recupero, se il recupero è necessario - il sistema dovrà fare il replay di tutti quei segmenti WAL, e questo potrebbe prendere un po' di tempo se è passato molto tempo dall'ultimo backup di base.

È importante anche notare che la funzione pg_start_backup crea un file chiamato backup_label nella directory di cluster, che viene rimosso da pg_stop_backup. Questo file sarà certamente archiviato come parte del file dump di backup. Il file etichetta di backup include la stringa fornita a pg_start_backup, così come l'orario dell'avvio di pg_start_backup, e il nome del file di partenza del WAL. In caso di confuzione è inoltre possibile guardare nel file dump di backup e determinare esattamente da quale sessione di backup arriva il file dump

[Avvertimento]

Avvertimento

TODO

It is also possible to make a backup dump while the server is stopped. In this case, you obviously cannot use pg_start_backup or pg_stop_backup, and you will therefore be left to your own devices to keep track of which backup dump is which and how far back the associated WAL files go. It is generally better to follow the continuous archiving procedure above.

24.3.3. Ripristino usando un backup ad archiviazione continua

Ok, il peggio è successo e si ha bisogno di recuperare dati da un backup. Ecco la procedura:

  1. Fermare il server, se è in esecuzione.

  2. Se si ha lo spazio per farlo, copiare l'intera directory di cluster ed ogni tablespace in un luogo temporaneo nel caso in cui se ne abbia bisogno più tardi. Notare che questa precauzione richiederà che si abbia abbastanza spazio libero sul sistema da contenere due copie dei database esistenti. Se non si ha sufficiente spazio su disco, si dovrebbe almeno salvare il contenuto della sottodirectory del cluster pg_xlog, dato che potrebbe contenere log che non sono stati archiviati prima che il sistema sia caduto.

  3. Rimuovere tutti i file e le sottodirectory esistenti nella directory di cluster e sotto le directory radice dei tablespace che si stanno usando.

  4. Ripristinare i file del database dal proprio backup di file system. Assicurarsi che siano ripristinati con la giusta proprietà (l'utente del sistema database, non root!) e con i giusti permessi. Se si stanno usando tablespace, si dovrebbe verificare che i link simbolici in pg_tblspc/ siano stati ripristinati correttamente.

  5. Rimuovere qualsiasi file presente in pg_xlog/; questi arrivano dal backup a livello di file system e quindi probabilmente sono obsoleti. Se non si è archiviato pg_xlog/ per niente, allora crearlo con i giusti permessi, facendo attenzione a impostarlo come link simbolico se lo era precedentemente.

  6. Se si hanno file segmento WAL non archiviati salvati dal passo 2, copiarli in pg_xlog/. (È meglio copiarli, non spostarli, così da avere comunque i file non modificati se succedesse qualche problema e di dovesse cominciare tutto daccapo).

  7. Creare un file di recupero recovery.conf nella directory di cluster (si veda Capitolo 26, Recovery Configuration). Si potrebbe anche voler modificare temporaneamente pg_hba.conf per impedire a utenti comuni di connettersi finchè non si è sicuri che il recupero abbia avuto successo.

  8. Avviare il server. Il server entrerà in modalità recovery e leggerà attraverso i file WAL di cui ha bisogno. Se il recupero dovesse terminare causa errori esterni, il server può essere riavviato semplicemente ed esso continuerà il recupero. Fino al completamento del processo di recupero, il server rinominerà recovery.conf in recovery.done (per prevenire l'accidentale rientro in modalità recovery) e quindi inizierà le normali operazioni del database.

  9. Ispezionare il contenuto del database per assicurarsi di essere tornati allo stato desiderato. Se non è cos', ritornare al passo 1. Se tutto è a posto, permettere agli utenti di connettersi ripristinando pg_hba.conf alla normalità.

La parte chiave di tutto questo è l'impostazione di un file di configurazione di recupero che descriva come si vuole recuperare e quanto lontano dovrebbe arrivare il recupero. È possibile usare recovery.conf.sample (normalmente si trova nella directory share/ del percorso di installazione) come prototipo. La sola cosa che si deve assolutamente specificare in recovery.conf è la restore_command, che dice a PostgreSQL™ come recuperare i segmenti WAL archiviati. Come l'archive_command, questa è una stringa di comando shell. Può contenere %f, che verrà sostituito dal nome del file di log desiderato, e %p, che verrà sostituito dal percorso in cui copiare il file di log. (Il percorso è relativo alla directory di lavoro corrente, per es., la directory data del cluster). Scrivere %% se si ha bisogno di includere un carattere % nel comando. Il comando più semplice sarà qualcosa simile a:

restore_command = 'cp /mnt/server/archivedir/%f %p'

che copierà i segmenti WAL archiviati precedentemente dalla directory /mnt/server/archivedir. Certamente, è possibile usare qualcosa di molto più complicato, come uno script shell che richiede che l'operatore monti un nastro appropriato.

[Avvertimento]

Avvertimento

TODO

It is important that the command return nonzero exit status on failure. The command will be called requesting files that are not present in the archive; it must return nonzero when so asked. This is not an error condition. Not all of the requested files will be WAL segment files; you should also expect requests for files with a suffix of .backup or .history. Also be aware that the base name of the %p path will be different from %f; do not expect them to be interchangeable.

I segmenti WAL che non possono essere trovati nell'archivio saranno cercati dentro pg_xlog/; questo permette l'utilizzo di segmenti non archiviati. Comunque, saranno usati i segmenti che sono disponibili dall'archivio preferibilmente ai file in pg_xlog/. Il sistema non sovrascriverà i contenuti esistenti di pg_xlog/ quando recupera i file archiviati.

Normally, recovery will proceed through all available WAL segments, Normalmente, il recupero procederà attraverso tutti i segmenti WAL disponibili, thereby restoring the database to the current point in time (or as (o più vicino possibile ai segmenti WAL disponibli). Inoltre, un recupero normale finirà finirà con un messaggio «file not found», il testo esatto del messaggio di errore dipende dalla scelta di restore_command. Si potrebbe vedere anche un messaggio di errore all'avvio di un recupero per un file chiamato in maniera simile a 00000001.history. Anche questo è normale e non indica un problema in situazioni di recupero semplici; si veda Sezione 24.3.4, «Timeline» per discussioni a riguardo.

Se si vuole tornare a qualche istante nel tempo (tipo, appena prima che il DBA junior ha cancellato la tabella di transazione principale), basta specificare il punto di arresto richiesto in recovery.conf. Si può specificare il punto d'arresto, noto come «recovery target», sia attraverso data/orario sia per completamento di uno specifico ID di transazione. Al momento della scrittura di questo libro, solo l'opzione data/orario è molto usabile, dato che non ci sono strumenti che aiutino l'identificazione con accuratezza di quale transazione usare.

[Nota]

Nota

Il punto di arresto deve essere successivo al momento finale del backup di base, per es., il momento finale di pg_stop_backup. Non è possibile usare un backup base per recuperare un momento in cui il backup era in corso. (Per recuperare a un momento del genere, si deve tornare indietro al precedente backup di base e andare in avanti da quello).

Se il recupero trova dati WAL corrotti, si arresterà a quel momento e il server non partirà. In quei casi il processo di recupero può essere lanciato di nuovo dall'inizio, specificando un «recovery target» precedente il punto di corruzione, così che il recupero possa completarsi normalmente. Se il recupero fallisce per una ragione esterna, tipo un crash del sistema o se gli archivi WAL sono diventati inaccessibili, allora il recupero può semplicemente essere riavviato e ripartirà circa da dove è fallito.

[Avvertimento]

Avvertimento

TODO

Recovery restart works much like checkpointing in normal operation: the server periodically forces all its state to disk, and then updates the pg_control file to indicate that the already-processed WAL data need not be scanned again.

24.3.4. Timeline

La capacità di ripristinare il database a un istante passato crea delle complessità che sono affini a storie di fantascienza sui viaggi temporali e universi paralleli. Per esempio, nello storico originale del database, supporre di aver eliminato una tabella critica alle 17:15 di martedì sera, ma non non essersi accorti dell'errore fino al mezzogiorno di giovedì. Prendere il backup, ripristinare all'istante 17:14 di martedì sera, e ecco qua. In questo storico del database, non si è mai cancellata la tabella. Ma supporre che più tardi si sia realizzato che questa non è stata proprio una grande idea, e che si voglia tornare a qualche istante di giovedì mattina nello storico originale. Non potremmo farlo se, mentre il database era in esecuzione, ha sovrascritto alcuni dei file segmento WAL che precedevano l'istante al quale si desidera tornare ora. Così, per evitare ciò, è necessario distinguere le serie di record WAL generata dopo che è stato fatto un recupero a un istante nel tempo da quelle state generate nello storico originale del database.

Per gestire questo problema, PostgreSQL™ ha la nozione di timelines. Ogni volta che un recupero è completo, una nuova timeline viene creata per identificare la serie di record WAL generati dopo quel recupero. L'ID della timeline è parte dei nome dei file segmento WAL, così una che nuova timeline non sovrascriva i dati WAL generati da timeline precedenti. Infatti è possibile archiviare molte timeline differenti. Mentre questa potrebbe sembrare una caratteristica inutile, spesso salva la vita. Considerare la situazione in cui non si è abbastanza sicuri a quale istante recuperare, e così dover fare diversi recuperi per tentativi finchè non si trova il migliore. Senza le timeline questa operazione genererà presto confusione. Con le timeline, è possibile recuperare da qualsiasi stato precedente, inclusi stati in ramificazioni di timeline abbandonate precedentemente.

Ogni volta che una nuova timeline viene creata, PostgreSQL™ crea uno file «timeline history» che mostra da quale timeline è stata generata e quando. Questi file storico sono necessari per permettere al sistema di pescare i giusti file segmento WAL quando si recupera da un archivio che contiene molteplici timeline. Quindi, sono archiviati all'interno dell'area di archivio WAL semplicemente cole file segmento WAL. I file storico sono semplicemente piccoli file di testo, così è economico e giusto tenerne traccia indefinitamente (a differenza dei file segmento che sono grandi). È possibile, se si vuole, aggiungere commenti a un file storico per registrare le proprie note sul come e perchè quella particolare timeline è stata creata. Questi commenti saranno utili specialmente quando si ha un folto gruppo di timeline come risultato di sperimentazioni.

Il comportamento predefinito è do recuperare lungo la stella timeline che era la corrente quando il backup di base è stato fatto. Se si desidera recuperare all'interno di timeline figlie (cioè, si vuole restituire qualche stato che è stato generato dopo un tentativo di recupero), bisogna specificare l'ID della timeline "bersaglio" in recovery.conf. Non è possibile recuperare all'interno di timeline che ramificate precedentemente rispetto al backup di base.

24.3.5. Suggerimenti e esempi

Proponiamo qui alcuni suggerimenti per configurare l'archiviazione continua.

24.3.5.1. Hot backup a sè stanti

È possibile usare le funzionalità di backup PostgreSQL™ per produrre hot backup a sè stanti. Questi sono backup che non possono essere usati per recuperi di istanti nel tempo, sono tipicamente molto più veloci a svolgere backup e ripristino rispetto ai dump fatti con pg_dump. (Sono anche molto più grandi dei dump pg_dump, per questo in alcuni casi il vantaggio di velocità potrebbe essere vanificato).

Per prepararsi a hot backup a sè stanti, impostare wal_level a archive (o hot_standby), archive_mode a on, e impostare un archive_command che esegue l'archiviazione solo quando un file seitch esiste. Per esempio:

archive_command = 'test ! -f /var/lib/pgsql/backup_in_progress || cp -i %p /var/lib/pgsql/archive/%f < /dev/null'

Questo comando compierà l'archiviazione quando /var/lib/pgsql/backup_in_progress esiste, altrimenti silenziosamente restituirà lo stato di uscita zero (permettendo a PostgreSQL™ di riciclare i file WAL non voluti).

Con questa preparazione, un backup può essere effettuato usando uno script simile al seguente:

touch /var/lib/pgsql/backup_in_progress
psql -c "select pg_start_backup('hot_backup');"
tar -cf /var/lib/pgsql/backup.tar /var/lib/pgsql/data/
psql -c "select pg_stop_backup();"
rm /var/lib/pgsql/backup_in_progress
tar -rf /var/lib/pgsql/backup.tar /var/lib/pgsql/archive/

Il file switch /var/lib/pgsql/backup_in_progress viene creato prima, abilitando l'archiviazione di file WAL completi. Dopo che il backup è terminato il file switch viene rimosso. I file WAL archiviati sono quindi aggiunti al backup così che sia il backup di base che tutti i file WAL richiesti siano parte della stesso file tar. Per favore, ricordare di aggiungere la gestione degli errori agli script di backup.

Se la dimensione dell'archivio è proccupante, usare pg_compresslog, http://pglesslog.projects.postgresql.org, per rimuovere full_page_writes non necessarie e spazio in coda dai file WAL. Si può poi usare gzip per comprimere ulteriormente l'output di pg_compresslog:

archive_command = 'pg_compresslog %p - | gzip > /var/lib/pgsql/archive/%f'

Si avrà poi la necessità di usare gunzip e pg_decompresslog durante il recupero:

restore_command = 'gunzip < /mnt/server/archivedir/%f | pg_decompresslog - %p'

24.3.5.2. archive_command scripts

Molte persone scelgono di usare script per definire i loro archive_command, così che le loro voci postgresql.conf appariranno molto semplici:

archive_command = 'local_backup_script.sh'

Usare uno script separato è consigliabile ogni volta che si vuole usare più di un singolo comando nel processo di archiviazione. Questo permette la gestione di tutta la complessità all'interno dello script, che può essere scritto in linguaggi di scripting popolari tipo bash o perl. Qualsiasi messaggio scritto su stderr dallo script apparirà nel log del server database, permettendo che configurazioni complesse siano diagnosticate facilmente se falliscono.

Esempi di esigenze che potrebbero essere risolti all'interno di uno script includono:

  • Copiare dati verso luoghi di immagazzinamento sicuro non in loco

  • Raggruppare file WAL così che siano trasferiti ogni tre ore, invece che uno alla volta

  • Interfacciarsi con altri software di backup e ripristino

  • Interfacciarsi con software di monitoraggio per segnalare errori

24.3.6. Avvertimenti

Al momento di questa scrittua, ci sono diverse limitazioni alla tecnica di archiviazione continua. Queste probabilmente saranno risolte in versioni future:

  • Operazioni su indici hash attualmente non sono sottoposte a log WAL, per questo motivo il replay non aggiornerà questi indici. Questo significherà che ogni nuovo inserimento sarà ignorato dall'indice, le righe aggiornate apparentemente scompariranno e le righe cancellate manterranno comunque puntatori. In altre parole, se si modifica una tabella che ha un indice hash allora si otterranno risultati di query incorretti su un server standby. Quando il ripristino è completato si raccomanda di REINDEX(7) manualmente ogni indice dopo il completamento di un'operazione di ripristino.

  • Se un comando CREATE DATABASE(7) viene eseguito mentre sta avendo luogo un backup di base, e quindi il database template copiato da CREATE DATABASE viene modificato mentre il backup di base è in esecuzione, è possibile che il ripristino faccia si che queste modifiche siano propagate anche all'interno del database creato. Questo comportamento ovviamente è indesiderabile. Per evitare questo rischio, è meglio non modificare nessun database template mentre un backup di base è in esecuzione.

  • I comandi CREATE TABLESPACE(7) sono sottoposti a log WAL con il percorso assoluto, e saranno inoltre sottoposti a replay come creazioni di tablespace con lo stesso percorso assoluto. Questo potrebbe essere indesiderabile se il log è stato sottoposto a replay su una macchina diversa. Può essere pericoloso anche se il log viene sottoposto a replay sulla stessa macchina, ma all'interno di una nuova directory dati: il replay sovrascriverà comunque il contenuto del tablespace originale. Per evitare potenziali incomprensioni, la buona pratica è di realizzare un nuovo backup di base dopo aver creato o eliminato dei tablespace.

Si dovrebbe notare inoltre che il formato WAL predefinito è abbastanza enorme dato che include molte snapshot di pagina del disco. Queste snapshot di pagina sono progettate per sostenere il ripristino dai crash, dato che si potrebbe aver bisogno di mettere a posto pagine disco scritte parzialmente. In dipendenza del proprio hardware e software di sistema, il rischio di scritture parziali potrebbe essere abbastanza piccolo da ignorare, nel qual caso è possibile ridurre significativamente il volume totale dei log archiviati disabilitando le snapshot di pagina usando il parametro full_page_writes. (Leggere le note e i warning in Capitolo 29, Reliability and the Write-Ahead Log prima di farlo). Disabilitare le snapshot non previene l'uso dei log per operazioni PITR. Un area per sviluppo futuro è di comprimere dati WAL archiviati rimuovendo copie di pagine non necessarie anche quando full_page_writes è attivo. Nel frattempo, gli amministratori potrebbero desiderare ridurre il numero di snapshot di pagina incluse nel WAL incrementando i parametri d'intervallo di checkpoint tanto quanto tanto quanto fattibile.

Documentazione di PostgreSQL 9.0 > Amministrazione del server > Backup e ripristino > Archiviazione continua e Ripristino Point-In-Time (PITR)
PrecedenteBackup a livello di file systemMigrazioni fra versioniSuccessivo