注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

生命无非记忆

不要在记忆中丢失了自己

 
 
 

日志

 
 

PostgreSQL时间线的实现  

2014-09-11 14:01:39|  分类: postgreSQL[原创] |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

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,计算logidsegno

                       ii.              从前往后遍历expectedTLIs链表

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

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

c)         对于logidsegno相同的WAL文件

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

                       ii.              对于logidsegno相同的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的情况下,redorecoveryTargetTLI的日志后,redo操作结束;

结束方式:

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

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

  评论这张
 
阅读(667)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016