Postgresql备份和恢复.docx

上传人:b****6 文档编号:7083974 上传时间:2023-01-17 格式:DOCX 页数:8 大小:26.41KB
下载 相关 举报
Postgresql备份和恢复.docx_第1页
第1页 / 共8页
Postgresql备份和恢复.docx_第2页
第2页 / 共8页
Postgresql备份和恢复.docx_第3页
第3页 / 共8页
Postgresql备份和恢复.docx_第4页
第4页 / 共8页
Postgresql备份和恢复.docx_第5页
第5页 / 共8页
点击查看更多>>
下载资源
资源描述

Postgresql备份和恢复.docx

《Postgresql备份和恢复.docx》由会员分享,可在线阅读,更多相关《Postgresql备份和恢复.docx(8页珍藏版)》请在冰豆网上搜索。

Postgresql备份和恢复.docx

Postgresql备份和恢复

Postgresql备份和恢复

和任何包含珍贵数据的东西一样,PostgreSQL数据库也应该经常备份。

尽管这个过程相当简单,但是我们还是应该理解做这件事所用的一些技巧和假设。

备份PostgreSQL数据有三种完全不同的方法:

SQL转储文件系统级别备份在线备份每种备份都有自己的优点和缺点。

SQL转储SQL转储的方法采用的主意是创建一个文本文件,这个文本里面都是SQL命令,当把这个文件回馈给服务器时,将重建与转储时状态一样的数据库。

PostgreSQL为这个用途提供了应用工具pg_dump。

这条命令的基本用法是:

pg_dumpdbname>outfile

正如你所见,pg_dump把结果输出到标准输出。

我们下面就可以看到这样做有什么好处。

pg_dump是一个普通的PostgreSQL客户端应用(尽管是个相当聪明的东西。

)这就意味着你可以从任何可以访问该数据库的远端主机上面进行备份工作。

但是请记住pg_dump不会以任何特殊权限运行。

具体说来,就是它必须要有你想备份的表的读权限,因此,实际上你几乎总是要成为数据库超级用户。

要声明pg_dump应该以哪个用户身份进行联接,使用命令行选项-hhost和-pport。

缺省主机是本地主机或你的环境变量PGHOST声明的值。

类似,缺省端口是环境变量PGPORT或(如果它不存在的话)编译好了的缺省值。

(服务器通常有相同的缺省,所以还算方便。

)和任何其他PostgreSQL客户端应用一样,pg_dump缺省时用与当前操作系统用户名同名的数据库用户名进行联接。

要覆盖这个名字,要么声明-U选项,要么设置环境变量PGUSER。

请注意pg_dump的联接也和普通客户应用一样要通过客户认证机制。

由pg_dump创建的备份在内部是一致的,也就是说,在pg_dump运行的时候对数据库的更新将不会被转储。

pg_dump工作的时候并不阻塞其他的对数据库的操作。

(但是会阻塞那些需要排它锁的操作,比如VACUUMFULL。

)Important:

如果你的数据库结构依赖于OID(比如说用做外键),那么你必须告诉pg_dump把OID也倒出来。

要倒OID,可以使用-o命令行选项。

缺省时也不会转储"大对象"。

如果你使用大对象,请参考pg_dump的命令手册页。

从转储中恢复pg_dump生成的文本文件可以由psql程序读取。

从转储中恢复的常用命令是psqldbname<infile

这里的infile就是你给pg_dump命令的outfile参数。

这条命令不会创建数据库dbname,你必须在执行psql前自己从template0创建(也就是说,用命令createdb-Ttemplate0dbname)。

psql支持类似pg_dump的选项用以控制数据库服务器位置和用户名。

参阅psql的手册获取更多信息。

在开始运行恢复之前,目标库和所有在转储出来的库中拥有对象的用户,以及曾经在某些对象上被赋予权限的用户都必须已经存在。

