Postgresql PG_REWIND 怎么就这样不行

原创
2019/12/04 06:00
阅读数 164

PostgreSQL 在操作的过程中,如果利用物理复制的过程中,另一台从库,或者主库由于某些原因,不再与主库同步,或者主库crash 起不来了,怎么办,如果在利用现在的主库或备库,弄出一个 twins 。 


其实PG 早就想到这个问题了,PG有一个独特的命令 pg_rewind 可以帮助你,再造一个你。

我们看看pg_rewind能帮我们什么


pg_rewind 的工作原理有点类似rsync,它可以无缝的读取源目录与目的目录之间不同的数据块,而重复的数据块将不再被读取。这样的方式其实对于上面的问题是一个好的解决方案,因为如果主从复制,任何一方坏了,使用PG_REWIND 可以快速将你认为的数据完全的一方的数据同步到另一方,而不用做全量复制,这样最大的好处就是节省了时间。


当然如果大概率知道checksum的(包括MYSQL的binlog checksum )大多可以想到,怎么知道这两边的数据是否一致,必须的校验块,postgresql 如果要使用pg_rewind 功能需要你做以下的一些设置


1  full_page_writes = on

2  wal_log_hints = on

3   hot_standby = on

4  如果你在初始化数据库集群(postgresql 单机也叫数据库集群,别和真正的集群的含义搞混)做了data checksum 也是可以的。  




其主要的工作原理,在目的集群中对比源,与目的端之间的不同点,就是什么时候两个服务器之间的数据开始不同步的。通过知道这些不同点开始进行

1  使用文件系统的方式进行拷贝

2 使用libpq 建立连接的方式将数据进行拷贝


在拷贝数据文件的以外还需要拷贝事务提交的文件,pg_xact 以及配置文件等等。生成backup label 文件,并且指定开始要恢复的 wal 日志点,并应用恢复点以后的日志,并且还要刷新 pg_control 文件(在设置了检查点并刷新日志之后,检查点的位置将保存在文件pg_control中),最后执行initdb -S 将数据刷入到磁盘后,关闭。


问题1 ,PG_REWIND 怎么识别两台PG 是曾经为primary 和 standby的管理

其实就是通过 database system identifier 来鉴别,同样的主从的 database system identifier 的编码是一致的。同时也要看version 与 catalog version number 是否一致。



而关于bakcup label 其中包含了check point ,而后续的复制也是要依靠这个check point 点 目的集群就可以不断应用源集群从CHECKPOINT LOCATION 之后的WAL 日志。


当然其中的原理不光如此,下面就开始做一个实验看看pg_rewind的强大的功能。


首先下面有两台PG , 192.168.198.120 主库  192.168.198.176 从库

通过pg_basebackup 进行数据同步后,在 192.168.198.120 上在进行相关的一些建库,曾表,插入数据的事情,看看PG_REWIND 是否可以进行相关的数据同步

pg_basebackup 命令就不在讲了,默认大家都会了,不会的可以百度,或者看我之前的关于这方面的东西。


1 下面的两个服务器的数据已经是一致的,通过pg_basebackup 进行的复制


2  对176 进行promote 操作,模拟主库失效,从库接替主库,此时主库和从库之间不再有任何关系 (需要修改176 的 postgresql 的监听地址,这点是基础就不再提了)


4  我们在176上进行创建一个pg_rewind库的操作,此时 两个库已经数据不一致了

最后在120 上执行 

 pg_rewind --target-pgdata=/pgdata/data  --source-server='host=192.168.198.176 port=5432 user=repl dbname=postgres password=repl' -P --debug



将数据追齐后,修改120 的配置文件,模拟失效的主库和已经提升为主库的“从库” 数据已经一致了


到这里本来就完事了,但实际上有些评论说pg_rewind 是可以做数据同步的,我是比较感兴趣的,到底 pg_rewind 可不可以做数据同步。

首先我们要确认几点,在达到共识的基础上才能继续下面的工作


1 即使是数据同步,也必须是在之前两个节点之间的关系是主从关系,或者至少是有关系,如果两个节点之间没有任何关系,则这个工作是没有办法做的。


2 数据同步是否需要 promote 操作作为前提,或者直接去修改 recovery.conf 文件


测试1 :


进行数据同步,然后将从库关闭,将recover.conf 变为 recover.done,然后重启动从库,在关闭,变更主库的数据,使用pg_rewind进行数据同步


结果失败,通过失败可以证明,如果主从失败后,想直接通过提升当前从库的方法,在通过 pg_rewind 进行数据同步的想法可以凉快去了



测试2  同步长时间的主库已经和原来的从库(从库已经提升为主库)的数据是否可行,这里的长时间其实也是看数据量,下面的情况就是报找不到pg_wal  文件,这边可以尝试从原来的从库上拷贝缺少的pg_wal 或者开启 archive 等方式保证你的pg_wal 是充足的。



图中源主库报没有00000004000000000000003F 文件,找到原来的从库,现在的主库将这个文件拷贝到原来的主库,则pg_rewind 正常工作。


 所以相关的pg_wal 文件也要留存好,最好是有archive 来做数据恢复的后盾。




总结,某些帖子中假想的想通过pg_rewind 来进行数据库之间的复制的想法是不可以的,同时pg_wal 中的日志数据应该进行archive 以防止出现找不到pg_wal 的问题。



本文分享自微信公众号 - AustinDatabases(AustinDatabases)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部