PostgreSQL9.0文档中“持续归档和基于时间点的恢..
时间:2010-08-18 来源:osdba
24.3 持续归档和基于时间点的恢复
PostgreSQL在数据目录的pg_xlog子目录中始终维护一个WAL日志文件。这个日志文件记录数据库数据文件的每个改变。这个日志文件存在的主要目的是为数据库异常崩溃后数据库能安全的恢复:如果系统崩崩溃后,PostgreSQL通过重放最后一次checkpoint后的日志文件把数据库恢复到一致状态。然而,这个日志文件的存在,提供了了第三种的数据库备份策略:我们可以把文件系统备份和WAL备份组合成来。当需要恢复的时候,我们先通过文件系统备份还原数据库,然后再重放我们备份的WAL日志,这样就把数据库带到了当前状态。对于管理者来说这个方法比前面的方法更复杂,但是它有以下更重要的好处:
24.3.1 Settup up WAL archiving 设置WAL归档 在一个抽象的场景中,一个运行的PostgreSQL数据库产生一个无限长的顺序的WAL记录。数据库物理的把这个WAL记录序列分割成WAL文件(每个WAL文件为一个WAL段),通常每个段的大小为16M(在编译PostgreSQL时可以通过编译选项改变这个大小)。这个段文件的名字是一个数字,用来反映它们在抽象的WAL序列中的位置。当不使用WAL归档时,系统也会创建一些WAL段文件,然后通过把不再需要的WAL文件改名成下一个日志号的方式循环的使用它们。能够被循环重复使用的WAL文件就是那些内容是最后一次checkpoint点之前的产生的的WAL文件。 在归档WAL数据时,我们需要抓取每个WAL段文件被填充的内容,在被循环使用之前把数据存储到其它地方。依赖于应用和可用的硬件,有不同的方法去把WAL数据归档到其它地方:我们能拷贝WAL文件到一个从另一台机器导出的NFS目录,或把它们写到磁带上(确保你能从磁带备份中识别出每个WAL文件的原始的名字),或批量的把它们刻录到光盘中,或着完全使用其它什么别的办法。为了提供数据库管理的灵活性,PostgreSQL并不对如何做存档的方法做任何假设,相反的,PostgreSQL让管理员指定一个特别的shell命令支执行WAL文件的归档任务。这个shell命令可以非常简单,如一个cp命令,或一个非常复杂的shell命令,这一切都取决你。 为了允许归档,需要把wal_level参数设置为“archive“或“hot_standby“,archive_mode参数设置为"on",并为archive_command命令指定一个shell命令。在实践中,postgresql.conf文件中将始终设置这些参数。在归档的命令中,“%p“用来替换需要归档的WAL全路径文件名,“%f“表示不带路径的文件名。(路径名是相对的当前的数据工作目录,即数据库的数据目录),如果你要使用“%“,请使用“%%”替代。最简单的归档命令为: archive_command = 'cp -i %p /mnt/server/archivedir/%f </dev/null' 这条命令将会把WAL文件拷贝到目录/mnt/server/archivedir目录(这仅是一个示例,而不是必须这样,同时这条命令也不是在所有平台都能正常工作).当“%p”和“%f”参数被替换后,实际的命令类似如下: cp -i pg_xlog/00000001000000A900000065 /mnt/server/archivedir/00000001000000A900000065 </dev/null 每个新WAL文件归档时类似这样的一条命令就会被数据库调用。 归档文件命令将以PostgreSQL服务器运行时的同一个用户去执行归档命令,被归档的一系列的WAL文件包含了数据库中任何有效的东西,你需要确保归档数据不会被非法访问,例如归档的目录不能有被其它用户读取的权限。 归档命令的返回值仅在成功的时候返加0,这是很重要的。当返回0时,PostgreSQL就会认为文件被成功的归档了,然后就会被删除或循环使用它们。反之,如果返回一个非零值,PostgreSQL会认为文件没有归档,然后会周期的重试,直到成功。 归档文件命令通常应旨在拒绝覆盖任何预先存在的文件。这是归档的一个重要的安全功能,当发生人为错误时能够保护你的归档(例如,将两个不同的服务器的WAL文件归档到了同一个目录中)。一个建议是测试您的存档命令,以确保它确实不覆盖现有的文件,同时最好在这种情况下返回非零状态。在许多的UNIX平台中,cp -i命令会提示是否覆盖一个文件,“</dev/null”会给出不覆盖的指示,然后命令以失败返回。如果你的平台不支持cp -i这个特性,你需要增加一个命令去测试文件是否存在。例如,命令可以类似如下: archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' 这条命令可以工作于大多数的UNIX平台。 在设计您的归档时,需要考虑当归档命令多次失败时将发生什么,如在某些方面需要操作员干预或归档文件运行空间不足的情况。例如:如果你写到不能自动换带的磁带的情况下,这就有可能发生。当磁盘满了,在更换磁盘前任何文件将不会被归档。您应确保任何错误或需要人工操作的要求能够被适当的报告出来,然后可以合理地快速解决。在这情况得到解决之前,pg_xlog目录一直会将处于满的状态。(如果px_xlog目录所在的文件系统满了,PostgreSQL将会做一个PANIC停机。未提交的事务将会丢失,一直到你释放空间之前数据库都会一直处于离线状态。 归档命令的速度是不重要的,只要它能跟上您的服务器生成WAL数据的平均速率。即使存档过程有点落后,但正常操作仍然能继续。如果归档大大落后,在一场灾难事件将会使丢失的数据量增加。它还意味着,在 pg_xlog/目录将包含大量的最终可能超过可用磁盘空间的未归档的WAL文件。建议您监视归档的过程,以确保它按您期望的那样工作。 编写您的归档命令时: 您应假定要归档文件的名称可以是最多64个字符,并且可以包含 ASCII 字母、 数字和“.”的任意组合。不需要保留原始的相对路径 (%p),但要保存的文件名称 (%f)。 请注意虽然 WAL存档将允许您恢复PostgreSQL数据库中的数据所做的任何修改,但不会恢复由于那些手动编辑而不是通过SQL操作配置文件(也就是 postgresql.conf、 pg_hba.conf 和 pg_ident.conf) 所做的更改。您可能希望在文件系统的备份过程将配置文件保存在一个位置中。如何重新定位配置文件请参见18.2节。 归档文件命令归档已经写完的WAL文件。因此,如果你的服务器生成很小WAL流量,完成的事务最后存储到归档记录中可能会有长时间的延迟。为一个限制未归档的数据最多时间是多少,可以设置archive_timeout参数去强制数据库切换到一个新的WAL文件。注意,强制切换的归档文件仍然有整个WAL文件的长度。因此设置非常短的archive_timeout时间是不明智的,它将增加你的归档存储空间。通常合理的archive_timeout值为1分钟。 如果要确保刚刚完成的事务记录尽快到归档中,可以强制手工调用pg_switch_xlog。与WAL管理相关的其他实用程序列在Table 9-56。 当wal_level设置为minimal时,一些sql命令被优化掉而不会记录在WAL日志中,请见14.4.7节。如果在执行一个这样的SQL语句时归档或流复制被打开,WAL不会包含足够的信息用于存档恢复。(crash恢复是不受影响的)。因为这样 wal_level只能在服务器启动时更改在。但是archive_command可以使用配置文件重新加载进行更改。如果想暂时停止存档做的一种方法是将 archive_command 设置为空字符串 ('')。这将导致 WAL 文件积累在pg_xlog目录,直到archive_command被重新设置。 24.3.2 制作数据库的基础备份 下面是制作数据库基础备份的一个相对简单的过程:
- 我们在开始备份数据库的时不再需要一个完美的一致性备份。在备份中的任何数据的非一致性都会被WAL日志文件的重放纠正。所以我们在备份数据库时不再需要一个特别的文件系统的快照就可以完成备份工作,例如通过tar或类似的文件归档工作就可以完成备份工作。
- 当我们组合一个无限长的WAL日文件的回放,持续的备份就可以通过不断的备份WAL日志文件来完成。这点对大数据库有特别重要的价值。因为这样,大数据库就不需要频繁的做全库备份了。
- 并不一定要把WAL文件一直重放到结束。我们能够重放到数据库到任何一个数据一致性的快照时间点,从而这项技术支持了基本时间点的恢复:你可以把数据库恢复到基础备份后的任一时间点。
- 如果我们持续的提供一系列的WAL日志文件给另一台机器上的从基础备份中还原出来的数据库,我们可以得到一个热备份的standby数据库:在任何时间我们都可以在第二台机器打开这个数据库,它拥有当前数据库的最近的数据状态。
24.3.1 Settup up WAL archiving 设置WAL归档 在一个抽象的场景中,一个运行的PostgreSQL数据库产生一个无限长的顺序的WAL记录。数据库物理的把这个WAL记录序列分割成WAL文件(每个WAL文件为一个WAL段),通常每个段的大小为16M(在编译PostgreSQL时可以通过编译选项改变这个大小)。这个段文件的名字是一个数字,用来反映它们在抽象的WAL序列中的位置。当不使用WAL归档时,系统也会创建一些WAL段文件,然后通过把不再需要的WAL文件改名成下一个日志号的方式循环的使用它们。能够被循环重复使用的WAL文件就是那些内容是最后一次checkpoint点之前的产生的的WAL文件。 在归档WAL数据时,我们需要抓取每个WAL段文件被填充的内容,在被循环使用之前把数据存储到其它地方。依赖于应用和可用的硬件,有不同的方法去把WAL数据归档到其它地方:我们能拷贝WAL文件到一个从另一台机器导出的NFS目录,或把它们写到磁带上(确保你能从磁带备份中识别出每个WAL文件的原始的名字),或批量的把它们刻录到光盘中,或着完全使用其它什么别的办法。为了提供数据库管理的灵活性,PostgreSQL并不对如何做存档的方法做任何假设,相反的,PostgreSQL让管理员指定一个特别的shell命令支执行WAL文件的归档任务。这个shell命令可以非常简单,如一个cp命令,或一个非常复杂的shell命令,这一切都取决你。 为了允许归档,需要把wal_level参数设置为“archive“或“hot_standby“,archive_mode参数设置为"on",并为archive_command命令指定一个shell命令。在实践中,postgresql.conf文件中将始终设置这些参数。在归档的命令中,“%p“用来替换需要归档的WAL全路径文件名,“%f“表示不带路径的文件名。(路径名是相对的当前的数据工作目录,即数据库的数据目录),如果你要使用“%“,请使用“%%”替代。最简单的归档命令为: archive_command = 'cp -i %p /mnt/server/archivedir/%f </dev/null' 这条命令将会把WAL文件拷贝到目录/mnt/server/archivedir目录(这仅是一个示例,而不是必须这样,同时这条命令也不是在所有平台都能正常工作).当“%p”和“%f”参数被替换后,实际的命令类似如下: cp -i pg_xlog/00000001000000A900000065 /mnt/server/archivedir/00000001000000A900000065 </dev/null 每个新WAL文件归档时类似这样的一条命令就会被数据库调用。 归档文件命令将以PostgreSQL服务器运行时的同一个用户去执行归档命令,被归档的一系列的WAL文件包含了数据库中任何有效的东西,你需要确保归档数据不会被非法访问,例如归档的目录不能有被其它用户读取的权限。 归档命令的返回值仅在成功的时候返加0,这是很重要的。当返回0时,PostgreSQL就会认为文件被成功的归档了,然后就会被删除或循环使用它们。反之,如果返回一个非零值,PostgreSQL会认为文件没有归档,然后会周期的重试,直到成功。 归档文件命令通常应旨在拒绝覆盖任何预先存在的文件。这是归档的一个重要的安全功能,当发生人为错误时能够保护你的归档(例如,将两个不同的服务器的WAL文件归档到了同一个目录中)。一个建议是测试您的存档命令,以确保它确实不覆盖现有的文件,同时最好在这种情况下返回非零状态。在许多的UNIX平台中,cp -i命令会提示是否覆盖一个文件,“</dev/null”会给出不覆盖的指示,然后命令以失败返回。如果你的平台不支持cp -i这个特性,你需要增加一个命令去测试文件是否存在。例如,命令可以类似如下: archive_command = 'test ! -f /mnt/server/archivedir/%f && cp %p /mnt/server/archivedir/%f' 这条命令可以工作于大多数的UNIX平台。 在设计您的归档时,需要考虑当归档命令多次失败时将发生什么,如在某些方面需要操作员干预或归档文件运行空间不足的情况。例如:如果你写到不能自动换带的磁带的情况下,这就有可能发生。当磁盘满了,在更换磁盘前任何文件将不会被归档。您应确保任何错误或需要人工操作的要求能够被适当的报告出来,然后可以合理地快速解决。在这情况得到解决之前,pg_xlog目录一直会将处于满的状态。(如果px_xlog目录所在的文件系统满了,PostgreSQL将会做一个PANIC停机。未提交的事务将会丢失,一直到你释放空间之前数据库都会一直处于离线状态。 归档命令的速度是不重要的,只要它能跟上您的服务器生成WAL数据的平均速率。即使存档过程有点落后,但正常操作仍然能继续。如果归档大大落后,在一场灾难事件将会使丢失的数据量增加。它还意味着,在 pg_xlog/目录将包含大量的最终可能超过可用磁盘空间的未归档的WAL文件。建议您监视归档的过程,以确保它按您期望的那样工作。 编写您的归档命令时: 您应假定要归档文件的名称可以是最多64个字符,并且可以包含 ASCII 字母、 数字和“.”的任意组合。不需要保留原始的相对路径 (%p),但要保存的文件名称 (%f)。 请注意虽然 WAL存档将允许您恢复PostgreSQL数据库中的数据所做的任何修改,但不会恢复由于那些手动编辑而不是通过SQL操作配置文件(也就是 postgresql.conf、 pg_hba.conf 和 pg_ident.conf) 所做的更改。您可能希望在文件系统的备份过程将配置文件保存在一个位置中。如何重新定位配置文件请参见18.2节。 归档文件命令归档已经写完的WAL文件。因此,如果你的服务器生成很小WAL流量,完成的事务最后存储到归档记录中可能会有长时间的延迟。为一个限制未归档的数据最多时间是多少,可以设置archive_timeout参数去强制数据库切换到一个新的WAL文件。注意,强制切换的归档文件仍然有整个WAL文件的长度。因此设置非常短的archive_timeout时间是不明智的,它将增加你的归档存储空间。通常合理的archive_timeout值为1分钟。 如果要确保刚刚完成的事务记录尽快到归档中,可以强制手工调用pg_switch_xlog。与WAL管理相关的其他实用程序列在Table 9-56。 当wal_level设置为minimal时,一些sql命令被优化掉而不会记录在WAL日志中,请见14.4.7节。如果在执行一个这样的SQL语句时归档或流复制被打开,WAL不会包含足够的信息用于存档恢复。(crash恢复是不受影响的)。因为这样 wal_level只能在服务器启动时更改在。但是archive_command可以使用配置文件重新加载进行更改。如果想暂时停止存档做的一种方法是将 archive_command 设置为空字符串 ('')。这将导致 WAL 文件积累在pg_xlog目录,直到archive_command被重新设置。 24.3.2 制作数据库的基础备份 下面是制作数据库基础备份的一个相对简单的过程:
- 确保WAL归档被打开和正常工作。
- 用超级用户连接到数据库并执行下面的命令:
- 安全的拷贝数据到离线的存储中。
- 每三小时批量的传输WAL文件,而不是每次一个文件。
- 与其它的备份恢复脚本进行交互。
- 与其它的监控系统进行交互和报告错误。
- 对hash索引的操作目前不会被记录到WAL日志中,所以应用WAL日志不会更新这些索引。这意味着任何新的插入将被索引忽略,更新的行也明显会消失,删除的行仍然保留着指针。换句话说,如果你修改了一个有hash索引的表,你将在standby上得到一个错误的查询结果。当恢复完成后,建议你手工的在这些hash索引上执行reindex.
- 当在进行基本备份的过程中,一个CREATE DATABASE命令被执行了,这时又修改了CREATE DATABASE命令使用的模板数据库,针对模板数据库的修改可能也被传播到standby的create database中。这当然不是我们希望的。为了避免这个风险,最好是在到基本备份时不要修改任何模板数据库。
- CREATE TABELSPACE命令中的路径被原样记录在WAL日志中,因而当恢复时创建出的表空间也使用这个绝对路径。如果我们在另一台机器上恢复时这可能不是我们希望的。在同一台机器上这也可能是危机,如果我们恢复数据库到一个新的数据目录: 恢复可能仍会覆盖原有的数据库。若要避免这种潜在问题,最好在创建或删除表空间后做一个新的基础备份。
相关阅读 更多 +