如果这些不存在,那么恢复将失败,因为恢复过程无法把这些对象恢复成原有的所有权和/或权限。

(有时候你希望恢复权限,不过通常你不需要这么做。

)一旦完成恢复,在每个数据库上运行ANALYZE是明智的举动,这样优化器就有有用的统计数据了。

你总是可以运行vacuumdb-a-z来VACUUMANALYZE所有数据库;这个等效于手工运行VACUUMANALYZE。

pg_dump和psql可以通过管道读写,这样我们就可能从一台主机上将数据库目录转储到另一台主机上,比如pg_dump-hhost1dbname|psql-hhost2dbnameImportant:

pg_dump生成的转储输出是相对于template0的。

这就意味着任何加入到template1的语言,过程等都会经由pg_dump转储。

结果是,在恢复的时候,如果你使用的是客户化的template1,那么你必须从template0中创建空的数据库,就象我们上面的例子那样。

有关如何有效地向PostgreSQL里装载大量数据的建议.使用pg_dumpall上面的方法在备份整个数据库集群的时候比较麻烦而且不方便。

因此我们提供了pg_dumpall程序。

pg_dumpall备份一个给出的集群中的每个数据库,同时还确保保留象用户和组这样的全局数据状态。

这个命令的基本用法是:

pg_dumpall>outfile

生成的转储可以用psql恢复:

psqltemplate1<infile

(实际上,你可以声明任意现有的数据库进行连接,但是如果你是向一个空的数据库装载,那么template1是你唯一的选择。

)恢复pg_dumpall的转储的时候通常需要数据库超级用户权限,因为我们需要它来恢复用户和组信息。

处理大数据库因为PostgreSQL允许表的大小大于你的系统允许的最大文件大小,可能把表转储到一个文件会有问题,因为生成的文件很可能比你的系统允许的最大文件大。

因为pg_dump输出到标准输出,你可以用标准的Unix工具绕开这个问题:

使用压缩的转储.使用你熟悉的压缩程序,比如说gzip。

pg_dumpdbname|gzip>filename.gz

用下面命令恢复:

createdbdbname

gunzip-cfilename.gz|psqldbname

或者catfilename.gz|gunzip|psqldbname使用split。

.split命令允许你你用下面的方法把输出分解成操作系统可以接受的大小。

比如,让每个块大小为1兆字节:

pg_dumpdbname|split-b1m-filename

用下面命令恢复:

createdbdbname

catfilename*|psqldbname使用客户化转储格式.如果PostgreSQL是在一个安装了zlib压缩库的系统上制作的,那么客户化转储格式将在写入输出文件的时候压缩数据。

它会生成和使用gzip类似大小的转储文件,但是还附加了一个优点:

你可以有选择地恢复库中的表。

下面的命令用客户化转储格式转储一个数据库:

pg_dump-Fcdbname>filename

客户化格式的转储不是脚本,不能用于psql,而是需要使用pg_restore转储。

请参考pg_dump和pg_restore的手册获取细节。

注意

出于向下兼容的考虑,缺省的时候pg_dump并不转储大对象。

要转储大对象,你必须使用客户化或者tar输出格式,并且在pg_dump中使用-b选项。

参阅pg_dump手册获取详细信息。

在PostgreSQL源码树的contrib/pg_dumplo路径里也包含一个可以转储大对象的程序。

另一个备份的策略是直接拷贝PostgreSQL用于存放数据库数据的文件。

tar-cfbackup.tar/usr/local/pgsql/data不过,你要受到两个限制,令这个方法不那么实用,或者至少比pg_dump的方法逊色一些:

为了进行有效的备份,数据库服务器必须被关闭。

象拒绝所有联接这样的折衷的方法是不行的,因为总是有一些缓冲区数据存在。

(主要因为tar和类似的工具在做备份的时候并不对文件系统的状态做原子快照)。

如果你曾经深入了解了数据库在文件系统布局的细节,你可能试图从对应的文件或目录里备份几个表或者数据库。

