集群故障后如何恢复原主机
pg的高可用架构中,主库挂掉后,备库会自动升级为主库继续提供服务,对于原来的主库通常有两种处理方式
- 删掉,重搭新备库。
- 降级为备库,继续服务。
很显然,相比来说第一种不是个很好的方案,而且当数据量比较大时,重搭备库的时间成本太高。
但是因为老的主库挂掉的原因多种多样,甚至有可能是高可用系统的误判,而老主库也有可能是在挂掉之后又重新作为主库启动起来,这个时候降级并重搭流复制关系的操作就有可能失败(新的备库比新主库数据更超前)。
为了解决这种情况,PostgreSQL 引入了pg_rewind工具。
pg_rewind
pg_rewind 工具主要实现了从源集群到目的集群的文件级别数据同步。但是和rsync的区别是,pg_rewind 不需要去读那些未变化的文件块,当数据量比较大而变化较小的时候,pg_rewind会更快。
先看下官方介绍:
pg_rewind是一个工具,用于在群集的时间线发生分歧之后,将PostgreSQL群集与同一群集的另一个副本进行同步。典型的方案是在故障转移后将旧的主服务器恢复联机,作为新主服务器之后的备用服务器。
优势是啥?
pg_rewind 工具主要实现了从源集群到目的集群的文件级别数据同步,pg_rewind 不需要去读那些未变化的文件块,当数据量比较大而变化较小的时候,pg_rewind会更快。
pg_rewind为了能够支持文件级别的数据同步,postgresql.conf必须配置如下参数
wal_log_hints=on
full_page_writes=on
具体实现
为了在PostgreSQL 中实现文件级别同步数据的功能,pg_rewind 主要进行了如下的处理步骤:
-
在目的集群中找到源集群和目的集群的分叉点之前的最近一次checkpoint 点。这样相当于找到了在两个副本数据产生不同前的最后一个一致性位点。目的集群在这个位点之后所有的表数据变化都记录在这个位点之后的WAL 日志中。
-
pg_rewind 会将目的集群这些变化的数据页从源集群复制过来。这里会有2种方式:
-
使用文件系统方式拷贝
-
使用 libpq 建立连接的方式拷贝
总结来讲:pg_rewind 可以快速找到两个集群数据开始分叉的点,然后找到目的集群从该点之后的数据变化,通过拷贝源集群的对应数据页,再通过应用源集群的WAL 日志达到数据一致。