转载:PostgreSQL时间线的实现

来自: http://zisedeqing.blog.163.com/blog/static/95550871201481115942717/、

1.1    基本原理

正常情况下,数据库是沿着一条时间线一直延伸的,但是如果中途,用户期望从归档中进行恢复,则这时数据库的时间线就会产生分支,沿着新的时间线延伸。如下图所示:

PG时间线的实现 - zisedeqing - 生命无非记忆

1.2    基本流程

使用时间线进行恢复的基本流程是:

1.      确定recoveryTargetTLI

即要恢复到的那个时间线

2.      确定时间线集合expectedTLIs

3.      Redo

根据expectedTLIs,确定正确的WAL文件

4.      Redo结束,确定新的时间线

 

下面分别介绍这几部中在PG中是如何实现的。

1.3    实现

1.3.1 时间线的表示

使用TimeLineID表示一个时间线,实际上就是一个无符号的整型。时间线从1开始,然后依次递增。

1.3.2 产生新的时间线

1.      新时间线产生的时机

只有在启动时,从归档中进行恢复,才会产生新的时间线,否则一直沿着原来的时间线走。

2.      History文件

在产生新的时间线时,会创建一个历史文件,叫做history文件:

?  命名规则:

NewTimeLine.history

?  内容:

父亲时间线|分出时的日志文件名|分出的原因

?  作用:

在归档恢复时,如果该归档中包含多个时间线,则可以帮助系统在恢复时找到正确的WAL文件。

?  生命周期:

每个history文件,在创建新的时间线时会被删除,但是其内容则会copy到新的history文件的开头。如下所示:

00000002.history的内容如下:

PG时间线的实现 - zisedeqing - 生命无非记忆 

则00000003.history的内容如下:

PG时间线的实现 - zisedeqing - 生命无非记忆

 

?  归档

History文件在产生会,会“立即”进行归档,所以在归档目录中会存在完整的时间线历史文件的序列。

1.3.3 恢复期间的时间线

在数据库正常运行期间,时间线是不会发生变化的,只有在归档恢复时才会发生时间线的变化,下面说明在恢复期间时间线时如何变化,以及如何使用时间线恢复到正确的位置。

1.3.3.1时间线的确定

恢复期间时间线的选择有如下的几种情况:

1.      从控制文件里面记录的checkpoint记录得到时间线:

recoveryTargetTLI =ControlFile->checkPointCopy.ThisTimeLineID;

2.      从recovery.conf中读取用户配置的时间线

a)        如果用户没有设置时间线,则时间线不变;

b)        如果用户设置的时间线为0,则表示用户期望回复到最新的时间线

确定最新时间线的方法是:

         从recoveryTargetTLI记录的时间线开始,这个扫描history文件,直到找到不存在history文件的那个时间线。

c)        如果用户设置的时间线大于 0 ,则使用该时间线;

确定好恢复时要恢复到的时间线后,我们需求验证该时间线的有效性:

         判断是否存在history文件,如果不存在,则是无效的时间线,系统退出;

         时间线为1的时间线是没有history文件的,因为它没有parent时间线。

1.3.3.2时间线的使用

1.      使用history文件确定expectedTLIs

a)        expectedTLIs是恢复期间可能需要扫描的时间线的集合,它记录的在恢复期间可能的会使用到的WAL文件所在的时间线。

b)        扫描history文件,把history文件中的每个parent时间线添加到expectedTLIs链表头部,最后把recoveryTargetTLI加到链表头部

2.      使用expectedTLIs

a)        WAL日志文件的名字是由TLI+logid+segment组成的,所以必须找到正确的时间线才能选择正确的WAL文件;

b)        找到正确的WAL文件

                        i.             根据recptr,计算logid和segno

                      ii.             从前往后遍历expectedTLIs链表

根据每个时间线,拼成WAL文件名,然后试图打开该文件,如果文件不存在,则继续遍历,直到找到存在的文件

                     iii.             如果没有找到WAL文件,则报错

c)        对于logid和segno相同的WAL文件

                        i.             通过b),找到正确的WAL文件

                      ii.             对于logid和segno相同的WAL文件,其TLI必然不同,我们选择在expectedTLIs链表位置靠前的那个时间线上的WAL文件,这样做的原因是:

u  恢复必然从某个checkpoint日志开始;

u  而恢复开始的checkpoint日志必然在TLI大的那个WAL文件内,原因是:

l  日志redo完成后,我们是先创建新的时间线,然后在请求做checkpoint。

u  所以checkpoint之后的日志也必然在TLI大的那个WAL文件内。

3.      文件源的选择

a)        默认是从XLOG_FROM_PG_XLOG里面,如果是归档恢复,则在加上XLOG_FROM_ARCHIVE

b)        在选择WAL文件时,先从归档里面找,如果找不到,再从pg_xlog里面找

c)        如果都没有找到,则报错

4.      恢复完成后新时间线的创建

a)        归档恢复后,我们选择创建新的时间线,原因:

                        i.             本次恢复后,产生的日志文件都在新的时间线上,不会覆盖就的时间先上的日志;

                      ii.             如果发现本次恢复不是想要的结果,则可以再次直到恢复的时间线,不会由于日志覆盖该导致恢复失败;

b)        确定新的时间线

                        i.             从recoveryTargetTLI往后找,直到找到不存在history的时间线;

                      ii.             然后对该时间线加1,就是本次恢复后的新的时间线

u  所以,即使我们恢复到之前的时间线,也不会导致时间线不惟一;

u  +1的原因是,不存在history的那个时间先应该是归档恢复之前使用的当前的时间线,所以需要加1;

5.      Redo的结束

a)        在只设置了TLI的情况下,redo完recoveryTargetTLI的日志后,redo操作结束;

结束方式:

         在读取下一条日志时,如果在expectedTLIs内找不到适当的WAL文件,则终止redo

b)        在设置了TLI时,redo的终止点只会比TLI的时间点早,而不会比它晚,原因是redo需要的日志文件必须在expectedTLIs内。



---------------
-rw------- 1 wln wln 16777216 07-12 10:30 000000020000000000000019
-rw------- 1 wln wln 16777216 07-07 15:41 00000002000000000000001A
-rw------- 1 wln wln       41 07-06 08:41 00000002.history
-rw------- 1 wln wln 16777216 07-12 10:31 000000030000000000000019
-rw------- 1 wln wln 16777216 07-12 10:31 00000003000000000000001A
-rw------- 1 wln wln       84 07-12 10:31 00000003.history
-rw------- 1 wln wln 16777216 07-12 12:49 000000040000000000000019
-rw------- 1 wln wln 16777216 07-12 10:39 00000004000000000000001A
-rw------- 1 wln wln      127 07-12 10:38 00000004.history
drwx------ 2 wln wln     4096 07-12 10:38 archive_status
[wln@localhost pg_xlog]$ cat 00000002.history
1       0/602445C       no recovery target specified
[wln@localhost pg_xlog]$ cat 00000003.history
1       0/602445C       no recovery target specified

2       0/19FBD5DC      no recovery target specified
[wln@localhost pg_xlog]$ cat 00000004.history
1       0/602445C       no recovery target specified

2       0/19FBD5DC      no recovery target specified

3       0/19FBD6FC      no recovery target specified



http://mysql.taobao.org/monthly/2015/07/03/
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值