pg 备份恢复(三)—— 详解完整恢复及基于时间点的恢复

一、 恢复配置详解

1. 归档恢复配置

主库 postgresql.conf

  • archive_mode:是否开启归档,若要用归档方式搭建从库则必须开启
  • archive_command:归档命令,通常是cp
  • archive_timeout:在指定秒数后强制切换一个wal文件,注意被切换的文件会跟正常文件一样大,所以这个参数设置过小会导致wal大量占用空间

从库 recovery.conf

  • restore_command:告诉从库如何获取归档WAL文件段的命令,通常是cp
restore_command = 'cp /data/PRD/postgres/10.7/pg5432/pg_archlog/%f %p'
  • archive_cleanup_command:从库清理已不需要的wal日志,避免磁盘空间撑满
archive_cleanup_command='pg_archivecleanup /data/PRD/postgres/10.7/pg5432/pg_archlog %r'
  • recovery_end_command:恢复完成后执行指定命令

2. recovery target设置

下列选项进指定恢复目标

recovery_target:目前只能为immediate,指定恢复在达到一致状态后尽快结束,打开DB

recovery_target_name:由pg_create_restore_point()创建的还原点,用于恢复到指定还原点

recovery_target_time:恢复到指定时间点,最常用

recovery_target_xid:恢复到指定事务ID,在指定事务之前提交的事务将被恢复。注意事务ID是顺序分配的,但后分配的事务ID可能先完成。精确的停止点受recovery_target_inclusive影响。

recovery_target_lsn:恢复到WAL的指定LSN,精确的停止点也受 recovery_target_inclusive的影响。

 

下列选项进一步指定恢复目标,并且影响到达目标时会发生什么
recovery_target_inclusive:布尔值,指定恢复到恢复目标之后还是之前,默认为之后(true)

recovery_target_timeline:指定恢复的时间线。默认只沿着基础备份建立时时间线恢复而不会切换到新的时间线。通常设置为latest,这样便可恢复到该离当前最近的时间线。

recovery_target_action:指定在达到恢复目标时服务器采取的动作。

  • pause:默认值,表示恢复将被暂停
  • promote:表示恢复结束且服务器将开始接受连接
  • shutdown:表示在达到恢复目标之后停止服务器。

使用pause的目的是恢复到最想要的位置。当确定已恢复到最想要的位置,可以使用pg_wal_replay_resume()结束暂停的状态,这会让恢复终结。如果恢复的位置不是想要的,那么关闭服务器,重新设置恢复目标,然后启动DB继续恢复。

注意在recovery_target_action被设置为shutdown时,recovery.conf将不会被重命名,任何后续的启动都将会以立刻关闭为终结,除非该配置被改变或者recovery.conf文件被手工移除。

如果没有设置恢复目标,这个设置没有效果。如果没有启用hot_standby,pause设置的动作将和shutdown一样。

http://postgres.cn/docs/10/recovery-target-settings.html
 

二、 时间线——pg中的平行世界

这个概念感觉类似Oracle的化身(Incarnation)和小说电影里的平行世界。虽然可以通过PITR恢复到之前的时间点,相当于小说里时光倒流主角重生了,但回到的不再是原来的世界,而是去到了一个平行世界。

 

1. 为什么需要时间线

还是拿小说举例子,重生的主角通常都担心自己做了一点什么事情会影响历史的进程,当然小说电视剧里主角的影响最后总是会被历史修复。那pg能够修复回退后的更改吗?

比如某天17点开发来找你说误操作了,要恢复到15点的数据。好的,我们给他恢复了。恢复之后业务运行了半个小时,开发又来找你说,刚才搞错了应该恢复到16点的数据,能够做到吗?

如果没有时间线的概念而在15点后又没另外做备份,能用之前的备份+归档恢复到16点的数据吗?显然是不能的,因为在DB运行过程中产生了与旧WAL文件重名的文件,归档时覆盖原来的日志,导致恢复到16点需要的WAL文件丢失。

阿里云的博客有张图挺形象的

无时间线数据库恢复

 

2. 时间线的作用

为了解决这个问题,PostgreSQL引入了时间线的概念。每当归档文件恢复完成,创建一个新的时间线用来区别新生成的WAL记录。区别的方式很简单,就在WAL文件名里加入了时间线ID,由时间线和日志序号来组成WAL文件名,不会覆盖由以前的时间线生成的WAL。

$ ls -1
00000002.history
00000003.history
00000003000000000000001A
00000003000000000000001B

源码实现如下:

#define XLogFileName(fname, tli, log, seg)	\
    snprintf(fname, XLOG_DATA_FNAME_LEN + 1, "%08X%08X%08X", tli, log, seg)

有了时间线,只要备份和归档还在,我们小说的主角就能够重生到任意时间点了,但每次其实都相当于去到了一个平行世界,保证主角重生之后的所作所为不影响原来的世界。每个时间线也类似一个分支,在当前时间线的操作不会对其他时间线WAL造成影响。

有时间线数据库恢复

 

3. 何时会产生新时间线

  • 利用归档进行恢复,完整恢复和PITR都会

  • 从库激活为主库,即执行 pg_ctl promote –D $PGDATA

 

4. history文件

  • 何时产生:与时间线相同,每当创建一个新的时间线,pg都会创建一个“时间线历史”文件,文件名类似.history。
  • 内容:原时间线history文件的内容+一条当前时间线切换记录。

假设数据库恢复启动后,切换到新的时间线ID=5,那么文件名就是00000005.history ,该文件记录了自己是从什么时间哪个时间线什么原因分出来的(相当于主角重生之后还有记忆),该文件可能含有多行记录,每个记录的内容格式如下:

 * <parentTLI> <switchpoint> <reason>
 *
 *      parentTLI       ID of the parent timeline
 *      switchpoint     XLogRecPtr of the WAL position where the switch happened
 *      reason          human-readable explanation of why the timeline was changed

例如:

$ cat 00000004.history
1	0/140000C8	no recovery target specified
2	0/19000060	no recovery target specified
3	0/1F000090	no recovery target specified

当数据库在从包含多个时间线的归档中恢复时,这些history文件允许系统选取正确的WAL文件,当然,它也能像WAL文件一样被归档到WAL归档目录里。历史文件只是很小的文本文件,所以保存它们的代价很小。

当我们在recovery.conf指定目标时间线tli进行恢复时,程序首先寻找.history文件,根据.history文件里面记录的时间线分支关系,找到从pg_control里面的startTLI到tli之间的所有时间线对应的日志文件,再进行恢复。

 

参考

http://mysql.taobao.org/monthly/2015/07/03/

待补充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hehuyi_In

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值