postgresql 热备份和恢复

作为现今最强大的开源数据库,PostgreSQL拥有一切商业数据库所拥有的功能。在以前的版本中,它在数据恢复,可靠性方面虽然做的差强人意,但经过近几年的稳步发展,现在的PostgreSQL已经可以和Oracle并驾齐驱了。

在PostgreSQL7的时候就引入了WAL(Write Ahead Logging)的概念,即预写日志,所有对数据库的更改,在更改之前必须写到该LOG中,这样,就算机器断电,PostgreSQL也可以从该LOG中知道数据库在断电前做了什么操作,已经做到第几步了,这样保证了所有事务的完整性,但PostgreSQL7没有提供很好的灾难恢复机制,一旦数据库崩溃,除非你曾经对数据库作过pg_dump或者file system level backup,否则,你的数据将全部丢失,并且,就算你曾经对数据库做过备份,也只能恢复到你备份的那一刻的数据,这对一个生产数据库(特别是24*7生产库)来说,是无法容忍的。

PostgreSQL8的推出,使PostgreSQL的稳定性和可靠性又迈出了划时代的一步。除了提供对tablespace的支持外,PostgreSQL8提供了支持时间点的恢复---PITR.

基本原理和Oracle的热备份完全一样:

首先,对数据库在file system level做一个backup(PostgreSQL是首先用pg_start_backup('label')命令,然后用tar直接tar整个data目录,假设命名为base.tar,然后pg_stop_backup();结束热备。

Oracle首先是用alter tablespace xxx begin backup,然后直接cp数据文件);

然后,备份相关的配置文件(PostgreSQL只需备份postgresql.conf,pg_hba.conf,pg_ident.conf就可以了,其实,前面的tar已经将这些文件备份了,Oracle需要alter database backup control file......);

最后,备份WAL(

可以设置postgresql.conf中的archive_command,

该命令可以让PostgreSQL8自动将需要的归档的日志文件备份的其他地方中。

但是注意:如果你是让PostgreSQL8调用archive_command来备份WAL的话,

可能根本就做不到PITR,我做过实验,如果依靠base.tar和archive_command产生的WAL其实只能恢复到最后一个archive_command保存的WAL的数据,pg_xlog/下面可能还有数据,如果PostgreSQL8的数据目录彻底损坏的话,还是会丢失数据,所以,我建议,在写数据备份脚本的时候,最好将pg_xlog/下面的WAL也一起备份,见下面的cpArch.sh)。

如果数据库崩溃,我们就可以使用热备产生的base.tar和archive_command产生的WAL和我们自己备份的WAL(pg_xlog)来进行数据库的

recovery.

下面举例来说明:

我的PostgreSQL运行在:/home/pgsql/下面

数据目录在:/home/pgsql/database/

将热备数据文件备份到/disk3/PostgreSQL/base/下面

将WAL备份到/disk3/PostgreSQL/archives/下面

postgresql.conf中定义了如下的archive_command:

archive_command = 'cp -f %p /disk3/PostgreSQL/archives/%f'

该命令会将PostgreSQL产生的WAL cp到/disk3/PostgreSQL/archives/中。

 

热备参考脚本如下:

(1)为了使丢失的数据在一分钟之内,在crontab中每分钟将pg_xlog/下面的WAL

backup到/disk3/PostgreSQL/archives/。

crontab:
*/1 * * * * /home/pgsql/bin/cpArch.sh

cpArch.sh:
#!/bin/sh

cp -f /home/pgsql/database/pg_xlog/[0-9]* /disk3/PostgreSQL/archives/

(2)编写热备脚本 hotBackup.pl (我用的是perl):

#!/usr/bin/perl

############################################
# hotBackup.pl
# Use to hot backup the PostgreSQL database.
# Author:Seamus Dean
# Date:2005-04-11
############################################

my($datadir) ="/home/pgsql/database";
my($bindir) ="/home/pgsql/bin";
my($backupdir) ="/disk3/PostgreSQL/base";
my($receiver) ="ljh13\@sina.com.cn";

sub begin_backup()
{
    open(PSQL,"|$bindir/psql") or mail_user
("begin backup error.") && exit(100);
    print PSQL "select pg_start_backup('backupnow');\n";
    close(PSQL);
}

