postgres数据备份及恢复终结版

一.POSTGRESQL数据库备份策略。
1.一种是SQL 转储备份,SQL 转储是创建一个文本文件,这个文本里面都是 SQL 命令,当把这个文件回馈给服务器时,将重建与转储时状态一样的数据库。这种备份特点备份文件小。
2.另 一种备份是PITR,这个技术支持即时恢复是最大的特点。我们可以把数据库恢复到你开始备份以来的任意时刻的状态,持续把 WAL 文件序列填充给其它装载了同样的基础备份文件的机器,我们就有了一套"热备份"系统。然而这个方法缺点是只能支持整个数据库集群的恢复,而不能只单单恢复 某一个数据库,且备份的文件数据量要比SQL 转储备份大很多。
参考:http://man.ddvip.com/database/PostgreSQL80zhref/source/backup-online.html
3.SQL 转储备份打包后FTP分别上传到MGT服务器上的/dbbak/pgsql/目录下,其文件名类似Prod20081020.tar.gz,表示此备份文 件于2008年10月20日备份的。PITR备份也打包后通过FTP上传到/dbbak/pgsql/prod_wal目录下,其中类似 Prod20081020.tar.gz为BASE文件, WAL0115.tar.gz为WAL文件,表示11日15点的WAL文件.
4.BAK1服务器解压缩BASE和WAL文件后进行恢复.就可以得到和DB服务器数据一致的数据库了.
二.各服务器的脚本
1.DB服务器上的脚本1:Database_HotBackup.pl
此脚本主要是对数据库集BASE文件进行备份。

