热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PostgreSQL数据库的PITR技术(Point-In-Time-Recovery)介绍

为什么要写这篇文章?因为我看了一下,国内所有的PostgreSQL教程都没有很详细的介绍该功能,而相反,国内的Oracle文章对这块非常的看重。虽然,PostgreSQL的官方文档有一个章节是介绍这块内容的,但是写得太过理论化,没有能够留给读者很深刻的印象。的

为什么要写这篇文章?
因为我看了一下,国内所有的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 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.

结论:
PostgreSQL8的PITR已经做得非常的成功,完全有可能作为Oracle,Sqlserver以外的另外一种
轻量级解决方案而成为企业的首选。
所以,我们玩PostgreSQL的兄弟们,一定要对它有信心!


推荐阅读
  • 大数据领域的职业路径与角色解析
    本文将深入探讨大数据领域的各种职业和工作角色,帮助读者全面了解大数据行业的需求、市场趋势,以及从入门到高级专业人士的职业发展路径。文章还将详细介绍不同公司对大数据人才的需求,并解析各岗位的具体职责、所需技能和经验。 ... [详细]
  • 本文介绍了如何在Linux系统中获取库源码,并在从源代码编译软件时收集所需的依赖项列表。 ... [详细]
  • 软件测试行业深度解析:迈向高薪的必经之路
    本文深入探讨了软件测试行业的发展现状及未来趋势,旨在帮助有志于在该领域取得高薪的技术人员明确职业方向和发展路径。 ... [详细]
  • JUnit下的测试和suite
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 龙蜥社区开发者访谈:技术生涯的三次蜕变 | 第3期
    龙蜥社区的开发者们通过自己的实践和经验,推动着开源技术的发展。本期「龙蜥开发者说」聚焦于一位资深开发者的三次技术转型,分享他在龙蜥社区的成长故事。 ... [详细]
  • CentOS下ProFTPD的安装与配置指南
    本文详细介绍在CentOS操作系统上安装和配置ProFTPD服务的方法,包括基本配置、安全设置及高级功能的启用。 ... [详细]
  • 本文详细探讨了在Web开发中常见的UTF-8编码问题及其解决方案,包括HTML页面、PHP脚本、MySQL数据库以及JavaScript和Flash应用中的乱码问题。 ... [详细]
  • PHP面试题精选及答案解析
    本文精选了新浪PHP笔试题及最新的PHP面试题,并提供了详细的答案解析,帮助求职者更好地准备PHP相关的面试。 ... [详细]
  • C# 中创建和执行存储过程的方法
    本文详细介绍了如何使用 C# 创建和调用 SQL Server 存储过程,包括连接数据库、定义命令类型、设置参数等步骤。 ... [详细]
  • 本文介绍如何通过整合SparkSQL与Hive来构建高效的用户画像环境,提高数据处理速度和查询效率。 ... [详细]
  • 探讨密码安全的重要性
    近期,多家知名网站如CSDN、人人网、多玩、开心网等的数据库相继被泄露,其中大量用户的账户密码因明文存储而暴露无遗。本文将探讨黑客获取密码的常见手段,网站如何安全存储用户信息,以及用户应如何保护自己的密码。 ... [详细]
  • 本文详细探讨了Spring框架中遇到的NoSuchBeanDefinitionException异常,具体涉及com.thinkplatform.dao.UserLogDao Bean未定义的问题,并提供了相应的解决方案。 ... [详细]
  • Ubuntu 环境下配置 LAMP 服务器
    本文详细介绍了如何在 Ubuntu 系统上安装和配置 LAMP(Linux、Apache、MySQL 和 PHP)服务器。包括 Apache 的安装、PHP 的配置以及 MySQL 数据库的设置,确保读者能够顺利搭建完整的 Web 开发环境。 ... [详细]
  • 本文介绍了编程语言的基本分类,包括机器语言、汇编语言和高级语言的特点及其优缺点。随后详细讲解了Python解释器的安装与配置方法,并探讨了Python变量的定义、使用及内存管理机制。 ... [详细]
  • 本文详细介绍了如何在 Ubuntu 16.04 系统上配置 Qt 5.5 的交叉编译环境,特别针对 i.MX6 平台进行了优化设置。内容涵盖从基本的软件安装到高级配置的全过程。 ... [详细]
author-avatar
李老鱼儿_654
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有