Qual è il modo migliore per automatizzare il backup dei database PostgreSQL?


22

Trovo noioso dover eseguire il backup dei database ogni settimana. E penso anche che i backup settimanali dovrebbero essere trasformati in backup giornalieri. Se dovessi farlo, non voglio farlo manualmente. Qual è il modo migliore per automatizzare quotidianamente il backup dei database PostgreSQL?


Piccola nota: il dumping del db può uccidere le prestazioni, utilizzare un cluster e dump su nodi non attivi.
neutrina,

Puoi eseguire backup pianificati con l'aiuto di questo strumento gratuito postgresql-backup.com
Olek Nilson

Domanda successiva: quanto sei grande, quale meccanismo di backup generale hai in atto. Ad esempio, non eseguo mai il backup di nulla manualmente. Installa l'agente del mio sistema di backup, seleziona gli elementi di cui eseguire il backup nell'interfaccia utente, pianifica il backup (nel mio caso per i database: ogni 5 minuti) .... finito. Ma questo presuppone che ne abbia abbastanza che abbia senso installare un sistema adeguato.
TomTom,

Non definirei postgresql-backup.com una soluzione "gratuita". È gratuito solo per i primi 2 database ... @OlekNilson
Aidan Melen

Risposte:


40

lo stesso che fai per qualsiasi altra attività ripetitiva che può essere automatizzata: scrivi uno script per eseguire il backup e quindi imposta un processo cron per eseguirlo.

uno script come il seguente, ad esempio:

