下面主要讲述 PostgreSQL+ repmgr 高可用集群是如何实现switchover,以下是具体场景及其操作步骤。
该命令常见的使用场景为,若没有配置为自动切换,primary 节点宕机后,将手动指定 standby 节点提升为
primary 主服务器节点。
当主服务器发生宕机或者服务不可用,就需要新的备服务器来接管故障的主服务器,以确保整个 repmgr 集群对外
可用,这时可以通过 repmgr standby promote
来完成。
1、查看正常情况下集群状态
[postgres@node3 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Priority | Timeline | Connection string
----+-------+---------+-----------+----------+-----------+----------+----------+--------------------------------------------------------
1 | node1 | primary | * running | | location1 | 100 | 1 | host=node1 user=repmgr dbname=repmgr connect_timeout=2
2 | node2 | standby | running | node1 | location1 | 100 | 1 | host=node2 user=repmgr dbname=repmgr connect_timeout=2
3 | node3 | standby | running | node1 | location1 | 100 | 1 | host=node3 user=repmgr dbname=repmgr connect_timeout=2
4 | node4 | witness | * running | node1 | location1 | 0 | n/a | host=node4 user=repmgr dbname=repmgr connect_timeout=2
2、手动关闭primary节点,模拟primary故障宕机
模拟主库宕机,停止主库数据库服务。
[postgres@node1 ~]$ pg_ctl -D /data/pgsql12/data/ -o '-c config_file=/data/pgsql12/data/postgresql.conf' -l /data/pgsql12/logs/start.log stop
此时,复制群集将处于部分禁用状态,两个备用数据库都将尝试连接到已停止的主数据库时接受只读连接。请
注意,repmgr元数据表尚未更新,执行 repmgr cluster show
时请注意差异。
[postgres@node3 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf cluster show
3、手动在需要提升为primary节点的standby节点提升为primary节点
1)、查看当前集群信息,可以看到旧 primary 节点已经处于不可达的状态。
[postgres@node3 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf cluster show
2)、手动提升 standby(node2) 节点为 primary 节点。
[postgres@node2 ~]$ repmgr -f data/repmgr/conf/repmgr.conf standby promote
3)、查看当前集群状态,可以看到 standby 节点已经被提升为新的 primary。
[postgres@node3 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf cluster show
1、集群中其它 standby 节点默认还是连接在已经宕机的旧 primary 节点,需要我们手动将这些 standby 节点指
向新的 primary 节点。
[postgres@node3 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf standby follow
2、查看集群状态信息,可以发现,目前 standby 节点已经指向新的 primary 节点。
[postgres@node3 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf cluster show
当 primary 节点宕机后,后续业务稳定,我们是需要将宕机的 primary 主服务器节点重新加入集群并作为
standby 备用服务器节点进行服务。
1、清理宕机节点数据目录
[postgres@node1 ~]$ rm -rf /data/pgsql12/data/*
2、重新通过 repmgr 克隆备服务器 standby 节点
# 192.168.64.171为node2,也就是新的primary
[postgres@node1 ~]$ repmgr -h 192.168.64.171 -U repmgr -d repmgr -f /data/repmgr/conf/repmgr.conf standby clone
3、启动数据库
[postgres@node1 ~]$ pg_ctl -D /data/pgsql12/data/ -o '-c config_file=/data/pgsql12/data/postgresql.conf' -l /data/pgsql12/logs/start.log start
4、将宕机恢复后的旧 primary 节点以 standby 的身份重新加入集群
[postgres@node1 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf standby register --force
这里也可以通过下面的命令直接来重新加入原主服务到新集群:
[postgres@node1 ~]$ repmgr node rejoin -f /data/repmgr/conf/repmgr.conf -h 192.168.64.171 -U repmgr -d repmgr --force-rewind
1、查看 switchover 前的集群状态信息
[postgres@node3 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf cluster show
2、手动在需要提升为 primary 节点服务器上执行 switchover 命令
[postgres@node3 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf standby switchover
3、手动将其他 standby 节点指向新的 primary 节点
[postgres@node1 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf standby follow
[postgres@node2 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf standby follow
4、查看 switchover 变更后的集群信息
[postgres@node3 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf cluster show
当主服务器节点不可用时,repmgr 可将备用服务器自动提升为主服务器节点的过程称为 failover。
若想要实现高可用集群的自动故障转移,就必须提前安装好 repmgrd 守护程序。
1、failover 测试前集群信息查看
[postgres@node4 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Priority | Timeline | Connection string
----+-------+---------+-----------+----------+-----------+----------+----------+--------------------------------------------------------
1 | node1 | primary | * running | | location1 | 100 | 1 | host=node1 user=repmgr dbname=repmgr connect_timeout=2
2 | node2 | standby | running | node1 | location1 | 100 | 1 | host=node2 user=repmgr dbname=repmgr connect_timeout=2
3 | node3 | standby | running | node1 | location1 | 100 | 1 | host=node3 user=repmgr dbname=repmgr connect_timeout=2
4 | node4 | witness | * running | node1 | location1 | 0 | n/a | host=node4 user=repmgr dbname=repmgr connect_timeout=2
2、手动关闭 primary 节点,模拟故障宕机
[postgres@node1 ~]$ pg_ctl -D /data/pgsql12/data/ -o '-c config_file=/data/pgsql12/data/postgresql.conf' -l /data/pgsql12/logs/start.log stop
3、通过见证服务器查看集群信息变化
# 旧primary节点不可达,后续会根据配置文件设置重复几次重试连接primary节点,确认primary节点是否真正的无法使用
# node1: Role ==> primary | Status => ? unreachable
[postgres@node4 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf cluster show
# 当见证服务器确认旧primary节点不可达后,根据一定的规则选择standby节点并提升为新的primary节点
# node1: Role ==> primary | Status => ? unreachable
# node2: Role ==> standby | Status => ! running as primary
[postgres@node4 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf cluster show
# 提升新的primary节点完成后,旧的primary节点被至为failed
# node1: Role ==> primary | Status => - failed
# node2: Role ==> primary | Status => * running
[postgres@node4 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf cluster show
4、手动将集群内其它 standby 节点指向新的 primary 节点
该步骤存疑,理论上故障转移过程中也会自动将该步骤的功能包含实现。
[postgres@node3 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf standby follow
[postgres@node4 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf cluster show
5、重新将旧的 primary 节点以 standby 的身份加入到集群中
[postgres@node1 ~]$ repmgr node rejoin -f /data/repmgr/conf/repmgr.conf -h 192.168.64.171 -U repmgr -d repmgr --force-rewind
[postgres@node4 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf cluster show
问题原因:repmgr 出现切换后,原主库停止服务。手动启动原主库会导致数据库集群状态异常,变为双主。
解决方案:原主库 (node1) 查询集群状态,发现备库1 (node2) 已经成为新的主库,但是原主库 (node1) 仍然以主
库的模式启动,这时候集群就出现了双主的问题。检查后发现,备库2 (node3) 已经连接到了新主库 (node2),此
时可将原主库 (node1) 重新加入集群作为备库运行。
报错信息:
[postgres@node4 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Priority | Timeline | Connection string
----+-------+---------+-----------+----------+-----------+----------+----------+--------------------------------------------------------
1 | node1 | primary | * running | | location1 | 100 | 1 | host=node1 user=repmgr dbname=repmgr connect_timeout=2
2 | node2 | standby | ! running as primary | node1 | location1 | 100 | 1 | host=node2 user=repmgr dbname=repmgr connect_timeout=2
3 | node3 | standby | running | node1 | location1 | 100 | 1 | host=node3 user=repmgr dbname=repmgr connect_timeout=2
4 | node4 | witness | * running | node1 | location1 | 0 | n/a | host=node4 user=repmgr dbname=repmgr connect_timeout=2
WARNING: following issues were detected
- node "192.168.64.171" (ID: 2) is registered as standby but running as primary
node1 停止集群:
[postgres@node1 ~]$ pg_ctl -D /data/pgsql12/data/ -o '-c config_file=/data/pgsql12/data/postgresql.conf' -l /data/pgsql12/logs/start.log stop
测试是否可以将本节点重新加入集群:
[postgres@node1 ~]$ repmgr node rejoin -f /data/repmgr/conf/repmgr.conf -h 192.168.64.171 -U repmgr -d repmgr --force-rewind --config-files=/data/pgsql12/data/postgresql.conf --verbose --dry-run
正式将节点重新加入集群:
[postgres@node1 ~]$ repmgr node rejoin -f /data/repmgr/conf/repmgr.conf -h 192.168.64.171 -U repmgr -d repmgr --force-rewind --config-files=/data/pgsql12/data/postgresql.conf --verbose
重新查询集群状态,集群状态正常:
[postgres@node4 ~]$ repmgr -f /data/repmgr/conf/repmgr.conf cluster show
ID | Name | Role | Status | Upstream | Location | Priority | Timeline | Connection string
----+-------+---------+-----------+----------+-----------+----------+----------+--------------------------------------------------------
1 | node1 | standby | running | node1 | location1 | 100 | 1 | host=node1 user=repmgr dbname=repmgr connect_timeout=2
2 | node2 | primary | * running | | location1 | 100 | 1 | host=node2 user=repmgr dbname=repmgr connect_timeout=2
3 | node3 | standby | running | node1 | location1 | 100 | 1 | host=node3 user=repmgr dbname=repmgr connect_timeout=2
4 | node4 | witness | * running | node1 | location1 | 0 | n/a | host=node4 user=repmgr dbname=repmgr connect_timeout=2