转载:PostgreSQL时间线的实现
来自:
http://zisedeqing.blog.163.com/blog/static/95550871201481115942717/、
1.1基本原理正常情况下,数据库是沿着一条时间线一直延伸的,但是如果中途,用户期望从归档中进行恢复,则这时数据库的时间线就会产生分支,沿着新的时间线延伸。如下图所示: 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的内容如下: 则00000003.history的内容如下: ? 归档 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/(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |