查看node状态_倾情打造PostgreSQL高可用系列(三):理解PAF中的故障转移状态机(上)…

  • Post author:
  • Post category:其他


前言

ef1953d727e132c4829c3c71ee281dc5.png

前面我们介绍了

pg_auto_failover

的安装,和客户端如何配置failover。今天我们来学习一下pg_auto_failover的状态机。

pg_auto_failover日志在哪里看

配置Monitor、Primary Node、Secondary Node的时候,输出的日志可以打在终端上。可是后面想找日志居然找不到了。这倒是让我们很意外的。研究了一番,发现日志其实输出在

/var/log/message

里面,如果系统错误比较多,这可不方便我们看。不过我们做成了systemd服务之后,可以使用

journalctl

命令来查看。

使用

journalctl -u 服务名

可以显示日志。以下是Monitor节点最新日志的输出。

5acdfb1694e075f34acf4c30da95bee4.png

Monitor也叫状态机是个什么原理

Monitor也叫状态机是pg_auto_failover的核心机制。最简单的理解就是通晓各个节点当下的状态。首先各个节点的守护进程会发送事件给状态机,状态机根据发送过来的事件信息,为每个节点分配当前状态和目标状态。节点的当前状态是其功能的有力保证。而目标状态是告诉我们将要尝试的转换。

所以状态机很重要,它只有才全面了解了当前集群的状态。才会在出问题的时候做出决策。

但是问题来了,它是个单节点运行的。如果出现单点故障会怎么样?

我们来模拟一下,下面是状态机上显示的集群状态。

[postgres@paf1 ~]$ pg_autoctl show state
  Name |  Node |  Host:Port |       LSN | Reachable |       Current State |      Assigned State
-------+-------+------------+-----------+-----------+---------------------+--------------------
node_1 |     1 |  paf2:5432 | 0/321CFB8 |       yes |             primary |             primary
node_2 |     3 |  paf3:5432 | 0/321CFB8 |       yes |           secondary |           secondary

我们直接将状态机shutdown,进行硬件维护。

当状态机关闭后,在Primary Node节点执行查看集群状态,就会显示无法连接到状态机。

[postgres@paf2 ~]$ pg_autoctl show state
02:22:51 10678 WARN  Failed to connect to "postgres://autoctl_node@paf1:5432/pg_auto_failover?sslmode=require", retrying until the server is ready
02:22:51 10678 ERROR Connection to database failed: timeout expired
02:22:51 10678 ERROR Failed to connect to "postgres://autoctl_node@paf1:5432/pg_auto_failover?sslmode=require" after 1 attempts in 2 seconds, pg_autoctl stops retrying now
02:22:51 10678 ERROR Failed to retrieve current state from the monitor

通过

journalctl

命令查看Primary Node的日志,大量报无法连接Monitor的错误。

cdddfac2f5fc19fa93321436d727b0b8.png

此时主库和备库仍然可以连,并且集群状态无异常

[postgres@paf2 ~]$ psql -h 192.168.56.94
psql (13.1)
SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, bits: 256, compression: off)
Type "help" for help.

postgres=# x 
Expanded display is on.
postgres=# select usename,application_name,client_addr,backend_start,state,sync_state from pg_stat_replication ;
-[ RECORD 1 ]----+------------------------------
usename          | pgautofailover_replicator
application_name | pgautofailover_standby_3
client_addr      | 192.168.56.95
backend_start    | 2020-12-17 01:13:38.252427+00
state            | streaming
sync_state       | sync


[postgres@paf2 ~]$ psql -h 192.168.56.95
postgres=# x 
Expanded display is on.
postgres=# select status,receive_start_lsn,written_lsn,flushed_lsn,latest_end_lsn,slot_name from pg_stat_wal_receiver;
-[ RECORD 1 ]-----+-------------------------
status            | streaming
receive_start_lsn | 0/3000000
written_lsn       | 0/321CFB8
flushed_lsn       | 0/321CFB8
latest_end_lsn    | 0/321CFB8
slot_name         | pgautofailover_standby_3

可以发现状态机挂了对集群使用完全没有一丁点影响。但是此时如果集群里面的机器在挂一台,是没有办法自动进行故障转移的,因为我们失去了状态机。

状态机的转换示例

这段是官方文档的例子,描述了一个集群从诞生到高可用性的过渡的各种状态。

1.首先假定我们的状态机已经部署。

2.

Primary Node

