PostgreSQL veritabanlarının yedeklenmesini otomatikleştirmenin en iyi yolu nedir?


22

Her hafta veritabanlarını yedeklemenin zor olduğunu düşünüyorum. Ayrıca haftalık yedeklemelerin günlük yedeklemelere dönüştürülmesi gerektiğini düşünüyorum. Bunu yapmak zorunda olsaydım, manuel olarak yapmak istemiyorum. Günlük PostgreSQL veritabanlarının yedeklenmesini otomatikleştirmenin en iyi yolu nedir?


Küçük not: db'nin atılması performansı düşürebilir, bir küme kullanabilir ve aktif olmayan düğümlere atılabilir.
neutrinus

Bu ücretsiz araçla zamanlanmış yedeklemeler yapabilirsiniz postgresql-backup.com
Olek Nilson

Sonraki soru: Ne kadar büyüksünüz, hangi genel yedekleme mekanizmasına sahipsiniz? Örneğin, hiçbir zaman manuel olarak hiçbir şey yedeklemiyorum. Yedekleme sistemimin aracısını yükleyin, UI'da yedeklenecek öğeleri seçin, yedeklemeyi zamanlayın (benim durumumda: her 5 dakikada bir) .... tamamlandı. Ancak bu, uygun bir sistemi kurmanın mantıklı olacağı anlamına gelir.
TomTom

Postgresql-backup.com adresine "ücretsiz" bir çözüm demem. Sadece ilk 2 veritabanında ücretsiz ... @OlekNilson
Aidan Melen

Yanıtlar:


40

otomatikleştirilebilecek herhangi bir tekrarlayan görev için yaptığınız gibi - yedeklemeyi yapmak için bir komut dosyası yazarsınız ve ardından çalıştırmak için bir cron işi ayarlarsınız.

Örneğin, aşağıdaki gibi bir komut dosyası:

(Not: postgres kullanıcısı veya aynı yetkilere sahip başka bir kullanıcı olarak çalıştırılmalıdır)

#! /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 (satır 27) kullanımdan kaldırıldı, şimdi https://wiki.postgresql.org/wiki/Deprecated_Features ile değiştirildi--column-inserts


10
İyi bir komut dosyası için +1
rkthkr

Backuppc için PreDumpCmd'ye çok benzer bir şey kullanıyorum, istisna olarak tarihi yola kodlamamıştım.
David Pashley

2
Harika senaryo, ama regex'i ince ayarlamamı sağladım, öyle ki boruları ve boş satırları veritabanı isimleri içermiyordu. DBS=$($PSQL -l -t | egrep -v 'template[01]' | awk '{print $1}' | egrep -v '^\|' | egrep -v '^$')
s29

@ s29 Ben tüm bu grep hackery yerine doğrudan bir sorgu kullanmak daha iyi olduğunu düşünüyorum, gibi: DBS = ($ ($ {PSQL} -t -A -c "pg_database'den veri ismini seçin, burada veri ismini ('template0', 'içinde değil) template1 ') "))
PolyTekPatrick 10:17

Müthiş script - peki ClusterControl gibi servisleri nasıl karşılaştırırız?
19

7
pg_dump dbname | gzip > filename.gz

İle yeniden yükle

createdb dbname
gunzip -c filename.gz | psql dbname

veya

cat filename.gz | gunzip | psql dbname

Kullanın split. splitKomut Eğer altta yatan dosya sistemine boyutunda kabul edilebilir parçalar halinde çıktı split sağlar. Örneğin, 1 megabayt boyutunda parçalar yapmak için:

pg_dump dbname | split -b 1m - filename

İle yeniden yükle

createdb dbname
cat filename* | psql dbname

İçlerinden birini fırlatabilirsin /etc/cron.hourly

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


Dosyayı bölmek harika bir fikir. Dökümü bölmek, split -Cbir çizginin asla bölünmemesi için kullanmak daha iyidir . Başarısız bir geri yüklemenin hata ayıklaması daha kolaydır.
Gianluca Della Vedova

3

"El ile" verdiğiniz komutlar ne olursa olsun, - komut dosyasına yazın ve bu betiğe cron'a veya kullandığınız zamanlayıcıya çağrı yapın.

Elbette senaryoyu daha süslü hale getirebilirsiniz, ancak genel olarak, oraya gideceğinizi düşünüyorum - basit başlayın ve daha sonra ayrıntılandırın.

En basit olası komut dosyası:

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

/Home/randell/bin/backup.sh olarak kaydedin, cron'a ekleyin:

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

Pg_dumpall kullanılırsa, tek bir tabloyu ondan geri yüklemek mümkün müdür yoksa bir kerede hepsini geri yükler mi? dumpall kullanılarak oluşturulan tek bir tabloyu geri yüklemek için komut dosyasını paylaşabilir misiniz
Ashish Karpe

0

Kümenin tamamını minimum sistem yükü ile yedeklemek istiyorsanız, postgresql kümesinin kök dizinini kolayca değiştirebilirsiniz. Örneğin:

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

bu benim yedekleme betiğimin büyük kısmı.


1
Hayır, WAL arşivlemeyi de etkinleştirmediyseniz bu işe yaramaz.
Peter Eisentraut

0

Herhangi birinin postgresini cygwin vb. yardımı olmadan bir Windows makinesinde yedeklemesi gerekiyorsa, işi oldukça iyi yapan bir toplu iş dosyasına sahibim.

bu, veritabanlarını her gün kendi dizinindeki ayrı dosyalara yedekler

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
)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.