这样做是没用的,因为包含在这些文件里的信息只是部分信息。

还有一半信息在提交日志文件pg_clog/*里面,它包含所有事务的提交状态。

只有拥有这些信息,表文件的信息才是可用的。

当然,试图只恢复表和相关的pg_clog数据也是徒劳的,因为这样会把数据库集群里的所有其他没有用的表的信息都拿出来。

所以文件系统的备份只适用于一个数据库集群的完整恢复。

另外一个文件系统备份的方法是给数据目录做一个"一致的快照",条件是文件系统支持这个功能(并且你愿意相信它是实现正确的)。

典型的过程是制作一个包含数据库的卷的"冻结快照",然后把整个数据库目录(不仅仅是部分,见上文)从快照拷贝到备份设备,然后释放冻结快照。

这样甚至在数据库服务器在运行的时候都可以运转。

不过,这样创建的备份会把数据库文件保存在一个没有恰当关闭数据库服务器的状态下;因此,如果你在这个备份目录下启动数据库服务器,它就会认为数据库服务器经历过崩溃并且重放WAL日志。

这不是个问题,只要意识到它即可(并且确信在自己的备份中包含WAL文件)。

如果你的数据库分布在多个卷上(比如,数据文件和WAL日志在不同的磁盘上),那么可能就没有任何方法获取所有卷上准确的同步冻结快照。

在你新闻这样的情况下的一致性快照的技术之前,仔细阅读你的文件系统文档。

最安全的方法是关闭数据库服务器足够长的时间,以建立所有冻结快照。

还要说明的是,文件系统备份不会比SQL转储小。

恰恰相反,大多数情况下它要大。

(比如pg_dump不用倒出索引,只是创建它们的命令。

)在任何时候,PostgreSQL都在集群的数据目录的pg_xlog/子目录里维护着一套预写日志(WAL)。

这些日志记录着每一次对数据库的数据文件的修改的细节。

这些日志存在是为了防止崩溃:

如果系统崩溃,数据库可以通过"重放"上次检查点以来的日志记录以恢复数据库的完整性。

但是,日志的存在让它还可以用于第三种备份数据库的策略:

我们可以组合文件系统备份与WAL文件的备份。

如果需要恢复,我们就恢复备份,然后重放备份了的WAL文件,把备份恢复到当前的时间。

这个方法对管理员来说,明显比以前的方法更复杂,但是有非常明显的优势:

在开始的时候我们不需要一个非常完美的一致的备份。

任何备份内部的不一致都会被日志重放动作修改正确(这个和崩溃恢复时发生的事情没什么区别)。

因此我们不需要文件系统快照的功能,只需要tar或者类似的归档工具。

因为我们可以把无限长的WAL文件序列连接起来,所以连续的备份简化为连续地对WAL文件归档来实现。

这个功能对大数据库特别有用,因为大数据库的全备份可能并不方便。

我们可没说重放WAL记录的时候我们必须重放到结尾。

我们可以在任意点停止重放,这样就有一个在任意时间的数据库一致的快照。

因此,这个技术支持即时恢复:

我们可以把数据库恢复到你开始备份以来的任意时刻的状态。

如果我们持续把WAL文件序列填充给其它装载了同样的基础备份文件的机器,我们就有了一套"热备份"系统:

在任何点我们都可以启动第二台机器,而它拥有近乎当前的数据库拷贝。

和简单的文件系统备份技术一样,这个方法只能支持整个数据库集群的恢复,而不是一个子集。

同样,它还要求大量的归档存储:

基础备份量可能很大,而且忙碌的系统将生成许多兆需要备份的的WAL流量。

但是,它仍然时在需要高可靠性的场合下的最好的备份技术。

要想从在线备份中成功恢复,你需要一套连续的WAL归档文件,它们最远回朔到你开始备份的时刻。

因此,要想开始备份,你应该在开始第一次基础备份之前设置并测试你的步骤。

根据我们讨论过的归档WAL文件的机制。

1.设置WAL归档抽象来看,一个运行着的PostgreSQL系统生成一个无限长的WAL日志序列。

系统物理上把这个序列分隔成WAL段文件,通常一块时16M字节大(在制作PostgreSQL的时候可以改变其大小)。

这些段文件的名字是数值命名的,这些数值反映他们在抽取出来的WAL序列中的位置。

在不适用WAL归档的时候,系统通常只是创建几个段文件然后"循环"使用它们,方法是把不再使用的段文件的名字重命名为更高的段编号。

系统假设那些内容比前一次检查点更老的段文件是没用的了,然后就可以循环利用。

在归档WAL数据的时候,我们希望在每个段文件填充满之后捕获之,并且把这些数据在段文件被循环利用之前保存在某处。

根据应用以及可用的硬件的不同,我们可以有许多不同的方法"把数据保存在某处":

我们可以把段文件拷贝到一个NFS装配的目录,把它们放到另外一台机器上,或者把它们写入磁带机里(需要保证你有办法把文件恢复为原名),或者把它们打成包,烧录到CD里,或者是其它的什么方法。

为了给数据库管理员提供最大可能性的灵活性,PostgreSQL试图不对如何归档做任何假设。

取而代之的是,PostgreSQL让管理员声明一个shell命令执行来拷贝一个完整的段文件到它需要去的地方。

该命令可以简单得就是一个cp,或者它可以调用一个复杂的shell脚本—所有都由管理员决定。

所使用的shell命令由配置参数archive_command声明,它实际上总是放在postgresql.conf文件里的。

在这个字串里,任何%p都被要归档的文件的绝对路径代替,而任何%f只是被文件名代替。

如果你需要在命令里嵌入一个真正的%,写%%。

最简单的有用命令是类似下面这样的archive_command='cp-i%p/mnt/server/archivedir/%f</dev/null'

它将把WAL段拷贝到目录/mnt/server/archivedir。

这个只是一个例子,并非我们建议的方法,可能不能在所有系统上都正确运行。

归档命令将在运行PostgreSQL服务器的同一个用户的权限下执行。

因此被归档的WAL文件实际上包含你的数据库里的所有东西,所以你应该确保自己的归档数据不会被别人窥探;比如,归档到一个没有组或者全局读权限的目录里。

有一点很重要:

当且仅当归档命令成功时,它才返回零。

在得到一个零值结果之后,PostgreSQL将假设该WAL段文件已经成功归档,因此它稍后将被删除或者被新的数据覆盖。

但是,一个非零值告诉PostgreSQL该文件没有被归档;因此它会周期性的重试直到成功。

归档命令通常应该设计成拒绝覆盖已经存在的归档文件。

这是一个非常重要的安全特性,可以在管理员操作失误(比如把两个不同的服务器的输出发送到同一个归档目录)的时候保持你的归档的完整性。

我们建议你首先要测试你准备使用到归档命令,以保证它实际上不会覆盖现有的文件,并且在这种情况下它返回非零状态。

我们发现,在这方面,cp-i在某些平台上是正确的,而在其它平台上是不正确的。

如果选定的命令本身并不能正确处理这个问题,你应该增加一个命令预先探测归档文件是否存在。

比如,类似下面的东西。

archive_command='test!

-f.../%f&&cp%p.../%f'

在几乎所有的Unix变种上都工作正确。

在设计你的归档环境都时候,请考虑一下如果归档命令不停失败会发生什么情况,因为有些方面要求操作者的干涉,或者是归档空间不够了。

比如,如果你往磁带机上写,但是没有自动换带机,那么就有可能发生这种情况;如果磁带满了,那就除非换磁带,否则啥事也做不了。

你应该确保人和错误条件或者人和要求操作员干涉带错误都会正确报告,这样才能迅速解决这些问题。

否则pg_xlog/目录会不停地填充WAL段文件,直到问题解决。

归档命令的速度并不要紧,只要它能跟上你的服务器生成WAL数据的平均速度即可。

即使归档进程落在了后面一点,正常的操作也会继续进行。

如果归档进程慢很多,就会增加灾难发生的时候丢失的数据量。

同时也意味着pg_xlog/目录包含大量未归档的日志段文件,并且可能最后超出了磁盘空间。

我们建议你监控归档进程,确保它是按照你的意识运转的。

如果你关心能够恢复到当前即时的状态,你可能需要采取几个额外的步骤以确保当前的,部分填充的WAL段也拷贝到了某些地方。

这条对于生成很少WAL流量的服务器(或者在运行中有松弛阶段的)特别重要,因为在一个WAL段文件完全填充满进而可以归档之前,可能需要很长时间。

一个处理这些的可能的方法是设置一个cron作业,周期性(比如每分钟一次)地标识当前WAL段文件然后把它们保存到某个安全的地方。

归档的WAL段和保存的当前段就足够保证你可以总是恢复到当前时间的一分钟之内。

这个行为目前还不是内置于PostgreSQL的,因为我们不想把archive_command的定义复杂化,因为那样就要要求它跟踪成功归档但是却又有不同时刻含义的同一个WAL文件。

archive_command只是用于处理那些不再改变的WAL段文件;除了错误重试之外,对于任何给出的文件名他都只被调用一次。

在写自己的归档命令的时候,你应该假设被归档的文件最多64个字符长并且可以包含ASCII字母,数字,以及点的任意组合。

我们不必要记住原始的全路径(%p),但是有必要记住文件名(%f)。

请注意尽管WAL归档允许你回复任何对你的PostgreSQL数据库的数据做的修改,在最初的基础备份之后,它还是不会回复对配置文件的修改(也就是说,postgresql.conf,pg_hba.conf和pg_ident.conf),因为这些文件都是手工编辑的,而不是通过SQL操作来编辑的。

所以你可能会需要把你的配置文件放在一个日常文件系统备份过程即可处理到的地方。

2.进行一次基础备份

进行基础备份的过程相当简单:

确保WAL归档打开并且可以运转。

以数据库超级用户身份连接到数据库,发出命令SELECTpg_start_backup('label');

这里的label是任意你想使用的这次备份操作的唯一标识。

(一个好习惯是使用你想把备份转储文件放置的目的地的全路径。

)pg_start_backup用你的备份的信息,在你的集群目录里,创建一个备份标签文件,叫做backup_label。

至于你连接到集群中的那个数据库没什么关系。

你可以忽略函数返回的结果;但是如果它报告错误,那么在继续之前处理它。

执行备份,使用任何方便的文件系统工具,比如tar或者cpio。

这些操作过程中既不需要关闭数据库,也不希望关闭数据库的操作。

再次以数据库超级用户身份连接数据库,然后发出命令SELECTpg_stop_backup();

如果这个返回成功,你的工作就完成了。

我们不需要太关心在pg_start_backup和开始实际的备份之间开销的时间,也不需要太关心备份结束和pg_stop_backup之间的时间;几分钟的延迟不会搞砸事情。

不过,你必须确保这些操作是按顺序执行的而不是重叠执行的。

要保证你的备份转储包括所有数据库集群目录里的文件(比如,/usr/local/pgsql/data)。

如果你在使用并未放置在这个目录里的表空间,也要小心地包含它们(并且要确保你的备份转储归档符号连接是符号连接,否则,恢复会把你的表空间搞乱)。

不过,你可以在备份转储文件里省略集群目录里的pg_xlog/子目录。

这个略微复杂些的动作是值得的,因为它减少了恢复的时候的错误。

如果pg_xlog/是一个指向集群目录之外的一个符号连接,那么这件事情很容易处理,出于性能考虑的时候经常这么做。

要使用这个备份,你需要保存所有备份开始以及之后的WAL段文件。

为了帮助你实现这个任务,pg_stop_backup函数创建一个备份历史文件,它马上存储到WAL归档区域。

这个文件的名字是以你在使用备份的时候需要的第一个WAL段文件的名字命名的。

比如,如果开始WAL文件是0000000100001234000055CD,那么备份历史文件将命名为类似0000000100001234000055CD.007C9330.backup这样的东西。

(这个文件名的第二部分表示在该WAL文件里面的准确位置,通常可以被忽略。

)一旦你安全地把备份转储文件归了档,那么你就可以删除所有那些数值名字在这个文件前面的归档的WAL段。

备份历史文件只是一个小的文本文件。

它包含你给予pg_start_backup的标签字串,以及备份的起始时间和终止时间。

如果你使用这个标签来表示转储文件放在哪里,如果需要的话,那么归档的历史文件就足够告诉你转储文件存放在哪里了。

因为你必须保留直到你最后一次基础备份的所有归档的WAL文件,那么两次基础备份之间的间隔通常是根据你想在归档WAL文件上花多少存储空间来定的。

你还应该考虑你准备在恢复上花多少时间,如果需要恢复的话—系统将需要重放所有那些段,而如果最后一次基础备份以来,时间已经很长了,那么那些动作可能会花掉好些时间。

还有一件事值得一提,那就是pg_start_backup函数在数据库集群目录里创建了一个叫backup_label的文件,它被pg_stop_backup删除。

这个文件当然也会作为你的备份转储文件的一部分归档。

这个备份标签文件包含你给予pg_start_backup的标签字串,以及pg_start_backup运行的时刻,以及起始WAL文件的名字。

如果有混淆,那么我们可以看看备份转储文件里面然后判断转储文件来自那个备份会话。

我们还可以在postmaster停止的时候制作一个备份转储。

在这种条件下,很明显你不能使用pg_start_backup或者pg_stop_backup,并且因此你必须靠自己的手段来跟踪备份转储文件都是那些,以及相关的WAL文件最远走到哪里。

通常使用上面的在线备份步骤更好些。

3.从在线备份中恢复好,最糟糕的事情发生了,现在你需要从备份中恢复。

下面是步骤:

停止postmaster,如果它还在运行的话。

如果你还有足够的空间,把整个集群数据目录和所有表空间拷贝到一个临时位置,以防万一你之后还需要它们。

请注意这个预防措施要求你在系统里又足够的剩余空间来现有库的保持两份拷贝。

如果你没有足够的空间,那么你至少需要把集群数据目录的pg_xlog子目录的内容拷贝到安全的地方,因为它们可能包含系统宕掉的时候还没有归档的日志。

然后清理掉所有在该集群数据目录里的现存文件,以及所有你使用的表空间里根目录下的现存文件。

从你的备份转储中恢复数据库文件。

要小心用正确的所有者(数据库系统用户,而不是root!

)和权限恢复它们。

如果你使用了表空间,你可能需要核实在pg_tblspc/里的符号连接都得到正确恢复。

删除任何目前还在pg_xlog/里的文件;这些文件来自备份转储,因此它们可能比目前的老。

如果你就根本没有归档pg_xlog/,那么重建之,要注意也要重建子目录pg_xlog/archive_status/。

如果你有在步骤2里面保存的WAL段文件,那么把它们拷贝到pg_xlog/。

(最好是拷贝它们,而不是把它们移动回来,这样即使发生了糟糕的事情,你需要重启的时候,你也依然拥有未修改的文件。

)在集群数据目录里创建一个恢复命令文件recovery.conf(参阅RecoverySettings)。

你可能还需要临时修改pg_hba.conf以避免普通用户连接,直到你确信恢复已经正常了为止。

启动postmaster。

postmaster将进入恢复模式并且继续读取它需要的归档的WAL文件。

在恢复

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 英语学习

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1