运行初始化后,节点上的监控进程将当前状态注册为

init

,目标状态注册为

single



init

代表着状态机除了知道节点存在,对节点其他情况一无所知,因为监控进程还没有连续的报告节点的运行状态。

Name |  Node |  Host:Port | LSN | Reachable |       Current State |      Assigned State
-------+-------+------------+-----+-----------+---------------------+--------------------
node_4 |     4 |  paf2:5432 | 0/0 |   unknown |                init |              single

3.当

Primary Node

上的守护进程持续向状态机报告运行状态后,Monitor会将当前状态分设置为

single

。这也就是说状态机认为这是一个单机,单机是没有故障转移的。此时集群中还没有其他节点,Monitor将的

Primary Node

目标状态也分配为

single

.

Name |  Node |  Host:Port |       LSN | Reachable |       Current State |      Assigned State
-------+-------+------------+-----------+-----------+---------------------+--------------------
node_4 |     4 |  paf2:5432 | 0/1613300 |   unknown |              single |              single

4.当开始初始化

Secondary Node

,Monitor就会将

Primary Node

的目标状态分配为

wait_primary

,此时在等待

Secondary Node

进行同步。为了完成从

single



wait_primary

的转换,

Primary Node

会将

Secondary Node

节点的主机名和IP添加到pg_hba.conf中允许连接。

Secondary Node

此时会转换为

wait_standby

,其目标状态也是

wait_standby

。需要等到

Primary Node

授予其连接权限。

Name |  Node |  Host:Port |       LSN | Reachable |       Current State |      Assigned State
-------+-------+------------+-----------+-----------+---------------------+--------------------
node_4 |     4 |  paf2:5432 | 0/1613338 |       yes |              single |        wait_primary
node_5 |     5 |  paf3:5432 |       0/0 |   unknown |        wait_standby |        wait_standby

5.一旦连接权限授予后,监控器将

Secondary Node

的就会将目标分配为

catchingup

,此时从

wait_standby



catchingup

的过程中将会运行pg_basebackup,编辑recovery.conf以及在

热备

节点中重新启动PostgreSQL。

Name |  Node |  Host:Port |       LSN | Reachable |       Current State |      Assigned State
-------+-------+------------+-----------+-----------+---------------------+--------------------
node_4 |     4 |  paf2:5432 | 0/2000060 |       yes |        wait_primary |        wait_primary
node_5 |     5 |  paf3:5432 |       0/0 |   unknown |        wait_standby |          catchingup

6.当

Secondary Node

节点处于热备模式,并能够连接

Primary Node

时,

Secondary Node

的目标状态就会变成

secondary



Primary Node

的目标状态也会变成

primary

。Postgres从

Primary Node

传输WAL日志,然后在

Secondary Node

上重做它们。然后

Secondary Node

会向Monitor汇报pg_stat_replication.sync_state和WAL replay lag。

Name |  Node |  Host:Port |       LSN | Reachable |       Current State |      Assigned State
-------+-------+------------+-----------+-----------+---------------------+--------------------
node_4 |     4 |  paf2:5432 | 0/30000D8 |       yes |             primary |             primary
node_5 |     5 |  paf3:5432 | 0/30000D8 |       yes |           secondary |           secondary

状态机的图示

官方提供了一张状态机的图,不过官方说这张图缺少了指向

single

状态的链接。

It’s missing links to the

single

state, which can always been reached when removing all the other nodes.

不是很理解官方这个意思。删除所有其他节点的时候始终都能reached?

0faa40c84072ed1e5ff1654bc2e45973.png

所以我决定来模拟一下删除节点操作。写一个shell循环,在Monitor上执行查看状态。

while true; 
do 
pg_autoctl show state ; 
sleep 1; 
done

当我删除

Secondary Node

的时候。可以看到基本上很快就从

primary

变成了

single

pg_autoctl drop node --pgdata /var/lib/pgsql/13/data/  --destroy

f4c3cee067478f0b8258e9f6f5e30c27.png

总结

我的理解其实状态机就是监控收集集群中各个节点的状态,并根据预设好的决策系统对各种状态进行控制,例如,如果主库现在down机了,状态机无法接收到主库的信息,就会执行决策,采取故障转移的策略。

而我们需要做的事情就是了解各种状态。下一回我们会详细介绍这些状态。这样有利于我们对集群出现问题后好做一个把控。



版权声明:本文为weixin_26776943原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。