(Nota: deve essere eseguito come l'utente postgres o qualsiasi altro utente con gli stessi privilegi)

#! /bin/bash

# backup-postgresql.sh
# by Craig Sanders <cas@taz.net.au>
# This script is public domain.  feel free to use or modify
# as you like.

DUMPALL='/usr/bin/pg_dumpall'
PGDUMP='/usr/bin/pg_dump'
PSQL='/usr/bin/psql'

# directory to save backups in, must be rwx by postgres user
BASE_DIR='/var/backups/postgres'
YMD=$(date "+%Y-%m-%d")
DIR="$BASE_DIR/$YMD"
mkdir -p "$DIR"
cd "$DIR"

# get list of databases in system , exclude the tempate dbs
DBS=( $($PSQL --list --tuples-only |
          awk '!/template[01]/ && $1 != "|" {print $1}') )

# first dump entire postgres database, including pg_shadow etc.
$DUMPALL --column-inserts | gzip -9 > "$DIR/db.out.gz"

# next dump globals (roles and tablespaces) only
$DUMPALL --globals-only | gzip -9 > "$DIR/globals.gz"

# now loop through each individual database and backup the
# schema and data separately
for database in "${DBS[@]}" ; do
    SCHEMA="$DIR/$database.schema.gz"
    DATA="$DIR/$database.data.gz"
    INSERTS="$DIR/$database.inserts.gz"

    # export data from postgres databases to plain text:

    # dump schema
    $PGDUMP --create --clean --schema-only "$database" |
        gzip -9 > "$SCHEMA"

    # dump data
    $PGDUMP --disable-triggers --data-only "$database" |
        gzip -9 > "$DATA"

    # dump data as column inserts for a last resort backup
    $PGDUMP --disable-triggers --data-only --column-inserts \
        "$database" | gzip -9 > "$INSERTS"

done

# delete backup files older than 30 days
echo deleting old backup files:
find "$BASE_DIR/" -mindepth 1 -type d -mtime +30 -print0 |
    xargs -0r rm -rfv

EDIT:
pg_dumpall -D switch (riga 27) è obsoleto, ora sostituito con --column-inserts
https://wiki.postgresql.org/wiki/Deprecated_Features


10
+1 per una sceneggiatura fantastica
rkthkr,

Uso qualcosa di molto simile come PreDumpCmd per backuppc, con l'eccezione che non codifico la data nel percorso, poiché backuppc si occupa di conservare più copie.
David Pashley,

2
Ottimo script, ma ho scoperto che avevo bisogno di modificare la regex in modo che non includesse pipe e righe vuote come nomi di database. DBS=$($PSQL -l -t | egrep -v 'template[01]' | awk '{print $1}' | egrep -v '^\|' | egrep -v '^$')
s29,

@ s29 Penso che sia meglio usare una query diretta invece di tutto quel trucchetto grep, come: DBS = ($ ($ {PSQL} -t -A -c "seleziona il nome dati da pg_database dove il nome dati non è in ('template0', ' template1 ') "))
PolyTekPatrick il

Fantastico script - quindi come si confronta con servizi come ClusterControl?
karn

7
pg_dump dbname | gzip > filename.gz

Ricarica con

createdb dbname
gunzip -c filename.gz | psql dbname

o

cat filename.gz | gunzip | psql dbname

Usa split. Il splitcomando consente di dividere l'output in parti di dimensioni accettabili per il file system sottostante. Ad esempio, per creare blocchi di 1 megabyte:

pg_dump dbname | split -b 1m - filename

Ricarica con

createdb dbname
cat filename* | psql dbname

Potresti lanciare uno di quelli dentro /etc/cron.hourly

Fonte da http://www.postgresql.org/docs/8.1/interactive/backup.html#BACKUP-DUMP-ALL


Dividere il file è un'ottima idea. È meglio dividere il dump, usando split -C, in modo che una linea non venga mai divisa. Il debug di un ripristino non riuscito è più semplice.
Gianluca Della Vedova,

3

Qualunque sia il comando che impartisci "a mano", - scrivili nello script e metti la chiamata a questo script in cron o in qualsiasi scheduler che usi.

Ovviamente puoi rendere la sceneggiatura più elaborata, ma in generale, penso che ci arriverai - inizia in modo semplice e successivamente perfeziona.

Script più semplice possibile:

#!/bin/bash
/usr/local/pgsql/bin/pg_dumpall -U postgres -f /var/backups/backup.dump

Salvalo come /home/randell/bin/backup.sh, aggiungi a cron:

0 0 * * 0 /home/randell/bin/backup.sh

Se viene utilizzato pg_dumpall, è possibile ripristinare una singola tabella da esso o ripristinerà tutto in una volta? puoi per favore condividere lo script per il ripristino di una singola tabella creata usando dumpall
Ashish Karpe il

0

Se si desidera eseguire il backup di un intero cluster con un carico di sistema minimo, è sufficiente eseguire il tar della directory principale del cluster postgresql. per esempio:

echo "select pg_start_backup('full backup - `date`');" | psql
/usr/bin/rdiff-backup --force --remove-older-than 7D $BACKUP_TARGET
/usr/bin/rdiff-backup --include '/etc/postgresql' --include $PGDATA --exclude '/*' / $BACKUP_TARGET
/bin/tar -cjf /mnt/tmp/$SERVER_NAME.tbz2 $BACKUP_TARGET 2>&1
echo "select pg_stop_backup();" | psql

questa è la maggior parte del mio script di backup.


1
No, questo non funziona se non hai abilitato anche l'archiviazione WAL.
Peter Eisentraut,

0

nel caso in cui qualcuno debba eseguire il backup dei propri postgres su una macchina Windows senza l'aiuto di Cygwin ecc. Ho un file batch che fa abbastanza bene il lavoro.

questo eseguirà il backup dei database in singoli file nella sua directory ogni giorno

set dtnm=%date:~-4,4%%date:~-7,2%%date:~0,2%
set bdir=D:\backup\%dtnm%
mkdir %bdir%

FOR /F "tokens=1,2 delims=|" %%a IN ('psql -l -t -A -U postgres') DO (
    IF %%b EQU postgres pg_dump -U postgres -f %bdir%\%%a.sql.gz -Z 9 -i %%a
)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.