--------------------------------------------------------
#!/usr/bin/perl
# Use to hot backup the PostgreSQL database.
# Date:2008-07-22 立秋云
# File Name: Database_HotBackup.pl
my($datadir)="/var/lib/pgsql/data";
my($bindir)="/usr/bin";
my($backupdir)="/backup/base";
use POSIX qw(strftime);
$date=strftime "%Y%m%d", localtime;
sub begin_backup()
{
open(PSQL,"|$bindir/psql")||exit(100);
printPSQL "select pg_start_backup('backupnow');/n";
close(PSQL);
}
sub end_backup()
{
open(PSQL,"|$bindir/psql")||exit(100);
printPSQL "select pg_stop_backup();/n";
close(PSQL);
}
sub do_backup()
{
system("/bin/cp $datadir$backupdir/data -a");
system("/bin/tar zcvf base.tar.gz $datadir");
system("/bin/mv -f base.tar.gz $backupdir/$date.tar.gz");
}
#tell psql begin our backup
&begin_backup();
#do tar
&do_backup();
#tell psql end backup
&end_backup();
--------------------------------------------------------
2.DB服务器上的脚本2:pg_bak.sh
此脚本实现SQL转储备份和FTP上传。把SQL转储文件上传到MGT服务器上备份。把BASE文件通过FTP分别传到BAK1和BAK2服务器上。
--------------------------------------------------------
#!/bin/sh
#备份数据库文件,by 立秋云 2008-10-17
#文件名: pg_bak.sh
DD=`date "+%Y%m%d"`#获取当前日期如20081010
DD1=`date '+%Y%m%d'-d '-1 day'`#获取一天前的日期
DD7=`date '+%Y%m%d'-d '-7 day'`#获取七天前的日期
DDM=`date '+%Y%m%d'-d '-2 month'`#获取一个月前的日期
SOURCE_DIR="/home/postgres/dbback" #定义需要备份文件所在的目录
#DB1=" DB1"#需要备份的数据库一
#DB2=" DB2"#需要备份的数据库二
DB3="DB3"#需要备份的数据库二
LOG="/home/postgres/log" #日志存放的目录
FTP_DIR="/dbbak/pgsql" #备份到FTP服务器所在的目录
BACK_FILE="Prod${DD}.tar.gz" #打包后的文件名
FTP_SERVER="192.168.96.131"#FTP服务器地址
FTP_USER="dbback"#FTP服务器用户名
FTP_PASSWD="passwd"#FTP服务器密码
FTP="${DD}ftp.log" #FTP日志名
BASE_DIR="/backup/base"
#备份从数据库dump
#/usr/bin/pg_dump -Fc $DB1 >${SOURCE_DIR}/${DD}${DB1}.dump
#/usr/bin/pg_dump -Fc $DB2 >${SOURCE_DIR}/${DD}${DB2}.dump
/usr/bin/pg_dump -Fc$DB3>${SOURCE_DIR}/${DD}${DB3}.dump
#删除老文件
cd${SOURCE_DIR}
tar -zcvfProd${DD}.tar.gz ${DD}*.dump
rm -rf${DD1}*.dump #删除一天前的dump文件
rm -rfProd${DD7}.tar.gz#删除七天前的dump.tar.gz文件
rm -rf$BASE_DIR/${DD7}.tar.gz#删除七天前的BASE.tar.gz文件
#FTP上传
echo"open $FTP_SERVER">$FTP
echo"user $FTP_USER$FTP_PASSWD" >>$FTP
echo"bin">>$FTP
echo"lcd $SOURCE_DIR">>$FTP
echo"cd $FTP_DIR">>$FTP
echo"mput $BACK_FILE">>$FTP
echo"">>$FTP
#echo "chmod 666 Prod${DDM}.tar.gz">> $FTP
#echo "delete Prod${DDM}.tar.gz" >> $FTP
echo"cd prod_wal">>$FTP
echo"lcd $BASE_DIR">>$FTP
echo"mput ${DD}.tar.gz">>$FTP
echo"">>$FTP
#echo "chmod 666 ${DDM}.tar.gz">> $FTP
#echo "delete ${DDM}.tar.gz" >> $FTP
echo"disconnect" >>$FTP
echo"open 192.168.96.130">>$FTP
echo"user $FTP_USER$FTP_PASSWD" >>$FTP
echo"bin">>$FTP
echo"lcd $BASE_DIR">>$FTP
echo"cd$BASE_DIR">>$FTP
echo"mput ${DD}.tar.gz">>$FTP
echo"">>$FTP
echo"bye">>$FTP
ftp -in<$FTP
mv -f$FTP$LOG
--------------------------------------------------------
3.DB服务器上的脚本3: wal_bak.sh
此脚本把WAL文件通过FTP分别传到BAK1服务器和BAK2服务器。
--------------------------------------------------------
#!/bin/sh
#备份WAL文件,by 立秋云 2008-10-17
#文件:wal_bak.sh
#定义变量
DATA_DIR="/var/lib/pgsql/data/pg_xlog"
BACKUP_DIR="/backup/archive"
DD=`date "+%d%H"`
DD1=`date '+%d%H'-d '-1 day'`
DD7=`date '+%d%H'-d '-7 day'`
FTP_DIR="/dbbak/pgsql/prod_wal"
BACK_FILE="WAL${DD}.tar.gz"
FTP_SERVER="192.168.96.131"
FTP_USER="dbback"
FTP_PASSWD="passwd"
FTP="ftp.log"
#备份
rm -rf${BACKUP_DIR}/0000000*
cd${DATA_DIR}
cp -f-a${DATA_DIR}/*${BACKUP_DIR}/
tar zcvf WAL.tar.gz *
mv -fWAL.tar.gz ${BACKUP_DIR}/WAL${DD}.tar.gz
#上传
echo"open $FTP_SERVER">$FTP
echo"user $FTP_USER$FTP_PASSWD" >>$FTP
echo"lcd $BACKUP_DIR">>$FTP
echo"bin">>$FTP
echo"prompt" >>$FTP
echo"cd $FTP_DIR">>$FTP
echo"mput $BACK_FILE">>$FTP
echo"chmod 666 WAL${DD7}.tar.gz" >>$FTP
echo"delete WAL${DD7}.tar.gz">>$FTP
echo"disconnect" >>$FTP
echo"open 192.168.96.130">>$FTP
echo"user $FTP_USER$FTP_PASSWD" >>$FTP
echo"lcd $BACKUP_DIR">>$FTP
echo"bin">>$FTP
echo"cd $BACKUP_DIR" >>$FTP
echo"prompt" >>$FTP
echo"mput $BACK_FILE">>$FTP
echo"bye">>$FTP
ftp -in<$FTP
#删除老文件
rm -rf$FTP
cd$BACKUP_DIR
rm -rfWAL${DD1}.tar.gz
--------------------------------------------------------
每天晚上自动执行
su postgres
crontab –e
加入一下内容使之自动执行。
--------------------------------------------------------
15* * * * /script/wal_bak.sh >/dev/null 2>&1
20* * * /script/Database_HotBackup.pl >/dev/null 2>&1
241* * * /script/pg_bak.sh >/dev/null 2>&1
--------------------------------------------------------
4.BAK1服务器上的脚本1: pg_wal_reset.sh
此脚本用来恢复数据库。每天晚上自动执行。使用命令crontab –e编辑使之自动执行此脚本。
类似于:44 4 * * * /script/pg_wal_reset.sh > /dev/null 2>&1 表示凌晨4:44分自动执行pg_wal_reset.sh脚本。
--------------------------------------------------------
#!/bin/sh
#文件名:pg_wal_reset.sh 立秋云
#定义变量
DH=`date "+%d%H"`#获取当前日期和小时,形如1210表示12日10点.可以手动指定时间.
DH7=`date '+%d'-d '-7 day'`
DD=`date "+%Y%m%d"`
DD1=`date '+%Y%m%d'-d '-1 day'`
DD7=`date '+%Y%m%d'-d '-7 day'`
service postgresql stop
cd/symphony
mv pgsql_datapgsql_data${DD1} #备份原数据集
mkdir pgsql_data
chown postgres:postgres pgsql_data
chmod 700pgsql_data
rm -rf/var/lib/pgsql/data${DD7}
#恢复base文件
cd/backup/base
rm -rf/backup/base/symphony
tar zxvf ${DD}.tar.gz
cp -a-fsymphony/pgsql_data/*/var/lib/pgsql/data/
echo"restore_command = 'cp /backup/archive/wal/%f %p'">/var/lib/pgsql/data/recovery.conf
cd/var/lib/pgsql/data
chown postgres:postgres recovery.conf
rm recovery.done
#恢复wal文件
cd/backup/archive
rm -rf/backup/archive/wal/*
tar zxvf WAL${DH}.tar.gz -Cwal
service postgresql start
#rm -rf /backup/base/${DD7}.tar.gz
rm -rf/backup/archive/WAL${DH7}*.tar.gz
--------------------------------------------------------
5.BAK1服务器上的脚本2:pg_wal_manual.sh
此脚本用来手动恢复数据库。
--------------------------------------------------------
#!/bin/sh
#文件位置: pg_wal_manual.sh 立秋云
#定义变量
##获取当前日期和小时,形如1210表示12日10点.可以手动指定时间.
DH=`date "+%d%H"`
DH7=`date '+%d'-d '-7 day'`
DD=`date "+%Y%m%d"`
DD1=`date '+%Y%m%d'-d '-1 day'`
DD7=`date '+%Y%m%d'-d '-7 day'`
service postgresql stop
cd/var/lib/pgsql/data/
rm recovery.done
echo"restore_command = 'cp /backup/archive/wal/%f %p'">/var/lib/pgsql/data/recovery.conf
chown postgres:postgres recovery.conf
#恢复wal文件
cd/backup/archive
rm -rf/backup/archive/wal/*
tar zxvf WAL${DH}.tar.gz -Cwal
service postgresql start
--------------------------------------------------------
6.BAK2服务器上SQL转储恢复脚本pg_restore.sh
--------------------------------------------------------
#!/bin/sh
#BY立秋云
#pg_restore.sh
#定义变量
DD=`date "+%Y%m%d"`
SOURCE_DIR="/dbbak/pgsql"
BACK_FILE="Prod${DD}.tar.gz"
cd$SOURCE_DIR
rm -rf*.dump
#还原
cd$SOURCE_DIR
tar zxvf $BACK_FILE
#pg_restore -cd DB1 ${DD}DB1.dump
#pg_restore -cd DB2 ${DD}DB2.dump
pg_restore -cdDB3 ${DD}DB3.dump
--------------------------------------------------------


来源:

立秋云的博客

你可能感兴趣的:(postgres)