Cách tốt nhất để tự động sao lưu cơ sở dữ liệu PostgreSQL là gì?


22

Tôi thấy thật tẻ nhạt khi phải sao lưu cơ sở dữ liệu mỗi tuần. Và tôi cũng nghĩ rằng sao lưu hàng tuần nên được biến thành sao lưu hàng ngày. Nếu tôi phải làm điều đó, tôi không muốn làm nó bằng tay. Cách tốt nhất để tự động hóa sao lưu cơ sở dữ liệu PostgreSQL hàng ngày là gì?


Lưu ý nhỏ: việc bỏ db có thể giết chết hiệu năng, sử dụng một cụm và kết xuất vào các nút không hoạt động.
neutrinus

Bạn có thể tạo các bản sao lưu theo lịch trình với sự trợ giúp của công cụ miễn phí này postgresql-backup.com
Olek Nilson

Câu hỏi tiếp theo: Bạn lớn bao nhiêu, bạn có cơ chế sao lưu chung nào. Ví dụ, tôi không bao giờ sao lưu bất cứ thứ gì bằng tay. Cài đặt tác nhân của hệ thống sao lưu của tôi, chọn các yếu tố được sao lưu trong UI, lên lịch sao lưu (trong trường hợp của tôi cho cơ sở dữ liệu: cứ sau 5 phút) .... đã hoàn tất. Nhưng điều đó giả định rằng có đủ ý nghĩa để cài đặt một hệ thống phù hợp.
TomTom

Tôi sẽ không gọi postgresql-backup.com là giải pháp "miễn phí". Nó chỉ miễn phí cho 2 cơ sở dữ liệu đầu tiên ... @OlekNilson
Aidan Melen

Câu trả lời:


40

giống như bạn làm cho bất kỳ tác vụ lặp đi lặp lại nào khác có thể được tự động hóa - bạn viết một tập lệnh để thực hiện sao lưu, và sau đó thiết lập một công việc định kỳ để chạy nó.

một tập lệnh như sau, ví dụ:

(Lưu ý: nó phải được chạy với tư cách là người dùng postgres hoặc bất kỳ người dùng nào khác có cùng quyền riêng tư)

#! /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 (dòng 27) không được dùng nữa, hiện được thay thế bằng --column-inserts
https://wiki.postgresql.org/wiki/Deprecated_Features


10
+1 cho một kịch bản tuyệt vời
rkthkr

Tôi sử dụng một cái gì đó rất giống như PreDumpCmd cho backuppc, ngoại trừ việc tôi không mã hóa ngày vào đường dẫn, vì backuppc xử lý việc giữ nhiều bản sao.
David Pashley

2
Kịch bản tuyệt vời, nhưng tôi thấy tôi cần phải điều chỉnh regex sao cho nó không bao gồm các đường ống và các dòng trống làm tên cơ sở dữ liệu. DBS=$($PSQL -l -t | egrep -v 'template[01]' | awk '{print $1}' | egrep -v '^\|' | egrep -v '^$')
s29

@ s29 Tôi nghĩ tốt hơn là sử dụng truy vấn trực tiếp thay vì tất cả các tin tặc grep đó, như: DBS = ($ ($ {PSQL} -t -A -c "chọn tên dữ liệu từ pg_database trong đó tên dữ liệu không nằm trong ('template0', ' template1 ') "))
PolyTekPatrick

Kịch bản tuyệt vời - vậy làm thế nào để so sánh với các dịch vụ như ClusterControl?
karns

7
pg_dump dbname | gzip > filename.gz

Tải lại với

createdb dbname
gunzip -c filename.gz | psql dbname

hoặc là

cat filename.gz | gunzip | psql dbname

Sử dụng split. Các splitlệnh cho phép bạn chia ra thành từng miếng có thể chấp nhận về kích thước đối với hệ thống tập tin cơ bản. Ví dụ: để tạo khối 1 megabyte:

pg_dump dbname | split -b 1m - filename

Tải lại với

createdb dbname
cat filename* | psql dbname

Bạn có thể ném một trong những /etc/cron.hourly

Được cung cấp từ http://www.postgresql.org/docs/8.1/interactive/backup.html#BACKUP-DUMP-ALL


Chia nhỏ tập tin là một ý tưởng tuyệt vời. Tốt hơn là phân chia bãi chứa, sử dụng split -C, để một dòng không bao giờ được phân chia. Việc gỡ lỗi của một khôi phục thất bại là dễ dàng hơn.
Gianluca Della Vedova

3

Bất cứ lệnh nào bạn đưa ra "bằng tay", - hãy viết chúng vào tập lệnh và đặt lệnh gọi cho tập lệnh này bằng cron hoặc bất kỳ trình lập lịch biểu nào bạn sử dụng.

Tất nhiên bạn có thể làm cho kịch bản trở nên lạ mắt hơn, nhưng nói chung, tôi nghĩ rằng bạn sẽ đến đó - bắt đầu đơn giản và sau đó tinh chỉnh.

Kịch bản đơn giản nhất có thể:

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

Lưu nó dưới dạng /home/randell/bin/backup.sh, thêm vào cron:

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

NẾU pg_dumpall được sử dụng là có thể khôi phục bảng duy nhất từ ​​nó hoặc nó sẽ khôi phục tất cả cùng một lúc? bạn có thể vui lòng chia sẻ tập lệnh để khôi phục bảng đơn được tạo bằng cách sử dụng dumpall
Ashish Karpe

0

Nếu bạn muốn sao lưu toàn bộ một cụm với tải hệ thống tối thiểu, bạn có thể chỉ cần tar thư mục gốc của cụm postgresql. ví dụ:

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

đó là phần lớn kịch bản sao lưu của tôi.


1
Không, điều này không hoạt động nếu bạn cũng không bật lưu trữ WAL.
Peter Eisentraut

0

trong trường hợp bất cứ ai cũng phải sao lưu các postgres của họ trên máy tính windows mà không cần sự trợ giúp của cygwin, v.v. Tôi có một tệp bó hoạt động khá tốt.

điều này sẽ sao lưu cơ sở dữ liệu vào các tệp riêng lẻ trong thư mục riêng của nó mỗi ngày

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
)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.