POSTGRESQL PG_REWIND 从源代码看功能

2021-07-10 00:00:00 数据 数据库 文件 复制 目的


PG_REWIND 是PG 9.6 开始提供的功能,主要的作用在于通过PG_REWIND 让PG 复制中的数据库快速的与预定的“主库”进行数据同步,而复制的方式是是文件块的方式,并且可以避过重复的数据块。所以复制的速度是快的,在不少的高可用方式中都被作为主库失败后的快速的将主库加入原有集群并作为从库继续工作的方案。



从PG_ REWIND 的源代码就中的可以看到引用了 pg_control.h,  controldata_utils.h 等文件。那我们就从这里说起。


首先PG 的复制初始时基于文件复制的方式进行的, system identifier是系统在 initdb 初始化时生成的,此后这个system identifier 是不会被改变的,也就是说,pg_rewind 如果想进行数据的复制,则前提的条件是这两个PG的数据库的 system identifier  是要一致的,否则PG_REWIND 是无法进行工作的。

我们通过上面的源代码可以证实,PG_REWIND 进行数据的复制的基础的确是要判断,源和目的的的 system_identified 一定是要一致的。同时还要判断两个数据库服务器的数据库版本和系统文件的版本。这也就坐实了,如果你的数据库的版本不一致那也是无法使用PG_REWIND


总结1 :通过源代码PG_REWIND的基础是, 两个数据库服务器的 SI 必须一致,同时数据库的版本必须一致。


在两个数据库确认之间早就已经是有关系的基础上, 那么在执行命令的时候,就需要保证目标库的状态应该是确认被关闭的。从上面的源代码看从命令行中给出的目标的数据库的状态,并确认是关闭的。



总结2:  在PG_REWIND 工作中,需要判断目标库的状态应是关闭的。

在做完这些工作后,就需要判断目的与源数据库中checkpoint的 timeline ,如果两个服务器一致,说明根本没有必要使用PG_REWIND 来进行工作,如果不是则需要,进行下面的工作。


上面的代码需要获得目的机器在启动后需要到的 小的recovery 的位置,并且将这些位置与目标机器中的位置进行对比,如果源的位置大于目标库的位置,则说明需要进行数据的复制,如果否,pg_rewind 就不需要了。


如果需要进行pg_rewind的情况下, 收集目的与源数据库之间文件信息,通过hash 的方式来判断文件之间是否有差异。

下面的代码是一个调用数据复制的代码, 其中在获得有多少需要进行数据复制的文件后,开始循环进行数据复制,通过hash table 中记录的数据文件进行one by one 的 数据复制


这里还有一个细节,在对比控制文件的时候,需要将内存中的存储信息,刷新到磁盘的文件中。



下面总结pg_rewind整体的工作过程


1  对源于目的主机的状态进行判断,符合要求则进行工作

2  通过控制文件来判断源与目的主机的是否曾经是复制的关系

3  通过在源与目的之间的checkpoint 来判断两个节点之间的数据的异同

    在checkpoint 点中后一次相同的点后的数据为要复制的数据

4  通过HASH TABLE将数据文件不同的进行复制,相同的不会复制

5  在目的机上建立backup label 文件,准备在目的机启动后,开始进入recovery 的状态,进行数据的recovery应用pg_wal文件

6  从库开机进行数据的追偿,达到与源库一致的状态

7  建立数据复制,功能完成



这里需要注意的是,


1  full_page_writes 需要打开

2  wal_log_hints  需要打开

3  保证PG control 文件正常没有被损坏




相关文章