Postgresql的灾备管理(二)一主一备——几个软件的缝合怪

前文所述,我抛弃了repmgr改用pgpool,就是看重了其丰富的灾备功能,很不幸的是,符合要求的snapshot模式宕机了,而且是官方修不好的那种,无奈放弃。 剩下的选项就是patroni. 又仔细研究了patroni的说明,对于备故障是有改同步复制为异步复制的功能,然而必须依赖etcd或者consul等分布式多活检测器,必须部署3台以上,而且主服务器身份的漂移只能通过HAproxy来实现,等于一个灾备程序需要再搭用2个其他程序,还要多加一台备用服务器,一点都不简单。

所幸的是,pgpool官方给了很多的bash脚本,以此为基础,我可以通过对repmgr的修补,来补全灾备功能,实现前述的2台机器条件下的乘法原理。以下是对repmgr功能缺陷的补全方案:

1)备服务器故障造成同步的主服务器无法接受写操作——更换postgresql相关的配置,将同步复制改成异步复制,使用reload进行不停机切换。但是当备服务器恢复了,重新加入进来后,也应该相应的恢复为同步复制。

2)备服务器切换为主服务器,应用程序无法得知——使用firewalld对写程序的接口进行端口转发的反向代理。在这种事件发生后试图在两台机器上进行切换,当然旧主服务器的机器可能根本无法接通,在恢复后应该先去备服务器进行检查,并同步最新的反向代理流向。用pgpool中学会的postgres账号互通进行切换,通过特殊的sudo设置和执行bash脚本去更改在firewalld的反向代理设置。读程序则在本机直接连,无需特意更改。

这里使用firewalld的端口转发(NAT)功能而不是虚拟IP来实现主服务器身份的漂移,不仅仅是因为大部分的云服务设置虚拟IP都非常麻烦,而且更重要的是两台数据库服务器为了实现最大限度的不相关性,已经分属于2个可用区的2个子网,虚拟IP策略根本无法跨网段,是无效的。又不想用HAProxy,就直接用Linux自带的底层NAT来实现反向代理了。

3)主服务器必须记录自己是否在solo状态。记录和解除都在故障切换时实现。则恢复后启动先检查自己是否在solo状态,如果是则直接作为主启动,并且试图通知另一台当备。如果不是则先检查另一台是否已经启动了,如果启动主动当备,如果还未启动则挂机等待另一台给信号,自己再去当备。

以上的实现依赖于repmgr的event_notification_command等接口,它们可以将当前发生的事件和具体细节传输给自定义的脚本来具体处理。当然开机启动也必须编写相应的脚本,来实现对repmgr启动的控制,避免主备身份出错。