Який найкращий спосіб автоматизувати резервне копіювання баз даних PostgreSQL?


22

Мені здається нудним резервне копіювання баз даних щотижня. І я також думаю, що щоденні резервні копії повинні бути перетворені на щоденні резервні копії. Якщо мені довелося це зробити, я не хочу робити це вручну. Який найкращий спосіб автоматизувати резервне копіювання баз даних PostgreSQL щодня?


Невелика примітка: скидання db може знищити продуктивність, використовувати кластер та скинути на неактивні вузли.
нейтрин

Ви можете зробити резервні резервні копії за допомогою цього безкоштовного інструменту postgresql-backup.com
Олек Нілсон

Наступне питання: наскільки ви великі, який у вас загальний механізм резервного копіювання. Наприклад, я ніколи не створюю резервного копіювання нічого вручну. Встановіть агент моєї системи резервного копіювання, виберіть елементи для резервного копіювання в інтерфейсі, заплануйте резервне копіювання (у моєму випадку для баз даних: кожні 5 хвилин) .... завершено. Але це передбачає наявність достатньої кількості, що має сенс встановити належну систему.
TomTom

Я б не назвав postgresql-backup.com "безкоштовним" рішенням. Це безкоштовно лише для перших 2 баз даних ... @OlekNilson
Айдан Мелен

Відповіді:


40

те саме, що ви робите для будь-якого іншого повторюваного завдання, яке можна автоматизувати - ви пишете скрипт для створення резервної копії, а потім встановлюєте завдання 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

EDIT:
pg_dumpall -D перемикач (рядок 27) застарілий, тепер замінено на --column-inserts
https://wiki.postgresql.org/wiki/Deprecated_Features


10
+1 за чудовий сценарій
rkthkr

Я використовую щось дуже схоже як PreDumpCmd для резервного копіювання, за винятком того, що я не кодую дату в шлях, оскільки backuppc займається збереженням декількох копій.
Девід Пашлі

2
Чудовий сценарій, але я виявив, що мені потрібно налаштувати регулярний вираз, щоб він не включав труби та порожні рядки як імена бази даних. DBS=$($PSQL -l -t | egrep -v 'template[01]' | awk '{print $1}' | egrep -v '^\|' | egrep -v '^$')
s29

@ s29 Я думаю, що краще використовувати прямий запит замість усіх греп-хакерів, наприклад: DBS = ($ ($ ($ {PSQL} -t -A -c "виберіть дане ім'я з pg_database, де дату не в ('template0', ') template1 ') "))
PolyTekPatrick

Дивовижний сценарій - так як це можна порівняти з такими послугами, як ClusterControl?
karns

7
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


Розщеплення файлу - чудова ідея. Краще розділити дамп, використовуючи split -Cтак, щоб лінія ніколи не була розділена. Налагодження помилкового відновлення простіше.
Джанлука Делла Ведова

3

Які б команди ви не видавали "вручну", - запишіть їх у скрипт і подзвоніть до цього сценарію в 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

ЯКЩО використовується pg_dumpall, чи можливо відновити одну таблицю з неї, або вона відновить усі відразу? можете поділитися сценарієм відновлення єдиної таблиці, створеної за допомогою dumpall
Ashish Karpe

0

Якщо ви хочете створити резервну копію цілого кластера з мінімальним завантаженням системи, ви можете просто відзначити кореневий каталог кластера 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

ось основна частина мого резервного сценарію.


1
Ні, це не працює, якщо у вас також не ввімкнено WAL-архівування.
Пітер Ейзентравт

0

у випадку, якщо комусь доведеться створити резервну копію своїх поштових адрес на машині 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
)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.