sub end_backup()
{
    open(PSQL,"|$bindir/psql") or mail_user
("end backup error.") && exit(100);
    print PSQL "select pg_end_backup();\n";
    close(PSQL);
}


sub do_backup()
{
    system("/bin/tar cvf base.tar $datadir");
    system("/bin/mv -f base.tar $backupdir/");
}


sub mail_user()
{
    my($msg) =@_;
    open(MAIL,"|/bin/mail -s backup-result $receiver") 
or die("can not talk to:mail command.\n");
    print MAIL $msg;
    close(MAIL);
}

###################################
# tell psql begin our backup
###################################
&begin_backup();

###################################
# do tar
###################################
&do_backup();

####################################
# tell psql end backup
####################################
&end_backup();

####################################
# mail the user about the result
####################################
&mail_user("PostgreSQL backup successfully.");

到这里,备份脚本基本上就完了,你可以将hotBackup.pl放在crontab中周期性的执行。

就算/home/pgsql/database目录彻底崩溃,我们可以像下面这样迅速恢复到1分钟内的数据:

#cp /disk3/PostgreSQL/base/base.tar ./
#tar xvf base.tar
#cd database/
#vi recovery.conf

输入如下内容:

restore_command='cp /disk3/PostgreSQL/archives/%f "%p"'

然后将/home/pgsql/database/pg_xlog/下面的WAL清空。

启动PostgreSQL,我们可以看到如下的LOG信息:

LOG: could not create IPv6 socket: 
Address family not supported by protocol
LOG: database system was interrupted at 2005-04-11 23:13:28 PDT
LOG: starting archive recovery
LOG: restore_command = "cp /disk3/PostgreSQL/archives/%f "%p""
cp: cannot stat `/disk3/PostgreSQL/archives/00000001.history': 
No such file or directory
LOG: restored log file "00000001000000000000002E.008EFCAC.
backup" from archive
LOG: restored log file "00000001000000000000002E" from archive
LOG: checkpoint record is at 0/2E8EFCAC
LOG: redo record is at 0/2E8EFCAC; undo record is at 0/0; 
shutdown FALSE
LOG: next transaction ID: 5271; next OID: 6351357
LOG: automatic recovery in progress
LOG: redo starts at 0/2E8EFCE8
LOG: restored log file "00000001000000000000002F" from archive
LOG: restored log file "000000010000000000000030" from archive
LOG: restored log file "000000010000000000000031" from archive
LOG: restored log file "000000010000000000000032" from archive
LOG: restored log file "000000010000000000000033" from archive
LOG: restored log file "000000010000000000000034" from archive
LOG: restored log file "000000010000000000000035" from archive
LOG: restored log file "000000010000000000000036" from archive
LOG: restored log file "000000010000000000000037" from archive
LOG: restored log file "000000010000000000000038" from archive
LOG: restored log file "000000010000000000000039" from archive
LOG: restored log file "00000001000000000000003A" from archive
LOG: restored log file "00000001000000000000003B" from archive
LOG: restored log file "00000001000000000000003C" from archive
LOG: restored log file "00000001000000000000003D" from archive
LOG: restored log file "00000001000000000000003E" from archive
LOG: restored log file "00000001000000000000003F" from archive
LOG: restored log file "000000010000000000000040" from archive
LOG: restored log file "000000010000000000000041" from archive
LOG: restored log file "000000010000000000000042" from archive
LOG: restored log file "000000010000000000000043" from archive
LOG: restored log file "000000010000000000000044" from archive
LOG: restored log file "000000010000000000000045" from archive
LOG: restored log file "000000010000000000000046" from archive
LOG: restored log file "000000010000000000000047" from archive
LOG: restored log file "000000010000000000000048" from archive
LOG: restored log file "000000010000000000000049" from archive
LOG: restored log file "00000001000000000000004A" from archive
LOG: restored log file "00000001000000000000004B" from archive
LOG: restored log file "00000001000000000000004C" from archive
LOG: record with zero length at 0/4C2BABE4
LOG: redo done at 0/4C2BABA8
LOG: restored log file "00000001000000000000004C" from archive
LOG: archive recovery complete
LOG: database system is ready

显示数据已经成功恢复。

/home/pgsql/database/下面的recovery.conf会变为:recovery.done.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值