Мне утомительно создавать резервные копии баз данных каждую неделю. И я также считаю, что еженедельные резервные копии следует превратить в ежедневные. Если бы мне пришлось это делать, я бы не хотел делать это вручную. Как лучше всего автоматизировать ежедневное резервное копирование баз данных PostgreSQL?
так же, как и для любой другой повторяющейся задачи, которую можно автоматизировать - вы пишете сценарий для резервного копирования, а затем настраиваете задание cron для его запуска.
сценарий, подобный следующему, например:
(Примечание: он должен быть запущен как пользователь postgres или любой другой пользователь с такими же привилегиями)
#! /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
РЕДАКТИРОВАТЬ :
pg_dumpall -D
переключатель (строка 27) устарел, теперь заменен на --column-inserts
https://wiki.postgresql.org/wiki/Deprecated_Features
pg_dump dbname | gzip > filename.gz
Перезагрузить с помощью
createdb dbname
gunzip -c filename.gz | psql dbname
или
cat filename.gz | gunzip | psql dbname
Использовать split
. В split
позволяет разделить вывод на части, размер которых приемлем для базовой файловой системы. Например, чтобы сделать куски размером 1 мегабайт:
pg_dump dbname | split -b 1m - filename
Перезагрузить с помощью
createdb dbname
cat filename* | psql dbname
Вы могли бы бросить один из них в /etc/cron.hourly
Источник из http://www.postgresql.org/docs/8.1/interactive/backup.html#BACKUP-DUMP-ALL
Какие бы команды вы ни выполняли «вручную», напишите их в скрипт и поместите вызов этого скрипта в cron или любой другой планировщик, который вы используете.
Вы, конечно, можете сделать сценарий более привлекательным, но в целом я думаю, что у вас все получится - начните с простого, а затем уточните.
Самый простой сценарий:
#!/bin/bash
/usr/local/pgsql/bin/pg_dumpall -U postgres -f /var/backups/backup.dump
Сохраните его как /home/randell/bin/backup.sh, добавьте в cron:
0 0 * * 0 /home/randell/bin/backup.sh
Если вы хотите создать резервную копию всего кластера с минимальной нагрузкой на систему, вы можете просто использовать tar для корневого каталога кластера postgresql. например:
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
это основная часть моего сценария резервного копирования.
в случае, если кому-то нужно сделать резервную копию своих postgres на машине с Windows без помощи cygwin и т. д., у меня есть командный файл, который довольно хорошо справляется с этой задачей.
это будет резервировать базы данных в отдельные файлы в собственном каталоге каждый день
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
)