PG备份和恢复

备份和恢复

理解和控制崩溃恢复

如果PG崩溃了,在服务日志中应该会出现安全级别为panic的一条消息。PG将立即重启并尝试使用事务日志或预写日志进行恢复

WAL由写入PG的data目录中的pg_xlog子目录中的一系列文件组成。数据库中的任何变动都先写入WAL,当一个事务被提交,默认且安全的行为是强制WAL日志被刷入磁盘。如果PG崩溃了,WAL可以被重新执行,这将使数据库还原到最后一条事务提交后的状态,确保了数据库改变的持久性

数据库本身改变不会在事务提交时被写入磁盘,这种改变在正确调优的服务器中会稍后通过后台写入程序写入

崩溃恢复会重新执行WAL,恢复一般从检查点的位置开始恢复。恢复需要的时长取决于最后的检查点之后事务日志中做的改变数。检查点对于恢复来说是已知安全的开始点,因为检查点时刻已将所有当前未完成的数据库改变写入磁盘

对于繁忙的数据库服务,检查点会变成性能瓶颈,因为这个时候会有大量写请求

检查点既可以被立即执行,也可以按计划执行。立即执行的检查点由超级用户发起的某些动作触发,例如checkpoint命令或其他命令;计划执行的检查点操作由PG自行决定。

 

要确保pg_xlog目录挂载的磁盘最少有3*16MB*checkpoint_segments或者16MB*wal_keep_segments中较大一项值的空间。

这是基于短期内负载没有改变的假设,实际上WAL文件数可能更多,因为PG会根据需求产生足够多的WAL文件,并在checkpoint操作完成后将这些文件从pg_xlog中删除

在PG之后的版本中,这个复杂的参数被max_wal_size参数取代。内部还是会使用这些相同的公式

 

恢复会一直持续到事务日志末尾,WAL文件是被持续写入的,因此没有结束点;实际上结束点就是最后一条正确的记录。每条WAL记录都包含独立的CRC校验,所以可以在处理记录之前知道它是否完成且正确。每条记录都包含一个指向前一条记录的指针,因此可以分辨出WAL中由动作记录链组成的有效链表。这种结构导致的结果是,恢复过程通常因读下一条WAL引发的某种错误而结束

恢复的速度可以很快,不过它依赖于恢复的动作

 

对一个数据库进行热逻辑备份

逻辑备份通过转储每张表的内容来实现对数据库数据的一个备份

pg_dump工具产生一个输出文件,若有必要,可以使用split命令将输出文件分割成数块

pg_dump归档文件,也就是自定义格式(custom format),默认是轻量压缩,可以取消压缩或进行更高压缩率的压缩

pg_dump通过在数据库中执行SQL语句来导出数据,当PG运行一个SQL语句时,生成了一个当前事务的“快照”,它能冻结视角中的数据库。9.3开始,pg_dump可以使用快照输出功能并行转储一个数据库,快照输出功能是在上一个版本引入的

无法在连接到多个数据库的多个会话间共享快照,所以在多个数据库中完全一致地并行运行多个pg_dump

快照的生成时间是我们唯一能恢复到的时间——无法恢复到哪个时间点之前或者之后,快照时间是开始备份的时间而不是结束的时间

当pg_dump运行时,他在被转储的表上施加了最低级的锁。这种锁被设计用于在对表进行转储的时候避免在表上运行DDL。如果转储开始时已经有一个DDL在运行,转储会暂停并等待它运行完成。如果想限制等待的时间,可以设置--lock-wait-timeout选项

由于pg_dump提取数据时会运行SQL查询,因此使用它时会有一些性能损耗

pg_dump允许选择性地备份表,选项-t还允许指定视图或者序列生成器。无法使用pg_dump单独转储其他类型的对象

pg_dump快照发生的时间是其开始运行的时间,文件修改的时间就是转储完成的时间,转储时间和快照时间一致

 

对所有数据库进行热逻辑备份

使用pg_dumpall工具。 不建议使用:

1、如果使用pg_dumpall,则产生的唯一输出是一个脚本文件。脚本文件无法使用pg_restore的并行还原功能。使用此方法备份,恢复过程也会强制以比希望的速度慢的多的速度执行

2、pg_dumpall依次为每个数据库产生转储。意味着pg_dumpall比并行针对每个数据库运行一个pg_dump任务要慢

3、无法保证所有数据库都在同一时间转储

4、pg_dumpall选项和pg_dump非常相似,但有些功能不可用

 

对一个表空间中的所有表进行热逻辑备份

有时候希望转储一个表空间中的表和数据,没有简单的命令能够做到,需要写一些可重用脚本

一个表空间可能包含不止一个数据库中的对象,所以先使用下面查询获取需要转储哪些数据库的对象:postgres=# select datname from pg_database where oid in (select pg_tablespace_databases(ts.oid) from pg_tablespace ts where spcname = 'mytablespacename');

pg_dump允许在命令行指定多张表,所以可以直接从数据库中生成表的列表

用psql里面的命名参数生成一个参数化脚本,然后用它来生成一个转储

