Qual é a melhor maneira de automatizar o backup dos bancos de dados PostgreSQL?

22

Acho tedioso ter que fazer backup de bancos de dados toda semana. E também acho que os backups semanais devem ser transformados em backups diários. Se eu tivesse que fazer isso, não quero fazer manualmente. Qual é a melhor maneira de automatizar o backup dos bancos de dados PostgreSQL diariamente?

Randell
fonte
Nota pequena: despejar o banco de dados pode prejudicar o desempenho, usar um cluster e despejar em nós não ativos.
Neutrinus
Você pode fazer backups agendados com a ajuda desta ferramenta gratuita postgresql-backup.com
Olek Nilson
Próxima pergunta: Qual o seu tamanho, qual mecanismo de backup geral você possui? Por exemplo, eu nunca estou fazendo backup de nada manualmente. Instale o agente do meu sistema de backup, selecione os elementos a serem copiados na interface do usuário, agende o backup (no meu caso para bancos de dados: a cada 5 minutos) .... concluído. Mas isso pressupõe que seja suficiente instalar um sistema adequado.
TomTom
Eu não chamaria o postgresql-backup.com de uma solução "gratuita". É gratuito apenas para os 2 primeiros bancos de dados ... @OlekNilson
Aidan Melen

Respostas:

40

o mesmo que para qualquer outra tarefa repetitiva que possa ser automatizada - você escreve um script para fazer o backup e, em seguida, configura um trabalho cron para executá-lo.

um script como o seguinte, por exemplo:

(Nota: ele deve ser executado como usuário do postgres ou qualquer outro usuário com os mesmos privilégios)

#! /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

EDIT:
pg_dumpall -D switch (linha 27) está obsoleto, agora substituído por --column-inserts
https://wiki.postgresql.org/wiki/Deprecated_Features

cas
fonte
10
+1 para um ótimo roteiro
rkthkr
Uso algo muito semelhante ao PreDumpCmd para backuppc, com a exceção de que não codifico a data no caminho, pois o backuppc lida com a manutenção de várias cópias.
David Pashley
2
Ótimo script, mas achei que precisava ajustar o regex para que não incluísse pipes e linhas em branco como nomes de banco de dados. DBS=$($PSQL -l -t | egrep -v 'template[01]' | awk '{print $1}' | egrep -v '^\|' | egrep -v '^$')
29 de
@ s29 Acho melhor usar uma consulta direta em vez de todo esse hackeamento grep, como: DBS = ($ ($ {PSQL} -t -A -c "selecione o nome do dat em pg_database onde o nome do dat não está em ('template0', ' template1 ') "))
PolyTekPatrick
Script incrível - então, como isso se compara a serviços como o ClusterControl?
karns
7
pg_dump dbname | gzip > filename.gz

Recarregar com

createdb dbname
gunzip -c filename.gz | psql dbname

ou

cat filename.gz | gunzip | psql dbname

Use split. O splitcomando permite dividir a saída em partes aceitáveis ​​em tamanho para o sistema de arquivos subjacente. Por exemplo, para criar blocos de 1 megabyte:

pg_dump dbname | split -b 1m - filename

Recarregar com

createdb dbname
cat filename* | psql dbname

Você pode jogar um daqueles /etc/cron.hourly

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

Nick Anderson
fonte
Dividir o arquivo é uma ótima idéia. É melhor dividir o despejo usando split -C, para que uma linha nunca seja dividida. A depuração de uma restauração com falha é mais fácil.
Gianluca Della Vedova
3

Quaisquer comandos que você emitir "manualmente", - escreva-os no script e chame esse script no cron ou em qualquer programa que você use.

É claro que você pode tornar o script mais sofisticado, mas geralmente penso que você chegará lá - comece simples e depois refine.

Script mais simples possível:

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

Salve-o como /home/randell/bin/backup.sh, adicione ao cron:

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

fonte
Se pg_dumpall for usado, é possível restaurar uma tabela única a partir dela ou ela será restaurada de uma só vez? você pode, por favor, compartilhar o script para restaurar uma tabela única criada usando dumpall
Ashish
0

Se você deseja fazer backup de um cluster inteiro com carga mínima do sistema, basta tar o diretório raiz do cluster postgresql. por exemplo:

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

essa é a maior parte do meu script de backup.

lee
fonte
1
Não, isso não funcionará se você também não tiver o arquivamento WAL ativado.
Peter Eisentraut
0

caso alguém precise fazer backup de seus postgres em uma máquina Windows sem a ajuda do cygwin etc, eu tenho um arquivo em lotes que faz o trabalho muito bem.

isso fará o backup dos bancos de dados em arquivos individuais em seu próprio diretório todos os dias

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
fonte