PostgreSQL的PITR技术(Point-In-Time-Recovery)

PostgreSQL的PITR技术(Point-In-Time-Recovery),第1张

概述PostgreSQL的PITR技术(Point-In-Time-Recovery) (by linux_prog@loveopensource.com ) 为什么要写这篇文章? 因为我看了一下,国内所有的PostgreSQL教程都没有很详细的介绍该功能,而相反,国内的Oracle 文章对这块非常的看重。虽然,PostgreSQL的官方文档有一个章节是介绍这块内容的, 但是写得太过理论化,没有能够留 Postgresql的PITR技术(Point-In-Time-Recovery)
(by linux_prog@loveopensource.com )

为什么要写这篇文章?
因为我看了一下,国内所有的Postgresql教程都没有很详细的介绍该功能,而相反,国内的Oracle
文章对这块非常的看重。虽然,Postgresql的官方文档有一个章节是介绍这块内容的,
但是写得太过理论化,没有能够留给读者很深刻的印象。
的确,一个数据库的可靠性和完整性是非常重要的,否则,很难叫人们所接受它。

本文假设读者对Postgresql已经有基本的认识,如果你对Postgresql还完全不熟悉的话,建议你先
去http://www.postgresql.org看看它的Documentation.
作为最强大的开源数据库,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命令每分钟都会重复的拷贝前面已经拷贝过的还没有
# 被postgresql的archive command备份的archive log,在生产环境可以使用rsync进行增量备份
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:linux_prog
##############################################################

my($datadir) =”/home/pgsql/database”;
my($bindir) =”/home/pgsql/bin”;
my($backupdir) =”/disk3/Postgresql/base”;
my($receiver) =” linux_prog@loveopensource.com “;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 protocolLOG: database system was interrupted at 2005-04-11 23:13:28 PDTLOG: starting archive recoveryLOG: restore_command = ”cp /disk3/Postgresql/archives/%f ”%p”"cp: cannot stat `/disk3/Postgresql/archives/00000001.history’: No such file or directoryLOG: restored log file ”00000001000000000000002E.008EFCAC.backup” from archiveLOG: restored log file ”00000001000000000000002E” from archiveLOG: checkpoint record is at 0/2E8EFCACLOG: redo record is at 0/2E8EFCAC; undo record is at 0/0; shutdown FALSELOG: next transaction ID: 5271; next OID: 6351357LOG: automatic recovery in progressLOG: redo starts at 0/2E8EFCE8LOG: restored log file ”00000001000000000000002F” from archiveLOG: restored log file ”000000010000000000000030″ from archiveLOG: restored log file ”000000010000000000000031″ from archiveLOG: restored log file ”000000010000000000000032″ from archiveLOG: restored log file ”000000010000000000000033″ from archiveLOG: restored log file ”000000010000000000000034″ from archiveLOG: restored log file ”000000010000000000000035″ from archiveLOG: restored log file ”000000010000000000000036″ from archiveLOG: restored log file ”000000010000000000000037″ from archiveLOG: restored log file ”000000010000000000000038″ from archiveLOG: restored log file ”000000010000000000000039″ from archiveLOG: restored log file ”00000001000000000000003A” from archiveLOG: restored log file ”00000001000000000000003B” from archiveLOG: restored log file ”00000001000000000000003C” from archiveLOG: restored log file ”00000001000000000000003D” from archiveLOG: restored log file ”00000001000000000000003E” from archiveLOG: restored log file ”00000001000000000000003F” from archiveLOG: restored log file ”000000010000000000000040″ from archiveLOG: restored log file ”000000010000000000000041″ from archiveLOG: restored log file ”000000010000000000000042″ from archiveLOG: restored log file ”000000010000000000000043″ from archiveLOG: restored log file ”000000010000000000000044″ from archiveLOG: restored log file ”000000010000000000000045″ from archiveLOG: restored log file ”000000010000000000000046″ from archiveLOG: restored log file ”000000010000000000000047″ from archiveLOG: restored log file ”000000010000000000000048″ from archiveLOG: restored log file ”000000010000000000000049″ from archiveLOG: restored log file ”00000001000000000000004A” from archiveLOG: restored log file ”00000001000000000000004B” from archiveLOG: restored log file ”00000001000000000000004C” from archiveLOG: record with zero length at 0/4C2BABE4LOG: redo done at 0/4C2BABA8LOG: restored log file ”00000001000000000000004C” from archiveLOG: archive recovery completeLOG: database system is ready显示数据已经成功恢复。/home/pgsql/database/下面的recovery.conf会变为:recovery.done.结论:Postgresql8的PITR已经做得非常的成功,完全有可能作为Oracle,sqlserver以外的另外一种轻量级解决方案而成为企业的首选。所以,我们玩Postgresql的兄弟们,一定要对它有信心! 总结

以上是内存溢出为你收集整理的PostgreSQL的PITR技术(Point-In-Time-Recovery)全部内容,希望文章能够帮你解决PostgreSQL的PITR技术(Point-In-Time-Recovery)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1180785.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存