脚本名包含数据库名,可以降低在安装多个数据库的时候的出错概率

 

备份数据库对象的定义

仅转储定义的基本命令:pg_dumpall --schema-only > myscriptdump.sql

包含了所有对象,包括角色、表空间、数据库、模式、表、索引、触发器、约束、视图、函数、属主和访问权限

如果只想转储PG角色定义:pg_dumpall --roles-only > myroles.sql

如果只想转储PG表空间定义:pg_dumpall --tablespaces-only > mytablespaces.sql

同时转储角色和表空间定义,那么可使用:pg_dumpall --globals-only > myglobals.sql

输出是一个可读脚本文件,可再次运行重建每个数据库

--schema-only选项备份“数据库模式”,即数据库中(以及所有命名空间中)所有对象的定义。如果要备份某个数据库中命名空间中的定义和数据,则使用pg_dump的-n选项

 

独立的数据库热物理备份

物理备份允许一次性获得所有数据库的完全一致的视图,物理备份还允许即使在数据库中执行DDL改变的时候也能完成备份

物理备份是备份数据库的所有文件,但仅备份数据库文件不足以完成一个备份。简单备份数据库只能产生一个时间上不一致的数据库文件。要想让备份能在时间上一致,需要把从开始备份到完成备份之间的所有变动都添加进来

需要基础备份和适当的归档WAL文件来允许完成恢复

 

在线物理备份和持续归档

建立一个带有持续归档功能的在线物理备份,持续归档的目的是在恢复时,能够恢复到从备份开始的任何时间点

进行持续归档时,将生成连续的WAL文件。在某些事物率的情况下,一个数据库服务甚至可能每天生成100GB以上的归档日志。只需存储对备份有用的WAL文件,当决定不再需要保存某个备份时,可以从归档中删掉这些无用的WAL文件

在每个基础备份中会发现一个叫作backup_label的文件,一个物理备份需要的最早的WAL文件就是文件名由backup_label文件的第一行指定的文件

 

恢复所有数据库

恢复一个完整的数据库服务,包括所有的数据库是很重要的

PG被涉及成急需要少量信息就能执行一个恢复

逻辑恢复:逻辑恢复通过执行SQL来重建数据库对象

物理恢复:物理恢复在数据块级别重新执行对数据的改变,因此导致恢复速度比逻辑恢复快很多。物理恢复同时需要基础备份和一组归档的WAL文件

在基础备份的data目录中有个名为backup_label文件,告诉用户需要从归档中获得一个包含基础备份开始和结束的WAL位置的.backup文件。恢复过程必须从开始的WAL位置执行,且必须执行到结束的位置,才能保证对备份的恢复有效

恢复完成后,recovery.conf文件被重命名为recovery.done,以避免服务器重启时重新进入恢复过程

服务日志会记录从归档获得的每个WAL文件,因此可以检查进度和恢复完成的比例。可以在归档中查找最后一个WAL文件,用于计算还有多少文件需要恢复

如果文件被还原,restore_command应该返回零,如果失败应该返回非零。恢复过程会一直持续,直到不存在下一个WAL文件为止,因此在日志中最终总会有条出错信息被记录

如果丢失了一些WAL文件,或者某些文件被损坏,恢复过程会停止在那个点。数据库不会执行之后的任何改变,用户也会丢失那些改变

如果恢复过程正常开始,可以启停服务。启停服务不会影响恢复

如果有必要,可以在恢复过程中连接到数据库服务并运行查询

一旦恢复过程执行到了停止点,那么就可以让恢复过程在之后的任何一个时间点停止

 

恢复到一个时间点

PITR是基于时间点的恢复。是PG物理备份和恢复技术的别名

停止恢复的点称为恢复目标(recovery target)

恢复过程通过重做每条WAL记录实现,对应着每个数据块的改变,因此可能每个事务会有很多WAL记录。任何成功事务的最后部分都是一个提交类型的WAL记录,也存在终止事务的记录。每个事务的完成记录都包含了一个时间戳,可以判断是否在这个点停止恢复

也可以使用事务编号(xid)来定义恢复目标,不过找到要恢复的xid比较困难,可能要通过其他外部记录来找到它,条件是这些外部记录存在

恢复目标定义在recovery.conf文件中,且在服务运行时不允许被改变。如果打算改变恢复目标,可以关闭服务,编辑recovery.conf,然后重启服务。不过要注意,如果改变了恢复目标,而恢复进程已经跨过了此目标,则会出现错误。如果定义的recovery_target_time已经被越过,恢复进程将基本上会立即停止,这个点比正确的停止点要晚。如果定义的recovery_target_xid已经被越过,恢复过程将被继续,直到完成最后一个归档的日志文件。因此使用全新基础备份重新开始恢复比较安全

一旦服务完成恢复,它将分配一个新的时间轴。一旦服务完全恢复,就可以对数据库进行新的改变。这些改变可能和以前数据库上的“未来历史”中的改变有所不同。所以使用时间轴来区分不同未来。如果需要重新进行恢复,可以使用原来的或者新的时间轴来建立一个新的数据库历史状态

pg_dump工具无法用于生成PITR基础备份,其原因是日志的重演包含了数据库块的物理改变,而不是基于主键的逻辑改变。如果重新载入一个pg_dump生成的数据,则数据可能会写入不同数据块,因此发生的改变无法指向正确数据块

WAL包含的信息不足以完全重建产生改变的SQL。

 

恢复一个被删除/损坏的表

可能删掉或损坏一张表的方法有很多。表可能由于物理原因被损坏,也可能被写的很糟糕的删除更新语句损坏,因为有可能更新过多记录或者覆盖关键数据

1、逻辑恢复——通过pg_dump -F c 生成的自定义转储文件恢复

如果使用pg_dump生成了自定义格式的逻辑备份,那么可以从转储文件中简单地提取想要的表

2、逻辑恢复——通过脚本类型的转储恢复

3、物理恢复——没有办法一步就从物理备份中恢复一张表

 

恢复一个被删除/损坏的表空间

1、逻辑恢复——通过pg_dump -F c 生成的自定义转储文件恢复

2、逻辑恢复——通过脚本类型的转储恢复

3、物理恢复

 

恢复一个被删除/损坏的数据库

1、逻辑恢复——通过pg_dump -F c生成的自定义转储文件恢复

2、逻辑恢复——通过pg_dump生成的脚本转储文件恢复

3、逻辑恢复——通过pg_dumpall生成的脚本转储文件恢复

4、物理恢复

 

为备份/恢复提速

物理备份:提升物理备份性能的方法是通过并行备份,使用多个任务备份文件。备份的时候,可以跳过某些文件:

*任何被DBA放在data目录中的,实际上不应该在那里的文件

*pg_xlog中的任何文件

*pg_log的旧服务日志文件(甚至包括当前日志文件)。

逻辑备份:想备份数据库服务上的所有数据库,应该并行运行多个pg_dump任务。可能希望加速单个pg_dump任务的速度,但暂时没有

物理恢复:与物理备份类似,如果使用并行恢复,有可能用较快速度把一切还原,或者使用rsync一类的文件备份工具,可以通过自动重用现有文件来加速文件备份

逻辑恢复:无论是使用psql,还是pg_restore,都可以通过为进行恢复的用户在postgresql.conf文件中设置maintenance_work_mem = 128MB,或者更大值来加快处理速度

如果服务在运行归档或者在做流复制,事务日志的写可能会带来麻烦。可以通过增加WAL缓冲区大小并减少检查点操作的频率来解决此问题。将wal_buffers设置为16MB到64MB之间,并设置checkpoint_segments到1024,可以适当缓解此问题

如果不在运行归档或者流复制,或者在恢复时可以关闭它们,意味着有能力最小化事务日志的写入量。此情况下可能希望使用--single-transaction选项,也可以提高性能

若pg_dump使用的是-F c选项(自定义格式),那么可以使用并行模式进行恢复,如下:pg_resotre -j NumJobs

可能需要注意如何选择并行的程度。一个好的开始是使用CPU个数(实际上是CPU核心数,启用超线程的CPU可能会欺骗操作系统有更多CPU)。使用并行恢复的时候内存使用不要超出物理内存大小:每个任务可能使用到最多maintenance_work_mem内存,因此整个恢复过程可能因为碰到大索引而导致开始进行内存交换

无论要做什么,在建立每个对象后运行analyze。如果启用了autovacuum,会自动运行analyze。进行大型恢复时,通常禁用autovacuum会很有用,所以在完成恢复后要确认打开此开关。跳过这一步会导致在启动应用后产生很严重的性能问题,甚至有可能让人觉得数据库发生故障,停止响应

物理备份和恢复比较随意。可以用任何想用的方法,想多快就多快地复制文件。不管方法如何,把他们放回来就可以实现恢复

逻辑备份和恢复包括将数据移出移入数据库。明显比物理备份和恢复要慢,尤其是恢复、重建索引和约束会花费一些时间,即便是运行在并行模式中

压缩备份通常被认为是一种减小备份存储大小的方法,但即使是普通压缩也会消耗大量CPU

 

增量/差异备份和恢复

如果在备份大的PG数据库时出现了性能问题,可能需要增量备份或差异备份

增量备份是指只备份针对于最近的全备后发生变化的文件的备份。要进行恢复,必须恢复全量备份以及每个增量

差异备份是指备份最近的全备后发生的改变。同样恢复需要还原全备以及之后发生的全部改变

执行差异物理备份,可以用rsync对之前的全备和已有文件作比较,然后只覆盖改变的数据块。直接覆盖上一个备份不太好,最好保存两份或更多备份

PG不会明确追踪文件、表的最后修改日期或类似信息改变。PG的表存放在文件中,所以可以相信文件系统中文件的修改日期。但是有些情况下不可信,或者禁用了它,则无法做增量备份

pg_dump不支持指定where从句,即使添加了一个用来追踪最后变动日期的列last_changed_date,依旧需要手动去做一些工作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值