Postgresql的灾备管理(一)逻辑和工具
灾备到底要干什么
这是最简单的一主一备双机灾备部署。发生故障有三种可能,1号故障,2号故障和两者同时故障。
两者同时故障先不予考虑。
如上所示,假设初始状态是1号服务器为主,2号服务器为备,故障的发生基本有两种可能,1号故障或者2号故障。虽然大部分的灾备软件着重处理主服务器故障情景,我们先谈2号故障的情景。
备用机故障和恢复处理
如果2号发生故障,主服务器1号会不会受影响呢?在一种情况下会,就是同步标准状态下,即主服务器1号要记录任何数据库的增删改或曰写操作,必须要备服务器也记录,且备服务器只有2号一台。
既然现在所有的备服务器,即2号服务器都发生了故障,则主服务器就拒绝进行任何写操作了,因为它一旦故障,恢复的2号服务器无法复制从2号服务器故障到1号服务器故障之间的1号服务器所记录的增删改。
以往的主备要么需要至少两台备服务器,要么此时就彻底放弃主服务器的写功能了。瀚高提出来若要高可用,此时1号服务器应该把同步改为异步,即服务降级,不要求备服务器也记录,这样若备服务器恢复了,赶紧把宕机期间1号服务器发生的新记录同步过来即可。
所以这就是备服务器的脱钩和再挂钩管理。脱钩管理是主服务器对其脱钩,再挂钩管理是等其恢复后,其自身保证了数据已经和主服务器同步之后,再恢复主服务器对其同步的操作。
主力机故障和恢复处理
讲清了备服务器的操作,再讲主服务器如果故障该如何。除了备服务器自己主动提升为主服务器,和主服务器恢复之后甘愿降级作备之外,其余操作与备服务器脱钩和再挂钩并无本质区别。
很多软件只考虑了右边的情景,但是忽略了左边的情景,其实二者互为镜像,都是在只有一台服务器的情景下依然保持服务,从而降低了综合故障率。即必须二者同时故障,服务器才停止工作。如果不考虑备服务器的脱钩和再挂钩,则只要备服务器故障,系统就不能正常工作。
主备角色互换的注册问题
除此之外,还有一件非常重要的事,就是通知主备切换。Postgresql可以做到自己主备切换,但是其服务的应用程序如何知道主备角色换了?比较复杂的思路是用动态IP,哪个为主就哪个绑定特定的IP。但是此法在云环境可能实现不了,因为云路由可能不支持或者开通要额外收费。
所以前置的反向代理对通知主备切换十分重要。即应用程序自己去找反向代理时,会以为它就是Postgresql数据库,而反向代理自己知道真正的Postgresql哪个是主,哪个是备,从而在执行写操作时,只会去找主服务器。
工具选择
因此,所谓的『轻量级』repmgr基本上就是不可用的,因为它即使让Postgresql自己知道主备身份,但是并不能让应用程序适应这身份转换,那么主备切换就需要写额外的通知脚本,让应用程序去更改主备注册。即使加入了单纯的反向代理pg-bouncer,也必须手写这一步。
在这里多说一步,很多开源软件喜欢标榜自己『轻量级』,其实『轻量级』就是『未完工』和『功能缺陷』的营销说法(坏事好说)。虽然学起来简单,但是遇到实际问题就真的崩溃。一个成熟的程序员应该尽量规避那些宣传自己『轻量级』的软件、语言和框架。
合理的解决方案,只剩下了瀚高的收费软件,和pgpool-II.
两台主机同时故障的问题
降低同时故障概率
首先,刚才的设置保证了仅有一台主机故障时,整个数据库依然对外可用,则整体失败概率就是两台同时坏的概率,如果两台主机各自故障为独立事件,则总体故障的概率为各自故障的概率乘积。
现实情况中,两台主机各自故障并不一定独立,例如两台主机若在云上为同一台物理服务器虚拟出来的两份云主机,那很有可能在该物理服务器死机时,两台主机同时故障。
那么在部署的时候,就要求两台主机至少部署在不同区的主机上,最好是不同地域。这样才能最大限度的让两台的故障事件各自独立。在各自独立的前提下,两台主机同时故障的概率为各自故障概率的乘积,即一台主机的可用性若为99.9%,故障概率为0.001,两台同时故障的概率就为0.000001,两台的综合可用性为99.9999%,这样就从3个9的可用性一跃到6个9的可用性。
由上,两台Postgresql服务器的云主机有可能所处的网段都不一样,就不要谈绑定动态IP了。
分析故障和恢复场景
接下来再讲这种情景发生该如何处理。这种情景的发生场景,无非是主力机故障之后备用机故障,备用机故障之后主力机故障,以及二者恰巧同时故障。二者恰巧同时故障,则任何灾备程序都不会反应,故略过。在第二台主机故障时,它是无能为力的。
现在的问题在于,恢复时会发生什么,有四种场景:
1)主力机1故障——备用机2故障——主力机1恢复——备用机2恢复
2)主力机1故障——备用机2故障——备用机2恢复——主力机1恢复
3)备用机2故障——主力机1故障——备用机2恢复——主力机1恢复
4)备用机2故障——主力机1故障——主力机1恢复——备用机2恢复
1)主力机故障以后,备用机会自封为主力机,等待主力机恢复后让其降格为备用机。但是备用机还没等到主力机恢复,自己先故障了。主力机醒来不知道自己应该降格,则自己开始当主力机。备用机也醒了,发现自己好不容易当的主力又被老主力给夺回去了,怎么办?谁是主力?这就是经典的『脑裂问题』。通常的解决方案是增加一台『见证』主机。但是这也解决不了『见证』主机自己恰好同时崩溃,没看清谁该当主力的问题,或者是『见证』主机『智能』分析一下谁的数据库更新得更靠后?好像也解决不了问题。
2)这种情况和经典的备换主一致,虽然2号机宕机期间会服务中断,但是主备身份不发生冲突。
3)备用机恢复之时,是否会自封为主力机?如果是,则出现了和1)类似的『脑裂问题』。
4)此种情况和备用机故障再恢复类似,只是多了之间主力机故障的时间。
由上可见,问题的核心在于某台主机恢复后,面对集群内另一台主机在故障状态时,自己自封为主。如果某主机恢复后发现只有自己一台可用,偏偏要自封为主的逻辑不存在——即这时宁愿停止服务,等另一台恢复之后作为其备用机,则『脑裂问题』或『争霸问题』就不会出现。
一点感悟
胡适说过『多研究些问题,少谈些主义』。现在开源软件风起云涌,每个都标榜自己有独特的『概念』。我们作为实际应用开源软件的工作者,还是要从实际问题出发,避免被这些『概念』、『理念』或『主义』所迷惑。在动手之前,先动脑把应用场景推演一遍,少走弯路。