¿Cuál es la mejor manera de automatizar el respaldo de las bases de datos PostgreSQL?

22

Me resulta tedioso tener que hacer una copia de seguridad de las bases de datos todas las semanas. Y también creo que las copias de seguridad semanales deberían convertirse en copias de seguridad diarias. Si tuviera que hacer eso, no quiero hacerlo manualmente. ¿Cuál es la mejor manera de automatizar diariamente el respaldo de las bases de datos PostgreSQL?

Randell
fuente
Pequeña nota: volcar el db puede matar el rendimiento, usar un clúster y volcar en nodos no activos.
neutrinus
Puede hacer copias de seguridad programadas con la ayuda de esta herramienta gratuita postgresql-backup.com
Olek Nilson
Siguiente pregunta: ¿Qué tan grande es, qué mecanismo general de respaldo tiene instalado? Por ejemplo, nunca estoy haciendo una copia de seguridad de nada manualmente. Instale el agente de mi sistema de copia de seguridad, seleccione los elementos para hacer una copia de seguridad en la interfaz de usuario, programe la copia de seguridad (en mi caso para las bases de datos: cada 5 minutos) ... terminado. Pero eso supone tener suficiente para que tenga sentido instalar un sistema adecuado.
TomTom
No llamaría a postgresql-backup.com una solución "gratuita". Solo es gratis para las primeras 2 bases de datos ... @OlekNilson
Aidan Melen

Respuestas:

40

lo mismo que haces para cualquier otra tarea repetitiva que se pueda automatizar: escribes un script para hacer la copia de seguridad y luego configuras un trabajo cron para ejecutarlo.

un script como el siguiente, por ejemplo:

(Nota: debe ejecutarse como usuario de postgres, o cualquier otro usuario con los mismos privilegios)

#! /bin/bash

# backup-postgresql.sh
# by Craig Sanders <[email protected]>
# 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

EDITAR: el
pg_dumpall -D interruptor (línea 27) está en desuso, ahora reemplazado con --column-inserts
https://wiki.postgresql.org/wiki/Deprecated_Features

cas
fuente
10
+1 para un gran guión
rkthkr
Utilizo algo muy similar como PreDumpCmd para backuppc, con la excepción de que no codifico la fecha en la ruta, ya que backuppc trata de mantener varias copias.
David Pashley
2
Gran secuencia de comandos, pero descubrí que necesitaba ajustar la expresión regular para que no incluyera tuberías y líneas en blanco como nombres de bases de datos. DBS=$($PSQL -l -t | egrep -v 'template[01]' | awk '{print $1}' | egrep -v '^\|' | egrep -v '^$')
s29
@ s29 Creo que es mejor usar una consulta directa en lugar de toda esa piratería grep, como: DBS = ($ ($ {PSQL} -t -A -c "seleccione datname de pg_database donde datname no está en ('template0', ' template1 ') "))
PolyTekPatrick
Guión impresionante: ¿cómo se compara esto con servicios como ClusterControl?
Karns
7
pg_dump dbname | gzip > filename.gz

Recargar con

createdb dbname
gunzip -c filename.gz | psql dbname

o

cat filename.gz | gunzip | psql dbname

Uso split. lossplit comando le permite dividir la salida en partes de tamaño aceptable para el sistema de archivos subyacente. Por ejemplo, para hacer trozos de 1 megabyte:

pg_dump dbname | split -b 1m - filename

Recargar con

createdb dbname
cat filename* | psql dbname

Podrías tirar uno de esos en /etc/cron.hourly

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

Nick Anderson
fuente
Dividir el archivo es una gran idea. Es mejor dividir el volcado, usando split -C, para que una línea nunca se divida. La depuración de una restauración fallida es más fácil.
Gianluca Della Vedova
3

Cualesquiera que sean los comandos que emita "a mano", escríbalos en el script y ponga la llamada a este script en cron o en el programador que utilice.

Por supuesto, puede hacer que el guión sea más elegante, pero en general, creo que llegará allí: comience de manera simple y luego refine.

El guión más simple posible:

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

Guárdelo como /home/randell/bin/backup.sh, agregue a cron:

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

fuente
Si se usa pg_dumpall, ¿es posible restaurar una sola tabla o se restaurará todo de una vez? ¿podría compartir un script para restaurar una sola tabla creada usando dumpall?
Ashish Karpe
0

Si desea hacer una copia de seguridad de un clúster completo con una carga mínima del sistema, simplemente puede tar el directorio raíz del clúster postgresql. por ejemplo:

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

ese es el grueso de mi script de respaldo.

sotavento
fuente
1
No, esto no funciona si no tiene habilitado el archivo WAL.
Peter Eisentraut
0

en caso de que alguien tenga que hacer una copia de seguridad de sus postgres en una máquina Windows sin la ayuda de Cygwin, etc. Tengo un archivo por lotes que hace el trabajo bastante bien.

esto hará una copia de seguridad de las bases de datos en archivos individuales en su propio directorio todos los días

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
)
l0ft13
fuente