PostgreSQL HA集群高可用方案介绍 & pgpool-II+PostgreSQL HA方案部署

一、PostgreSQL HA集群高可用方案介绍
二、pgpool-II+PostgreSQL HA方案部署
三、pgpool-II常用命令


一、PostgreSQL HA集群高可用方案介绍

介绍PostgreSQL的集群高可用方案前,先了解一下几个概念

单主复制
单一主复制意味着仅允许在单个节点上修改数据,并将这些修改复制到一个或多个节点。只能在主节点上进行数据更新和插入。在这种情况下,应用程序需要将流量路由到主服务器,这会增加应用程序的复杂性。因为只有一个主节点负责写入数据,所以没有冲突的机会。在大多数情况下,单主复制对于应用程序来说就足够了,因为配置和管理起来并不那么复杂。但在某些情况下,单主复制是不够的,您需要多主复制。

多主复制
多主复制意味着有多个节点充当主节点。数据在节点之间复制,并且可以在一组主节点上进行更新和插入。在这种情况下,数据有多个副本。该系统还负责解决并发更改之间发生的任何冲突。有多个主复制有两个主要原因。一个是高可用性,第二个是性能。在大多数情况下,某些节点专用于密集写入操作,而某些节点专用于某些节点或用于故障转移。

多主复制的优缺点
优点:
万一一个主机发生故障,另一个主机仍然能提供更新和插入服务。
主节点位于几个不同的位置,因此所有主节点发生故障的机会非常小。
可以在多台服务器上进行数据更新。
应用程序不需要将流量仅路由到单个主机。

缺点:
多主复制的主要缺点是它的复杂性。
解决冲突非常困难,因为可以同时在多个节点上进行写操作。
有时在发生冲突的情况下需要人工干预。
存在数据不一致的可能性。

PostgreSQL集群高可用方案由多种部署方案:

pgpoll-II:基于SQL的主从复制。支持多主。是一个中间件,基于PostgreSQL的主备热备实现HA。
Slony-I:基于触发器的主从复制。支持层次级连和灾难恢复。简单部署节点:3节点(1主+2从)。
Bucardo:异步多主复制方案,是一个基于触发器的复制解决方案。有对Perl 5,DBI,DBD :: Pg,DBIx :: Safe的依赖。有解决冲突策略。复制经常中断并且出现错误。安装和配置比较复杂。
BDR:Bi-Directional Replication,双向复制。是一个异步多主复制解决方案。基于事务的重播操作方式实现向其他节点的复制。
xDB:EnterpriseDB开发维护的一个双向复制解决方案。
PostgreSQL-XC/XC2:EnterpriseDB和NTT开发的一个同步复制解决方案。没有随PostgreSQL新版本同步维护更新。但不太适合高TPS。
PostgreSQL XL:是PostgreSQL-XC的一个分支,落后于社区 PostgreSQL的版本迭代。没有随PostgreSQL新版本同步维护更新。但不太适合高TPS。
Rubyrep:Arndt Lehmann开发的异步主主复制方案。迭代维护不活跃。可以配置冲突解决方案。
GridSQL:开源,可用于PostgreSQL数据仓库。
DRDB:文件系统级别的复制。

PostgreSQL官方关于 High Availability, Load Balancing, and Replication 的方案介绍参考:https://www.postgresql.org/docs/12/different-replication-solutions.html
Table 26.1. High Availability, Load Balancing, and Replication Feature Matrix


PostgreSQL的Standby从数据库原理:
PostgreSQL在数据目录下的pg_xlog子目录中维护了一个WAL日志文件,该文件用于记录数据库文件的每次改变,这种日志文件机制提供了一种数据库热备份的方案,即:在把数据库使用文件系统的方式备份出来的同时也把相应的WAL日志进行备份,即使备份出来的数据块不一致,也可以重放WAL日志把备份的内容推到一致状态。这也就是基于时间点的备份(Point-in-Time Recovery),简称PITR。
而把WAL日志传送到另一台服务器有两种方式:WAL日志归档(base-file),流复制(streaming replication)。
WAL日志归档(base-file):是写完一个WAL日志后,才把WAL日志文件拷贝到standby数据库中,简言之就是通过cp命令实现远程备份,这样通常备库会落后主库一个WAL日志文件。
流复制(streaming replication):是postgresql9.x之后才提供的新的传递WAL日志的方法,它的好处是只要master库一产生日志,就会马上传递到standby库,同第一种相比有更低的同步延迟,所以我们一般会选择流复制的方式。
注意:实际配置中standby的搭建中最关键的一步就是在standby中生成master的基础备份。postgresql9.1之后提供了一个很方便的工具pg_basebackup来完成。


重点介绍一下pgpool-II:

pgpool-II中间件是一个位于PostgSQLServer & PostgreClient之间的中间件,基于SQL的主从复制。支持多主。同步复制、不会丢数据。从服务仅支持只读查询。由于pgpoll-II是官方的,推荐部署这个方案。

下面重点介绍一下pgpool-II方案的特点:

1.复制:
  pgpoll-II 可以管理多个 PostgreSQL服务器,使用复制功能可以使2个或更多的物理磁盘上创建一个实时备份,这样服务不会因服务器的磁盘故障而中断。
  从功能上复制应该包含replication_mode和master_slave_mode 2种情况:
  replication_mode的实现方式就是分发SQL到多个节点,达到冗余高可用的目的,对SELECT语句可以设置是复制还是只发往其中一个节点。基于SQL分发的复制容易出现主备数据不一致的问题,在有PostgreSQL原生流复制可以用的情况下,HA没必要使用复制模式。
  master_slave_mode=true && master_slave_sub mode='stream' 时,采用的是流复制模式(stream replication),一般推荐采用该模式做HA。

2.负载均衡:
  如果复制生效时,在任何服务器上执行一个 SELECT 查询都会返回相同的结果。pgpoll-II 利用复制的优势来减少每个 PostgreSQL 服务器的负载,因为它可以使用分布在多个服务器之间进行SELECT查询,从而提高系统的整体吞吐量。
  最好是查询和 PostgreSQL 服务器数量成一定比例,大量用户同时执行很多只读查询的场景中负载均衡效果最好。

3.连接池&最大连接数:
  pgpool-II提供了连接池功能。同时pgpool-II还提供了最大连接数处理机制,这个一点和PostgreSQL的最大同时连接数有区别。PostgreSQL最大的同时链接数如果超出时就拒绝链接、失败处理,但pgpool-II超出最大连接数的连接请求可以通过配置设置为排队等待或者立即返回错误。 
  注意:
  1)对高并发业务使用pgpool-II一定要注意,应用端不能有长连接(即不能部署连接池),业务每次使用数据库连接的时间尽可能短、用完请立刻释放;
  2)相关参数的配置规则如下:
    max_pool & num_init_children & max_connections & superuser_reserved_connections 必须满足以下规则:
    不需要取消查询:max_pool * num_init_children     <= (max_connections - superuser_reserved_connections)
    需要取消查询:max_pool * num_init_children * 2 <= (max_connections - superuser_reserved_connections)

4.并行查询: 
并行查询可将数据分割/分配到多台服务器上同时执行,以减少总体执行时间。并行查询在查询大规模数据的时候非常有效。
其实就是sharding,并行查询必须和 replication_mode && 负载均衡同时使用,通过系统表定义sharding表和sharing键,sharing表以外的是复制表。由于并行模式限制比较多,用户一般很少使用。

5.查询缓存:查询缓存可以在 pgpool-II 的所有模式中使用,内部通过memcached实现。

6.HA:提供了HA功能。PostgreSQL在没有中间件的情况下,在Master数据库宕机,需要手工提升Standby为Master,还需要应用主动把连接切换到新Master库上才能保证整个系统能继续对外提供服务。
为了实现能自动切换、增加系统可靠性,可以选择部署pgpoll-II中间件的方案。
pgpoll-II可以检测数据库集群中的Master节点是否存活,在Master节点失效时可以自动提升Standby库,并且pgpoll-II本身可以做高可用部署,搭建多个pgpoll-II,使用VIP在多个pgpoll-II节点上漂移。

pgpool-II的典型应用场景:基于流复制(stream replication)的HA + 读写分离 + 读负载均衡是一个不错的应用场景。


pgpool-II的进程:

1.pgpool:主进程。对所有backend后端进行健康检查,如果有后端PostgreSQL宕机,则发起failover故障迁移。

2.watchdog:看门狗进程。多个pgpool-II之间的通信、配置同步等。
  看门狗进程由 pgpoll-II 自动启动/停止,也就是说,没有单独的命令来启动/停止它。 但是,pgpoll-II 启动时必须拥有管理员权限(root), 因为看门狗进程需要控制虚拟 IP 接口。
  看门狗的配置参数在 pgpool.conf 中配置。 在 pgpool.conf.sample 文件中的 WATCHDOG 小节是配置看门狗的示例。

3.lifecheck & heartbeat receiver & heartbeat sender:watchdog的另外几个进程,健康检查相关,检查上游信任的服务器连接(trusted_servers),检查收到的其它节点的心跳。

4.health check process(0) & health check process(1):健康检查相关的进程。

5.pgpool child:预生成的pgpool子进程,由 num_init_children 参数配置,默认32个。num_init_children 代表了最大并发数,超出的客户端将阻塞等待。每个子进程循环执行下面的任务:
  1)select()检查前端socket;
  2)accept()接收客户端连接;
  3)get_connection()根据客户端连接socket创建前端连接对象;
  4)get_backend_connection():
    a)connect_backend()新建后端连接,一个后端连接对象实际包含了到每个后端的socket。新建的连接需要放到连接池,如果已满先淘汰一个最老的连接对象。连接池的大小为 max_pool(默认为4)。
    b)connect_using_existing_connection()从连接池获取后端连接(需要连接的db,用户名等连接参数都相同)。循环执行pool_process_query(),将前端的请求转发到合适的后端。
  注意:如果超过 num_init_children 数的客户端尝试连接到 pgpool-II,它们将被阻塞(而不是拒绝连接),直到到任何一个 pgpool-II 进程的连接被关闭为止。最多有 2*num_init_children 可以被放入等待队列。

6.PCP:接收并处理PCP请求。

7.worker process:
  1)检查并执行reload_config请求;
  2)检查并执行restart_request请求;
  3)检查streaming replication mode下的主备延迟。


pgpoll-II 的四种模式:
load_balance_mode  负载均衡模式
replication_mode   复制模式
master_slave_mode  主备模式/主从模式(流复制模式)
parallel_mode      并行查询模式

pgpoll-II在不同模式下,提供了不同的功能,详情如下:

模式\功能    连接池    复制    负载均衡    故障恢复    在线恢复    并行查询    服务器数量   是否需要系统数据库
原始模式(*3):x         x        x            √          x            x          1或更多       x
复制模式:    √         √        √            √          √            x          2或更多       x
主备模式:    √         x        √            √         (*2)          x          2或更多       x
并行查询模式:√        (*1)     (*1)          x          x            √          2或更多       √

注意:
(*1):并行查询模式需要同时打开复制和负载均衡,但是复制和负载均衡无法用于并行查询模式中的分布式表。
(*2):准备模式的在线恢复可以和流复制同时使用。
(*3):客户端仅仅是通过 pgpoll-II 连接到 PostgreSQL服务器。这种模式仅仅用于限制到服务器的连接数,或者在多台机器上启用故障恢复。

一般情况下会选择配置为主备模式,实现故障恢复(自动failover)。

pgpoll-II 主备模式top结构:

                  pgpoll-II(VIP)
                    /           \
                   /              \
                  /                 \
             read&write       read
                /                      \
               /                         \
             v                            v
      pgpoll-II(master)            pgpoll-II(slave)
      pg(primary) ---------------> pg(standby)
                  streaming,sync         
    

pgpoll-II 的主要配置文件:
pcp.conf:用于管理、查看节点信息,如加入新节点。该文件主要是存储用户名及md5形式的密码。
pgpool.conf:pgpool的模式配置、主备数据库等信息的配置文件。
pool_hba.conf:用于认证用户登录方式,如客户端IP限制等,类似于postgresql的pg_hba.conf文件。
pool_passwd:用于保存相应客户端登录帐号名及md5密码。


关于pg_hba.conf、pool_hba.conf以及pool_passwd三者关系:
pg_hba.conf:是PostgreSQL数据库的客户端认证配置文件,用于对访问PostgreSQL数据库的请求实施访问认证控制。
pool_hba.conf:是pgpoll-II中间件的客户端认证配置文件,用于对访问pgpoll-II中间件的请求实施访问认证控制。同时,因为pgpoll-II位于PostgreSQL之前,因此请求需要先通过pgpoll-II的认证控制,随后通过PostgreSQL的认证控制。
pool_passwd:是pgpoll-II的认证文件。由于pgpoll-II无法获取PostgreSQL数据库上的用户密码信息,因此其通过检查pool_passwd内用户名及密码的方式,校验请求输入的用户名及密码是否正确。另外,当请求通过pgpoll-II认证后,pgpoll-II 将使用 pool_passwd 内保存的用户名及密码,连接后端 PostgreSQL 数据库。

注意:
1)如果 pgpoll-II 层面验证失败,会报错 "MD5" authentication with pgpool failed for user "XX"
1)如果 pgpoll-II 及 PostgreSQL 层面均进行 md5 认证,但由于用户密码没有保存在 pool_passwd 文件中,将会导致 pgpoll-II 层验证失败,报错 "MD5" authentication with pgpool failed for user "XX"。
2)如果 pgpoll-II 工作于复制、主备、并行等模式时,无法进行 md5 认证。pgpoll-II 接收到请求后,直接利用 pool_passwd 内的用户密码值,对后端 PostgreSQL 进行请求。对于非上述情况的,则采用 md5 认证。

pgpoll-II 主要脚本
pgpool.conf配置文件中需要指定的相关功能脚本(配置文件中需要配置脚本文件路径)
1,failover.sh:故障切换脚本。完成主备库角色的切换,主要有两种方式,推荐使用方式 pg_ctl promote 命令。
2,basebackup.sh & pgpool_remote_start.sh:Online Recovery脚本。basebackup.sh 主要是以在线备份恢复的方式重新构建备库;pgpool_remote_start 执行数据库启动命令。


二、pgpool-II+PostgreSQL HA方案部署

方案说明:
PostgreSQL主备方案通过流复制(replication)的方式实现了热备切换,但是是要手动建立触发文件实现,对于一些HA场景来说,还需要当主机宕机了后备机能自动切换。
pgpool-II中间件就可以实现这种功能。在PostgreSQL流复制( replication )的基础上,将PostgreSQL主、备两个节点加入pgpoll-II集群中,可实现读写分离、负载均衡、HA故障自动切换。
pgpoll-II主、备两个节点可以委托一个VIP节点作为应用程序访问的总入口地址,pgpoll-II主、备两节点之间通过watchdog看门狗进程进行监控,当pgpool1-II主节点宕机时,pgpool-II备节点会自动接管VIP继续对外提供不间断服务。

pgpoll-II 主备模式top结构:

                  pgpoll-II(VIP)
                    /           \
                   /              \
                  /                 \
             read&write       read
                /                      \
               /                         \
             v                            v
      pgpoll-II(master)            pgpoll-II(slave)
      pg(primary) ---------------> pg(standby)
                  streaming,sync    

PostgreSQL: 主备模式(流复制)
pgpool-II: 主备模式(流复制)、可同时开启负载均衡,分发查询任务给备节点(备节点不支持写)

部署整体上包含两个过程:
1.PostgreSQL(主备)的安装和配置
2.pgpool-II(主备)的安装和配置


1,环境准备
Server01:pgpoll-II(active/master)  + PostgreSQL(primary/master)
Server02:pgpoll-II(standby/slave) + PostgreSQL(standby/slave)

Centos7.8(4Core8G100g) + PostgreSQL 12.8 + pgpool-II-12-4.1.4

node      hostname   Services                 ip            
Server01  pgmaster   PostgreSQL + pgpool-II   192.168.100.93
Server02  pgslave    PostgreSQL + pgpool-II   192.168.100.94
VIP       poolvip    --                       192.168.100.95 (VIP无需独立节点)


2,PostgreSQL 12集群(主备)的安装,这里不详细介绍了,可以参考:
Centos7部署PostgreSQL 12集群(主备)》:https://blog.csdn.net/sunny05296/article/details/121000196


3.pgpoll-II 集群安装(主、备)


主备节点上设置/etc/hosts,添加poolvip的映射:
echo '
192.168.100.95 poolvip
' >> /etc/hosts


我直接通过 yum install -y pgpool-II-12 安装的,没有走rpm单独下载的方式安装。

如果要单独下载安装,可以参考官方的下载地址:
https://pgpool.net/mediawiki/index.php/Downloads
https://pgpool.net/mediawiki/index.php/Yum_Repository
https://www.pgpool.net/yum/rpms/4.2/redhat/rhel-7-x86_64/

官方的资料手册(不同版本有区别):
--pgpool所有版本官方文档:
  --所有版本手册: https://pgpool.net/mediawiki/index.php/Documentation
  --所有版本手册: https://www.pgpool.net/docs/
    --pgpool-II-4.1.4资料手册:
      --4.1.4版本手册: https://www.pgpool.net/docs/pgpool-II-4.1.4/en/html/
      --4.1.4版本手册-Installation: https://www.pgpool.net/docs/pgpool-II-4.1.4/en/html/installation.html
      --4.1.4版本手册-Server Configuration: https://www.pgpool.net/docs/pgpool-II-4.1.4/en/html/runtime-config.html
      --4.1.4版本手册-Server Configuration-Runing mode: https://www.pgpool.net/docs/pgpool-II-4.1.4/en/html/runtime-config-running-mode.html
      低版本pgpool-II 3.5.4还有中文手册:https://www.pgpool.net/docs/pgpool-II-3.5.4/doc/pgpool-zh_cn.html,高版本就没有提供中文手册了,只有英文手册。

--pgpool官方配置样例: https://www.pgpool.net/docs/latest/en/html/example-cluster.html
--pgpool FAQ: https://www.pgpool.net/mediawiki/index.php/FAQ


Master slave mode: 
  This mode is used to couple Pgpool-II with another master/slave replication software (like Slony-I and Streaming replication), that is responsible for doing the actual data replication.
  Load balancing (see Section 5.7 ) can also be used with master/slave mode to distribute the read load on the standby backend nodes.

Replication mode:
  This mode makes the Pgpool-II to replicate data between PostgreSQL backends.
  Load balancing (see Section 5.7 ) can also be used with replication mode to distribute the load to the attached backend nodes.
  重点关注:replicate_select 参数的配置,几种模式的配置说明,参考: "Table 5-2. replicate_select with load_balance_mode affects on SELECT routing" 
  When set to on, Pgpool-II enables the SELECT query replication mode. i.e. The SELECT queries are sent to all backend nodes.
  Table 5-2. replicate_select with load_balance_mode affects on SELECT routing

  replicate_select is true.                                                                      Y               N
  load_balance_mode is true.                                                                    ANY       Y          N
  SELECT is inside a transaction block.                                                          ANY        Y    N   ANY
  Transaction isolation level is SERIALIZABLE and the transaction has issued a write query.      ANY      Y N    ANY     ANY
  results(R:replication, M: send only to master, L: load balance).                              R         M L     L      M
  Default is off.

不同模式的配置文件模板:
pgpool.conf.sample               #Raw mode
pgpool.conf.sample-logical       #Logical replication mode
pgpool.conf.sample-master-slave  #主/备模式(Slony-I)
pgpool.conf.sample-replication   #Replication mode(复制模式)
pgpool.conf.sample-stream        #Streaming replication mode(流复制模式)
pgpool_remote_start.sample       #

failover.sh.sample               #4.1版本用这个模板
follow_master.sh.sample          #没有找到相关说明

In the raw mode, Pgpool-II does not care about the database synchronization. It's user's responsibility to make the whole system does a meaningful thing. Load balancing is not possible in the mode.

> 安装系统依赖包
# yum install -y libmemcached resource-agents 

> 安装 pgpool-II (pgpool-master & pgpool-slave 节点上安装)

# yum search pgpool-II
# yum install -y pgpool-II-12   #我的PG 12,选择安装pgpool-II-12


查看安装后的信息(我装的4.1.4版本)
# rpm -qa |grep pgpool
pgpool-II-12-4.1.4-1.rhel7.x86_64

安装后的目录位置:
/etc/pgpool-II-12/
/usr/pgpool-12/

# ls -1 /etc/pgpool-II-12/
failover.sh.sample
follow_master.sh.sample
pcp.conf.sample
pgpool.conf.sample
pgpool.conf.sample-logical
pgpool.conf.sample-master-slave
pgpool.conf.sample-replication
pgpool.conf.sample-stream
pgpool_remote_start.sample
pool_hba.conf.sample
recovery_1st_stage.sample
recovery_2nd_stage.sample

设置开机自启动
# systemctl enable pgpool-II-12


> 设置环境变量(主、备) 
主节点环境变量配置:
# echo '
PGPOOLHOME=/usr/pgpool-12
export PGPOOLHOME
PATH=$PATH:$PGPOOLHOME/bin
' >> .bash_profile

# source .bash_profile
# echo $PGPOOLHOME

# su - postgres
$ echo '
PGPOOLHOME=/usr/pgpool-12
export PGPOOLHOME
PATH=$PATH:$PGPOOLHOME/bin
' >> .bash_profile

$ source .bash_profile 
$ echo $PGPOOLHOME

备节点环境变量配置:备节点从主节点拷贝环境变量文件
# cd ~
# scp scp pgmaster:/root/.bash_profile ./
# source .bash_profile 
# echo $PGPOOLHOME

# su - postgres
$ scp pgmaster://var/lib/pgsql/.bash_profile ./
$ source .bash_profile
$ echo $PGPOOLHOME

> 目录创建&相关目录权限设置
# chown -R postgres.postgres /etc/pgpool-II-12/
# mkdir -p /var/run/pgpool-II-12
# chown postgres.postgres /var/run/pgpool-II-12

> 免密互信设置
root & postgres用户ssh免密互信设置
前面章节我已经设置节点ssh免密互信关系,这里就不用再设置了


> 修改配置文件(master)

修改配置文件前,先备份所有配置文件模板目录
# cp -r /etc/pgpool-II-12/ /etc/pgpool-II-12.bak

配置文件介绍:
pcp.conf:     用于管理、查看节点信息,如加入新节点。该文件主要是存储用户名及md5形式的密码。
pgpool.conf:  pgpool的模式配置、主备数据库等信息的配置文件。
pool_hba.conf:用于认证用户登录方式,如客户端IP限制等,类似于postgresql的pg_hba.conf文件。
pool_passwd:  用于保存相应客户端登录帐号名及md5密码。

单机和集群的配置文件模板有区别,配置时根据需要选择
[root@pgmaster ~]# ls -l /etc/pgpool-II-12.bak/
total 252
-rw-r--r-- 1 root root  2756 Oct 22 01:48 failover.sh.sample
-rw-r--r-- 1 root root  6575 Oct 22 01:48 follow_master.sh.sample
-rw-r--r-- 1 root root   858 Oct 22 01:48 pcp.conf.sample
-rw-r--r-- 1 root root 43528 Oct 22 01:48 pgpool.conf.sample
-rw-r--r-- 1 root root 42110 Oct 22 01:48 pgpool.conf.sample-logical
-rw-r--r-- 1 root root 43246 Oct 22 01:48 pgpool.conf.sample-master-slave
-rw-r--r-- 1 root root 43339 Oct 22 01:48 pgpool.conf.sample-replication
-rw-r--r-- 1 root root 43446 Oct 22 01:48 pgpool.conf.sample-stream
-rw-r--r-- 1 root root  1080 Oct 22 01:48 pgpool_remote_start.sample
-rw-r--r-- 1 root root  3476 Oct 22 01:48 pool_hba.conf.sample
-rw-r--r-- 1 root root  2830 Oct 22 01:48 recovery_1st_stage.sample
-rw-r--r-- 1 root root   712 Oct 22 01:48 recovery_2nd_stage.sample

# su - postgres
$ cd /etc/pgpool-II-12

pool_hba.conf 修改
$ cp pool_hba.conf.sample pool_hba.conf
$ vi pool_hba.conf
初始配置内容如下:
# "local" is for Unix domain socket connections only
local   all         all                               trust
# IPv4 local connections:
host    all         all         127.0.0.1/32          trust
host    all         all         ::1/128               trust

注意:修改时需要和 PostgreSQL 的 $PGDATA/pg_hba.conf 配置保持一致
注释掉初始的配置,我修改后配置如下:
# myconfigs
local   all             all                                     trust
host    all             all             0.0.0.0/0               md5
host    replication     replica         pgslave                 trust


pcp.conf 修改
$ cp pcp.conf.sample pcp.conf
$ pg_md5 1q2w3e
3fde6bb0541387e4ebdadf7c2ff31123
$ echo 'postgres:3fde6bb0541387e4ebdadf7c2ff31123' >> pcp.conf

注意:这里我出现了一点小插曲,最初密码配置错误,执行 pg_md5 postgres 的结果写入文件,导致后续通过pgpool 9999端口连接数据库失败、md5认证失败,提示密码错误。
后来检查时才发现,这里是针对postgres用户的密码进行hash计算,因此这里应该执行 pg_md5 1q2w3e 而不是 pg_md5 postgres。实际执行hash计算时,要输入你的postgres用户对应的实际密码。


pgpool.conf 修改
$ cp pgpool.conf.sample pgpool.conf
pgpool.conf的配置修改、放到后面单独介绍,这里先暂时跳过

pool_passwd 修改
$ pg_md5 -p -m -u postgres pool_passwd

注意:这里提示输入postgres用户的密码时一定要输入正确,这里不会检查正确性,但后面连接数据库时,如果这里配置密码错误,会导致后续连接认证失败


failover.sh脚本创建和配置
配置文件里,故障处理配置的是failover_command指定了failover的执行脚本,这里需要配置
$ cp failover.sh.sample  failover.sh
$ vi failover.sh

发现 failover.sh 默认配置内容并不想网上所介绍的如下内容:

#! /bin/sh
# Failover command for streaming replication.
# Arguments: $1: new master hostname.

new_master=$1
trigger_command="$PGHOME/bin/pg_ctl promote -D $PGDATA"
# Prompte standby database.
/usr/bin/ssh -T $new_master $trigger_command
exit 0;

而是如下:

#!/bin/bash
# This script is run by failover_command.

set -o xtrace
exec > >(logger -i -p local1.info) 2>&1

# Special values:
#   %d = failed node id
#   %h = failed node hostname
#   %p = failed node port number
#   %D = failed node database cluster path
#   %m = new master node id
#   %H = new master node hostname
#   %M = old master node id
#   %P = old primary node id
#   %r = new master port number
#   %R = new master database cluster path
#   %N = old primary node hostname
#   %S = old primary node port number
#   %% = '%' character

FAILED_NODE_ID="$1"
FAILED_NODE_HOST="$2"
FAILED_NODE_PORT="$3"
FAILED_NODE_PGDATA="$4"
NEW_MASTER_NODE_ID="$5"
NEW_MASTER_NODE_HOST="$6"
OLD_MASTER_NODE_ID="$7"
OLD_PRIMARY_NODE_ID="$8"
NEW_MASTER_NODE_PORT="$9"
NEW_MASTER_NODE_PGDATA="${10}"
OLD_PRIMARY_NODE_HOST="${11}"
OLD_PRIMARY_NODE_PORT="${12}"

PGHOME=/usr/pgsql-11
......
## If there's no master node anymore, skip failover.
if [ $NEW_MASTER_NODE_ID -lt 0 ]; then
    logger -i -p local1.info failover.sh: All nodes are down. Skipping failover.
        exit 0
fi
......
## If Standby node is down, skip failover.
......
## Promote Standby node.
logger -i -p local1.info failover.sh: Primary node is down, promote standby node ${NEW_MASTER_NODE_HOST}.

ssh -T -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \
    postgres@${NEW_MASTER_NODE_HOST} -i ~/.ssh/id_rsa_pgpool ${PGHOME}/bin/pg_ctl -D ${NEW_MASTER_NODE_PGDATA} -w promote

if [ $? -ne 0 ]; then
    logger -i -p local1.error failover.sh: new_master_host=$NEW_MASTER_NODE_HOST promote failed
    exit 1
fi

logger -i -p local1.info failover.sh: end: new_master_node_id=$NEW_MASTER_NODE_ID started as the primary node
exit 0


内容比较长,这里不全部贴出来了

需要修改PGHOME
$ vi failover.sh
PGHOME=PGHOME=/usr/pgsql-12    #默认是 /usr/pgsql-11,请按照实际修改

给failover.sh增加用户执行权限:
$ chmod u+x failover.sh


配置系统命令权限,配置 ifconfig(有的人用 ip addr), arping 执行权限 ,执行 failover.sh 需要用到,可以让其他普通用户执行。同时再创建两个日志文件目录:
root用户执行:
chmod u+s /sbin/ifconfig; chmod u+s /sbin/ip; chmod u+s /sbin/arping
chmod u+s /usr/sbin/ifconfig; chmod u+s /usr/sbin/ip; chmod u+s /usr/sbin/arping
mkdir -p /var/log/pgpool-II-12; chown -R postgres.postgres /var/log/pgpool-II-12; mkdir -p /var/run/pgpool-II-12; chown -R postgres.postgres /var/run/pgpool-II-12 

注意:
这里最初我只针对ifconfig设置,后面配置却用到了ip,导致后续VIP网卡创建失败,我索性把ifconfig, ip全加上了。还有 /sbin/和/usr/sbin两个目录下的文件我都授权了,否则后面定位修改可能会改错目录导致没有授权
如果命令权限没有,ifconfig 查看网卡,发现VIP网卡没有起来
这个问题掉坑里了,花了我不少时间定位


master配置pgpool.conf(关于参数,配置文件中有详细注释):
# su - postgres
$ cd /etc/pgpool-II-12
$ vi pgpool.conf

listen_addresses = '*'      #修改
port = 9999                 #使用默认值
pcp_listen_addresses = '*'  #使用默认值
pcp_port = 9898             #使用默认值
backend_hostname0 = 'pgmaster' #修改,主机名/IP。指定连接到 PostgreSQL 后台程序的地址。参数名的末尾添加一个数字来指定多个后台程序。被设置数据库节点ID为 0 的后台程序后台程序将被叫做“主数据库”
backend_port0 = 5432           #使用默认值、根据实际情况修改
backend_weight0 = 1            #使用默认值,指定pgpool-II后台程序的负载均衡的权重,默认值为1。参数名的末尾加一个数字来指定多个后台程序(例如:backend_weight0, backend_weight1)。修改必须重启 pgpool-II 才能生效。如果只计划使用一台 PostgreSQL 服务器,可以通过 backend_weight0 指定。
backend_data_directory0 = '/var/lib/pgsql/12/data' #使用默认值
backend_flag0 = 'ALLOW_TO_FAILOVER'  #使用默认值
backend_application_name0 = 'server0' #使用默认值,walsender's application_name, used for "show pool_nodes" command
backend_hostname1 = 'pgslave'  #修改,主机名/IP
backend_port1 = 5432         #使用默认值,根据实际情况修改
backend_weight1 = 1          #使用默认值
backend_data_directory1 = '/var/lib/pgsql/12/data'  #修改
backend_flag1 = 'ALLOW_TO_FAILOVER'  #使用默认值
backend_application_name1 = 'server1' #使用默认值,根据实际情况修改

# - Authentication -
enable_pool_hba = on          #修改
pool_passwd = 'pool_passwd'   #使用默认值

# FILE LOCATIONS
pid_file_name = '/var/run/pgpool-II-12/pgpool.pid' #使用默认值'/var/run/pgpool-II-12/pgpool.pid'
logdir = '/var/log/pgpool-II-12'                   使用默认值'/var/log/pgpool-II-12'

replication_mode = off                   #使用默认值关闭
load_balance_mode = on                   #修改
master_slave_mode = on                   #修改。设置为流复制模式
master_slave_sub_mode = 'stream'         #使用默认值。设置为流复制模式
sr_check_period = 5                      #修改
sr_check_user = 'replica'                #修改
sr_check_password = 'replica@1q2w3e'     #修改,如果是trust则注释掉
sr_check_database = 'postgres'           #使用默认值

# -HEALTH CHECK GLOBAL PARAMETERS-

health_check_period = 10                 #修改。默认是0代表关闭健康检查。健康检查的间隔,单位为秒。
health_check_timeout = 20                #使用默认值。健康检查的等待超时时间,单位为秒,默认值为20。0表示禁用超时(一直等待到 TCP/IP 超时)。
                                         #pgpool-II定期尝试连接到后台以检测backend后台数据库服务是否正常,如果检测到错误,则pgpool-II会尝试进行故障恢复或者退化操作。该参数可以避免健康检查在网络故障(例如网线断开等)情况下等待太长时间。
health_check_user = 'postgres'           #修改,执行健康检查的数据库用户,必须存在于数据库中
health_check_password = '1q2w3e'         #数据库密码 
health_check_database = 'postgres'       #修改。可根据实际设置,否则primary数据库down了,pgpool不知道,不能及时切换。默认为 '',即首先尝试使用“postgres”数据库,之后尝试“template1”数据库,直到成功。
health_check_max_retries = 0             #健康检查失败的最大重试次数,默认为0不重试。达到最大次数后不再进行健康检查,即使主节点恢复了,状态还是失败。默认值为0代表失败后不进行重试。
                                         #注意:如果启用 health_check_max_retries ,必须禁用 failover_on_backend_error 。
health_check_retry_delay = 1             #健康检查失败重试之间的间隔时间(单位为秒),默认值为1。如果为0则立即重试。
connect_timeout = 10000                  #使用connect()系统调用时放弃连接到后端的超时时间(单位毫秒)。默认为10000毫秒(10秒)。0表示不允许超时。注意:本参数不仅仅用于健康检查,也用于普通连接池的连接。

# --FAILOVER AND FAILBACK--
failover_command = '/etc/pgpool-II-12/failover.sh %H ' #修改
failover_on_backend_error = on           #默认为on。打开时,当往后台进程的通信中写入数据时发生错误时,pgpool-II将触发failover故障迁移处理;否则如果设置为off,pgpool-II将报告错误并断开该连接。
                                         #当连接到一个后台进程失败或者pgpool-II探测到master由于管理原因关闭,pgpool-II也会执行故障恢复过程。
                                         #注意:如果启用 health_check_max_retries ,必须禁用 failover_on_backend_error 。

# --WATCHDOG--
use_watchdog = on                     #修改
trusted_servers = 'pgmaster,pgslave'  #修改,检测到前端服务器的链路状态的信任服务器的列表(IP或hostname),逗号分隔,每台都要能支持ping通,例如:hostA,hostB,hostC
ping_path = '/bin'                    #使用默认值,ping command path
wd_hostname = 'pgmaster'              #修改,相互监控的看门狗进程(本机)的hostname或IP。Host name or IP address of this watchdog。
wd_port = 9000                        #使用默认值
wd_priority = 1                       #使用默认值

# --VIP config
delegate_IP = '192.168.100.95'        #修改,VIP(多台pgpool-II对外的的IP),指定客户端服务器(应用服务器等)昧拥降膒gpool-II的虚拟IP地址(VIP)。当一个pgpool-II从slave换到active,pgpool-II将使用这个VIP。
if_cmd_path = '/sbin'                 #使用默认值。指定切换IP地址的命令所在的路径
if_up_cmd = '/sbin/ip addr add $_IP_$/24 dev ens160 label ens160:0'   #修改,确认网卡名和netmask正确。指定用于启用VIP的命令。
                                       #注意:网上有的人配置为 'ifconfig ens160:0 inet $_IP_$ netmask 255.255.255.0'
                                       #也有人配置为: '/usr/bin/sudo /sbin/ip addr add $_IP_$/24 dev ens160 label ens160:0'
                                       #无论用 ifconfig 还是 ip addr。但要注意 chmod u+s /sbin/xx 执行权限时,需要保持一致、对使用的命令授权
if_down_cmd = '/sbin/ip addr del $_IP_$/24 dev ens160'  #修改,确认网卡名和netmask正确。同样可以设置为 'ifconfig ens160:0 down'
arping_path = '/usr/sbin'              #使用默认值,VIP切换后用于发送 ARP 请求的arping命令所在的路径。
arping_cmd = '/usr/sbin/arping -U $_IP_$ -w 1 -I ens160'  #修改,确认网卡名正确。注意:使用的命令要chmod u+s授权。有的人加了/usr/bin/sudo,我系统没有配置sudo,直接去掉/usr/bin/sudo。有的人用的是/sbin/arping,注意chmod u+s xxx正确授权

#- Watchdog consensus settings for failover –    #该模块负责pgpool-II 节点仲裁,watchdog(pgpool-II节点)本身故障后,其他节点会执行仲裁,选取出一个主节点去请求VIP
failover_when_quorum_exists = on
failover_require_consensus = on
allow_multiple_failover_requests_from_node = on  #默认off关闭,需要修改为on。如果不修改,可能导致pgpool-II主节点故障后VIP不会漂移
enable_consensus_with_half_votes = on            #默认off关闭,需要修改为on。如果不修改,可能导致pgpool-II主节点故障后VIP不会漂移

# - Lifecheck Setting -
# -- heartbeat mode --
wd_heartbeat_port = 9694               #使用默认值
wd_heartbeat_keepalive = 2             #使用默认值
wd_heartbeat_deadtime = 30             #使用默认值
heartbeat_destination0 = 'pgslave'     #修改,指定心跳信号发送的目标(目的端)的IP或hostname, 本参数名后面的数字表示“目标序号”,从0开始,通过序号区分参数可以指定多个发送目标
heartbeat_destination_port0 = 9694     #使用默认值
heartbeat_device0 = 'ens160'           #修改,网卡名

# --Other pgpool Connection Settings --
other_pgpool_hostname0 = 'pgslave'     #修改,指定被监控的pgpool-II服务器(对端)的主机名。参数末尾的数字表示“服务器id”,必须从0开始
other_pgpool_port0 = 9999              #修改,指定被监控的pgpool-II服务器(对端)的pgpool的端口号。参数末尾的数字表示“服务器id”,必须从0开始
other_wd_port0 = 9000                  #修改,指定pgpool-II服务器(对端)的需要被监控的看门狗的端口号。参数末尾的数字表示“服务器id”,必须从0开始

#other_pgpool_hostname1 = 'host1'      #如果集群部署节点较多、还有其他备监控的pgpool-II节点,则根据实际情况配置其他节点
#other_pgpool_port1 = 5432             #如果集群部署节点较多、还有其他备监控的pgpool-II节点,则根据实际情况配置其他节点
#other_wd_port1 = 9000                 #如果集群部署节点较多、还有其他备监控的pgpool-II节点,则根据实际情况配置其他节点


> 修改配置文件(slave)

备份配置文件模板目录
# cp -r /etc/pgpool-II-12/ /etc/pgpool-II-12.bak 

直接从master节点拷贝所有 pgpool 配置文件
# su - postgres
$ cd /etc/pgpool-II-12

从master远程拷贝5个文件:
scp postgres@pgmaster:/etc/pgpool-II-12/pool_hba.conf ./
scp postgres@pgmaster:/etc/pgpool-II-12/pcp.conf ./
scp postgres@pgmaster:/etc/pgpool-II-12/pgpool.conf ./
scp postgres@pgmaster:/etc/pgpool-II-12/pool_passwd ./
scp postgres@pgmaster:/etc/pgpool-II-12/failover.sh ./

修改slave配置文件(主要是针对slave和master有区别的地方进行修改)

$ vi pool_hba.conf
注意:修改时需要和 PostgreSQL 的 $PGDATA/pg_hba.conf 配置保持一致

# myconfigs
local   all             all                                     trust
host    all             all             0.0.0.0/0               md5
host    replication     replica         pgmaster                trust


pcp.conf 修改:和master一致、无需修改,直接跳过


pgpool.conf 修改(修改slave区别于master的相关参数):
$ vi pgpool.conf
wd_hostname = 'pgslave'                 #修改,相互监控的看门狗进程(本机)的hostname或IP。Host name or IP address of this watchdog。
heartbeat_destination0 = 'pgmaster'     #修改,指定心跳信号发送的目标(目的端)的IP或hostname
other_pgpool_hostname0 = 'pgmaster'     #修改,指定被监控的pgpool-II服务器(对端)的主机名。参数末尾的数字表示“服务器id”,必须从0开始

注意:
1)这里如果遗漏修改成对端,我最初 heartbeat_destination0 = 'pgslave' 忘了修改成 'pgmaster',导致重启pgpool服务时要等待很长时间才能 psql 连接数据库,修改正确后,重复服务很快就能连接了。
2)如果slave节点的网卡名和master不同,则也需要修改对应参数


pool_passwd 修改:和master一致、无需修改,直接跳过


failover.sh 脚本创建和配置:和master一致、无需修改,直接跳过


给failover.sh增加用户执行权限:
$ chmod u+x failover.sh


配置系统命令权限,配置 ifconfig(有的人用 ip addr), arping 执行权限 ,执行 failover.sh 需要用到,可以让其他普通用户执行。同时再创建两个日志文件目录:
root用户执行:
chmod u+s /sbin/ifconfig; chmod u+s /sbin/ip; chmod u+s /sbin/arping
chmod u+s /usr/sbin/ifconfig; chmod u+s /usr/sbin/ip; chmod u+s /usr/sbin/arping
mkdir -p /var/log/pgpool-II-12; chown -R postgres.postgres /var/log/pgpool-II-12; mkdir -p /var/run/pgpool-II-12; chown -R postgres.postgres /var/run/pgpool-II-12 

备节点配置完毕。

pgpool-II主、备节点配置完毕后,重启pgpool-II服务(主、备):
# systemctl restart pgpool-II-12
# systemctl status  pgpool-II-12
ifconfig可查看VIP(ens160:0)绑定在哪个节点
# ifconfig 


连接数据库测试 & 查看节点状态


主节点:
通过pgmaster连接pgpool端口:
# psql -hpgmaster -p9999 -Upostgres
postgres=# show pool_nodes;
 node_id | hostname | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change  
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
 0       | pgmaster | 5432 | up     | 0.500000  | primary | 0          | true              | 0                 |                   |                        | 2021-11-04 21:47:15
 1       | pgslave  | 5432 | up     | 0.500000  | standby | 0          | false             | 0                 |                   |                        | 2021-11-04 21:47:15

通过pgslave连接pgpool端口:
[root@pgmaster pgpool-II-12]# psql -hpgslave -p9999 -Upostgres
postgres=# show pool_nodes;
 node_id | hostname | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change  
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
 0       | pgmaster | 5432 | up     | 0.500000  | primary | 0          | false             | 0                 |                   |                        | 2021-11-04 21:51:54
 1       | pgslave  | 5432 | up     | 0.500000  | standby | 0          | true              | 0                 |                   |                        | 2021-11-04 21:51:54

通过VIP连接pgpool端口:
[root@pgmaster pgpool-II-12]# psql -hpoolvip -p9999 -Upostgres        
postgres=# show pool_nodes;
 node_id | hostname | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_c
hange  
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
 0       | pgmaster | 5432 | up     | 0.500000  | primary | 0          | false             | 0                 |                   |                        | 2021-11-04 21:47:15
 1       | pgslave  | 5432 | up     | 0.500000  | standby | 0          | true              | 0                 |                   |                        | 2021-11-04 21:47:15


备节点:
通过pgmaster连接pgpool端口:
# psql -hpgmaster -p9999 -Upostgres
postgres=# show pool_nodes;
 node_id | hostname | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change  
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
 0       | pgmaster | 5432 | up     | 0.500000  | primary | 0          | true              | 0                 |                   |                        | 2021-11-04 21:47:15
 1       | pgslave  | 5432 | up     | 0.500000  | standby | 0          | false             | 0                 |                   |                        | 2021-11-04 21:47:15

postgres=# \q

通过pgslave连接pgpool端口:
[root@pgslave pgpool-II-12]# psql -hpgslave -p9999 -Upostgres      
postgres=# show pool_nodes;
 node_id | hostname | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change  
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
 0       | pgmaster | 5432 | up     | 0.500000  | primary | 0          | false             | 0                 |                   |                        | 2021-11-04 21:51:54
 1       | pgslave  | 5432 | up     | 0.500000  | standby | 0          | true              | 0                 |                   |                        | 2021-11-04 21:51:54

通过VIP连接pgpool端口:
[root@pgslave pgpool-II-12]# psql -hpoolvip -p9999 -Upostgres
postgres=# show pool_nodes;
 node_id | hostname | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change  
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
 0       | pgmaster | 5432 | up     | 0.500000  | primary | 0          | false             | 0                 |                   |                        | 2021-11-04 21:47:15
 1       | pgslave  | 5432 | up     | 0.500000  | standby | 0          | true              | 0                 |                   |                        | 2021-11-04 21:47:15


模拟故障,测试failover功能

最初因为配置错误,导致failover模拟测试有问题:systemctl stop  pgpool-II-12 停止主服务,VIP无法漂移到备节点,备节点虽然日志显示提升为leader,但提示集群节点不够。但等我 systemctl start pgpool-II-12 启动主服务后,VIP却又成功的漂移到备节点了。
网上查找资料,尝试很多种办法,都没有解决该问题。
最终定位还是pgpool-II-4.1.4的配置文件参数配置导致的问题,修改相关参数解决:

vi pgpool.conf
修改后的配置如下:

#- Watchdog consensus settings for failover –    #该模块负责pgpool-II 节点仲裁,watchdog(pgpool-II节点)本身故障后,其他节点会执行仲裁,选取出一个主节点去请求VIP
failover_when_quorum_exists = on
failover_require_consensus = on
allow_multiple_failover_requests_from_node = on  #默认off关闭,需要修改为on。如果不修改,可能导致pgpool-II主节点故障后VIP不会漂移
enable_consensus_with_half_votes = on            #默认off关闭,需要修改为on。如果不修改,可能导致pgpool-II主节点故障后VIP不会漂移

1,模拟pgpool-II服务的failover切换,测试OK:停止pgpool-II主服务能,vip能漂移到备节点,pgpool-II 9999端口连接OK。
2,模拟PostgreSQL服务的failover切换,测试OK:停止PostgreSQL主服务,大约过几分钟后( tail -f /var/log/message 可查看切换日志信息),故障切换成功,pgpool-II 9999端口连接OK:
# psql -hpoolvip -p9999 -Upostgres
postgres=# show pool_nodes;
 node_id | hostname | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change  
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
 0       | pgmaster | 5432 | down   | 0.500000  | standby | 0          | false             | 0                 |                   |                        | 2021-11-05 19:22:48
 1       | pgslave  | 5432 | up     | 0.500000  | standby | 0          | true              | 0                 |                   |                        | 2021-11-05 13:48:16

查看主节点状态为down,原来主节点primary角色变为了standby角色。

但failover好像并没有完成PostgreSQL主备的配置切换,PostgreSQL主服务down掉以后,仅仅只是pgpool-II后端连接到了备节点提供查询服务。
如果要写数据库的话,难道还是需要人为处理:恢复PostgreSQL主服务,或者将PostgreSQL备切换为主服务、故障的主切换为备,才能写入数据?
PostgreSQL主节点down掉以后,pgpool-II能否自动完成PostgreSQL的主备配置切换?待后续再继续跟踪和确认。

重新启动/恢复主节点PostgreSQL服务
# systemctl start postgresql-12
# systemctl status postgresql-12
# psql -hpoolvip -p9999 -Upostgres
postgres=# show pool_nodes;
发现主节点状态没有自动恢复成up,仍然显示为down

尝试从pgpool提升一个节点,将备节点提升为主节点:
# pcp_promote_node --help
# pcp_promote_node -v -d -hpoolvip -p9898 -Upostgres -n 1    #NODEID是从0开始的,-n 1: 指定NODEID为1,提升该节点为主节点
# psql -hpoolvip -p9999 -Upostgres
postgres=# show pool_nodes;
 node_id | hostname | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change  
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
 0       | pgmaster | 5432 | down   | 0.500000  | standby | 0          | false             | 0                 |                   |                        | 2021-11-05 19:58:14
 1       | pgslave  | 5432 | up     | 0.500000  | primary | 1          | true              | 0                 |                   |                        | 2021-11-05 19:58:14

备节点以及提升为主节点了

再尝试重新关联一次主节点试试:
# pcp_attach_node -v -d -n 0 -Upostgres
Password: 
DEBUG: recv: tos="m", len=8
DEBUG: recv: tos="r", len=21
DEBUG: send: tos="C", len=6
DEBUG: recv: tos="c", len=20
pcp_attach_node -- Command Successful
DEBUG: send: tos="X", len=4
# psql -hpoolvip -p9999 -Upostgres
postgres=# show pool_nodes;
 node_id | hostname | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change  
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
 0       | pgmaster | 5432 | up     | 0.500000  | primary | 0          | true              | 0                 |                   |                        | 2021-11-05 20:11:41
 1       | pgslave  | 5432 | up     | 0.500000  | standby | 2          | false             | 0                 |                   |                        | 2021-11-05 20:03:53

重新关联node0以后,node0状态down->up了,role角色也变成了primary,node1角色自动降为standby了。

故障后,可以通过pgpool管理命令方便的完成:数据库备node1提升为主的操作,提升以后,原来的数据库主node0恢复后需要执行命令重新关联(同时会自动提升为主)。

但是:发现一个问题,主节点node0 down状态时,即使提升备节点node1为primary,发现但此时psql连接数据库 insert 插入数据失败、提示为只读连接不支持插入数据。
查看node1节点下的$PGDATA目录下的 standby.signal 文件依然存在,node0节点下的$PGDATA目录下没有自动生成 standby.signal 文件。
这说明node1的数据库并没有真正的切换为主,还是只读数据库、并不支持写操作。是failover脚本的问题,还是pgpool.conf关于failover配置的问题?该问题作为遗留问题,后续再跟踪研究。

注意:show pool_nodes; 中显示的 role 角色(primary | standby)是pgpool的主备角色、而不是数据库的主备角色。


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

pgpool-II 集群管理命令(启动&停止)

启动pgpool-II

# systemctl start pgpool-II-12
# systemctl status pgpool-II-12
# ps -aux|grep pgpool

启动两台服务器数据库(主、备)
# systemctl restart postgresql-12
# systemctl status postgresql-12


连接数据库测试 & 查看节点状态
# su - postgres
$ psql -hpgmaster -p9999 -Upostgres
$ show pool_nodes;
postgres=# show pool_nodes;
 node_id | hostname | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change  
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
 0       | pgmaster | 5432 | up     | 0.500000  | primary | 0          | false             | 0                 |                   |                        | 2021-11-04 21:47:15
 1       | pgslave  | 5432 | up     | 0.500000  | standby | 0          | true              | 0                 |                   |                        | 2021-11-04 21:47:15


多种方式测试所有IP/hostname连接是否OK:
$ psql -hpgmaster -p9999 -Upostgres        #pgmaster hostname
$ psql -hpgslave -p9999 -Upostgres         #pgslave hostname
$ psql -h192.168.100.93 -p9999 -Upostgres  #pgmaster IP
$ psql -h192.168.100.94 -p9999 -Upostgres  #pgslave IP
$ psql -h192.168.100.95 -p9999 -Upostgres  #VIP

注意:如果这里通过pgpool 9999端口连接数据库失败,提示密码错误:
-bash-4.2$ psql -hpgmaster -p9999 -Upostgres
Password for user postgres: 
psql: error: ERROR:  md5 authentication failed
DETAIL:  password does not match
-bash-4.2$

应该排查确认 pool_password & pcp.conf 是否配置错误的密码导致。
我最初配置的密码错误,导致通过pgpool-II 9999端口连接数据库(psql -hpgmaster -p9999 -Upostgres)失败,但是直接通过PostgreSQL 5432端口直接连接数据库(psql -hpgmaster -p5432 -Upostgres)却能成功。
最后检查发现时 pcp.conf & pool_passwd 配置错误导致的:
$ cd /etc/pgpool-II-12
$ cat pool_passwd 
postgres:md54d845859e6576c06dd59ce4247da0feb

$ cat pcp.conf
postgres:e8a48653851e28c69d0506508fb27fc5 

重新配置一遍 pcp.conf & pool_passwd:
$ pg_md5 -p -m -u postgres pool_passwd
$ cat pool_passwd 
postgres:md5095ed75f7a57cf11cccee5044d80c278

$ pg_md5 1q2w3e
3fde6bb0541387e4ebdadf7c2ff31123
$ vi pcp.conf
postgres:3fde6bb0541387e4ebdadf7c2ff31123
$ cat pcap.conf
postgres:3fde6bb0541387e4ebdadf7c2ff31123

重新配置正确后,通过pgpool-II 9999端口连接成功了。


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

附录:
搭建过程中发现的其他问题,定位过程比较曲折,遇到了好多问题,定位过程记录了一部分,便于参考:

问题:
部署完以后,启动服务后,systemctl status  pgpool-II-12 查看主、备节点查看服务状态有报错:

主:
[root@pgmaster pgpool-12]# systemctl status  pgpool-II-12
● pgpool-II-12.service - PGPool-II Middleware Between PostgreSQL Servers And PostgreSQL Database Clients
   Loaded: loaded (/usr/lib/systemd/system/pgpool-II-12.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2021-11-04 12:34:54 CST; 45s ago
  Process: 26923 ExecStop=/usr/pgpool-12/bin/pgpool -f /etc/pgpool-II-12/pgpool.conf -m fast stop (code=exited, status=0/SUCCESS)
 Main PID: 26931 (pgpool)
   CGroup: /system.slice/pgpool-II-12.service
           ├─26931 /usr/pgpool-12/bin/pgpool -f /etc/pgpool-II-12/pgpool.conf -n -D
           ├─26933 pgpool: watchdog
           ├─26937 pgpool: lifecheck
           ├─26938 pgpool: wait for connection request
           ├─26939 pgpool: heartbeat receiver
           ├─26940 pgpool: wait for connection request
           ├─26941 pgpool: heartbeat sender
           ├─26942 pgpool: wait for connection request
           ......
           └─26971 pgpool: wait for connection request

Nov 04 12:35:37 pgmaster pgpool[26931]: 2021-11-04 12:35:37: pid 26931: WARNING:  failed to connect to PostgreSQL server, getaddrinfo() failed with error "Na... not known"
Nov 04 12:35:37 pgmaster pgpool[26931]: 2021-11-04 12:35:37: pid 26931: ERROR:  failed to make persistent db connection
Nov 04 12:35:37 pgmaster pgpool[26931]: 2021-11-04 12:35:37: pid 26931: DETAIL:  connection to host:"gpmaster:5432" failed
Nov 04 12:35:37 pgmaster pgpool[26931]: 2021-11-04 12:35:37: pid 26931: LOG:  find_primary_node: make_persistent_db_connection_noerror failed on node 0
Nov 04 12:35:37 pgmaster pgpool[26931]: 2021-11-04 12:35:37: pid 26931: LOG:  find_primary_node: standby node is 1
Nov 04 12:35:38 pgmaster pgpool[26931]: 2021-11-04 12:35:38: pid 26931: WARNING:  failed to connect to PostgreSQL server, getaddrinfo() failed with error "Na... not known"
Nov 04 12:35:38 pgmaster pgpool[26931]: 2021-11-04 12:35:38: pid 26931: ERROR:  failed to make persistent db connection
Nov 04 12:35:38 pgmaster pgpool[26931]: 2021-11-04 12:35:38: pid 26931: DETAIL:  connection to host:"gpmaster:5432" failed
Nov 04 12:35:38 pgmaster pgpool[26931]: 2021-11-04 12:35:38: pid 26931: LOG:  find_primary_node: make_persistent_db_connection_noerror failed on node 0
Nov 04 12:35:38 pgmaster pgpool[26931]: 2021-11-04 12:35:38: pid 26931: LOG:  find_primary_node: standby node is 1
Hint: Some lines were ellipsized, use -l to show in full.
[root@pgmaster pgpool-12]# 

备:
[root@pgslave etc]# systemctl status  pgpool-II-12
● pgpool-II-12.service - PGPool-II Middleware Between PostgreSQL Servers And PostgreSQL Database Clients
   Loaded: loaded (/usr/lib/systemd/system/pgpool-II-12.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2021-11-04 12:36:26 CST; 10s ago
  Process: 10729 ExecStop=/usr/pgpool-12/bin/pgpool -f /etc/pgpool-II-12/pgpool.conf -m fast stop (code=exited, status=0/SUCCESS)
 Main PID: 10815 (pgpool)
   CGroup: /system.slice/pgpool-II-12.service
           ├─10815 /usr/pgpool-12/bin/pgpool -f /etc/pgpool-II-12/pgpool.conf -n -D
           ├─10817 pgpool: watchdog
           ├─10825 pgpool: lifecheck
           ├─10826 pgpool: heartbeat receiver
           ├─10827 pgpool: heartbeat sender
           ├─10828 pgpool: wait for connection request
           ......
           └─10860 pgpool: wait for connection request

Nov 04 12:36:34 pgslave pgpool[10815]: 2021-11-04 12:36:34: pid 10815: WARNING:  failed to connect to PostgreSQL server, getaddrinfo() failed with error "Nam... not known"
Nov 04 12:36:34 pgslave pgpool[10815]: 2021-11-04 12:36:34: pid 10815: ERROR:  failed to make persistent db connection
Nov 04 12:36:34 pgslave pgpool[10815]: 2021-11-04 12:36:34: pid 10815: DETAIL:  connection to host:"gpmaster:5432" failed
Nov 04 12:36:34 pgslave pgpool[10815]: 2021-11-04 12:36:34: pid 10815: LOG:  find_primary_node: make_persistent_db_connection_noerror failed on node 0
Nov 04 12:36:34 pgslave pgpool[10815]: 2021-11-04 12:36:34: pid 10815: LOG:  find_primary_node: standby node is 1
Nov 04 12:36:35 pgslave pgpool[10815]: 2021-11-04 12:36:35: pid 10815: WARNING:  failed to connect to PostgreSQL server, getaddrinfo() failed with error "Nam... not known"
Nov 04 12:36:35 pgslave pgpool[10815]: 2021-11-04 12:36:35: pid 10815: ERROR:  failed to make persistent db connection
Nov 04 12:36:35 pgslave pgpool[10815]: 2021-11-04 12:36:35: pid 10815: DETAIL:  connection to host:"gpmaster:5432" failed
Nov 04 12:36:35 pgslave pgpool[10815]: 2021-11-04 12:36:35: pid 10815: LOG:  find_primary_node: make_persistent_db_connection_noerror failed on node 0
Nov 04 12:36:35 pgslave pgpool[10815]: 2021-11-04 12:36:35: pid 10815: LOG:  find_primary_node: standby node is 1
Hint: Some lines were ellipsized, use -l to show in full.
[root@pgslave etc]# 

从日志上看貌似pgpool没有连接上 PostgreSQL master node 0,只找到了 standby node 1
检查心跳机制配置参数:
https://www.pgpool.net/docs/latest/en/html/runtime-config-health-check.html
参数检查也没有发现问题。

网上搜索资料,各种办法尝试修改,都没有解决。最终还是回到报错日志上来,仔细分析日志:
failed to connect to PostgreSQL server, getaddrinfo() failed with error "Nam... not known"
从这个日志上来看,很明显是pgpool连接后端 PostgreSQL 失败,获取IP地址有问题
vi pgpool.conf 仔细检查 backend_hostname0 参数的配置,终于找到问题原因了:pgmaster 我配错成 gpmaster 了,修改回来,问题解决。

主节点:
[root@pgmaster pgpool-II-12]# systemctl restart pgpool-II-12 
[root@pgmaster pgpool-II-12]# systemctl status pgpool-II-12 
● pgpool-II-12.service - PGPool-II Middleware Between PostgreSQL Servers And PostgreSQL Database Clients
   Loaded: loaded (/usr/lib/systemd/system/pgpool-II-12.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2021-11-04 21:24:40 CST; 35s ago
  Process: 27380 ExecStop=/usr/pgpool-12/bin/pgpool -f /etc/pgpool-II-12/pgpool.conf -m fast stop (code=exited, status=0/SUCCESS)
 Main PID: 27387 (pgpool)
   CGroup: /system.slice/pgpool-II-12.service
           ├─27387 /usr/pgpool-12/bin/pgpool -f /etc/pgpool-II-12/pgpool.conf -n -D
           ├─27389 pgpool: watchdog
           ├─27394 pgpool: lifecheck
           ├─27395 pgpool: wait for connection request
           ├─27396 pgpool: heartbeat receiver
           ├─27397 pgpool: wait for connection request
           ├─27398 pgpool: heartbeat sender
           ├─27399 pgpool: wait for connection request
           ......
           ├─27428 pgpool: wait for connection request
           ├─27430 pgpool: PCP: wait for connection request
           ├─27431 pgpool: worker process
           ├─27432 pgpool: health check process(0)
           └─27433 pgpool: health check process(1)

Nov 04 21:24:46 pgmaster pgpool[27387]: 2021-11-04 21:24:46: pid 27387: DETAIL:  updating the state of quarantine backend nodes
Nov 04 21:24:46 pgmaster pgpool[27387]: 2021-11-04 21:24:46: pid 27389: LOG:  new IPC connection received
Nov 04 21:24:46 pgmaster pgpool[27387]: 2021-11-04 21:24:46: pid 27398: LOG:  creating socket for sending heartbeat
Nov 04 21:24:46 pgmaster pgpool[27387]: 2021-11-04 21:24:46: pid 27398: DETAIL:  setsockopt(SO_BINDTODEVICE) requires root privilege
Nov 04 21:24:46 pgmaster pgpool[27387]: 2021-11-04 21:24:46: pid 27398: LOG:  set SO_REUSEPORT option to the socket
Nov 04 21:24:46 pgmaster pgpool[27387]: 2021-11-04 21:24:46: pid 27398: LOG:  creating socket for sending heartbeat
Nov 04 21:24:46 pgmaster pgpool[27387]: 2021-11-04 21:24:46: pid 27398: DETAIL:  set SO_REUSEPORT
Nov 04 21:24:50 pgmaster pgpool[27387]: 2021-11-04 21:24:50: pid 27436: LOG:  successfully acquired the delegate IP:"192.168.100.95"
Nov 04 21:24:50 pgmaster pgpool[27387]: 2021-11-04 21:24:50: pid 27436: DETAIL:  'if_up_cmd' returned with success
Nov 04 21:24:50 pgmaster pgpool[27387]: 2021-11-04 21:24:50: pid 27389: LOG:  watchdog escalation process with pid: 27436 exit with SUCCESS.
[root@pgmaster pgpool-II-12]# 

备节点:
[root@pgslave pgpool-II-12]# systemctl restart pgpool-II-12 
[root@pgslave pgpool-II-12]# systemctl status pgpool-II-12 
● pgpool-II-12.service - PGPool-II Middleware Between PostgreSQL Servers And PostgreSQL Database Clients
   Loaded: loaded (/usr/lib/systemd/system/pgpool-II-12.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2021-11-04 21:24:36 CST; 38s ago
  Process: 30521 ExecStop=/usr/pgpool-12/bin/pgpool -f /etc/pgpool-II-12/pgpool.conf -m fast stop (code=exited, status=0/SUCCESS)
 Main PID: 30523 (pgpool)
   CGroup: /system.slice/pgpool-II-12.service
           ├─30523 /usr/pgpool-12/bin/pgpool -f /etc/pgpool-II-12/pgpool.conf -n -D
           ├─30525 pgpool: watchdog
           ├─30526 pgpool: lifecheck
           ├─30527 pgpool: heartbeat receiver
           ├─30528 pgpool: heartbeat sender
           ├─30529 pgpool: wait for connection request
           ......
           ├─30560 pgpool: wait for connection request
           ├─30561 pgpool: PCP: wait for connection request
           ├─30562 pgpool: worker process
           ├─30563 pgpool: health check process(0)
           └─30564 pgpool: health check process(1)

Nov 04 21:24:49 pgslave pgpool[30523]: 2021-11-04 21:24:49: pid 30525: LOG:  received the get data request from local pgpool-II on IPC interface
Nov 04 21:24:49 pgslave pgpool[30523]: 2021-11-04 21:24:49: pid 30525: LOG:  get data request from local pgpool-II node received on IPC interface is forwarde...x pgmaster"
Nov 04 21:24:49 pgslave pgpool[30523]: 2021-11-04 21:24:49: pid 30525: DETAIL:  waiting for the reply...
Nov 04 21:24:49 pgslave pgpool[30523]: 2021-11-04 21:24:49: pid 30523: LOG:  master watchdog node "pgmaster:9999 Linux pgmaster" returned status for 2 backend nodes
Nov 04 21:24:49 pgslave pgpool[30523]: 2021-11-04 21:24:49: pid 30523: LOG:  backend nodes status remains same after the sync from "pgmaster:9999 Linux pgmaster"
Nov 04 21:24:49 pgslave pgpool[30523]: 2021-11-04 21:24:49: pid 30523: LOG:  Pgpool-II parent process received watchdog quorum change signal from watchdog
Nov 04 21:24:49 pgslave pgpool[30523]: 2021-11-04 21:24:49: pid 30525: LOG:  new IPC connection received
Nov 04 21:24:49 pgslave pgpool[30523]: 2021-11-04 21:24:49: pid 30523: LOG:  watchdog cluster now holds the quorum
Nov 04 21:24:49 pgslave pgpool[30523]: 2021-11-04 21:24:49: pid 30523: DETAIL:  updating the state of quarantine backend nodes
Nov 04 21:24:49 pgslave pgpool[30523]: 2021-11-04 21:24:49: pid 30525: LOG:  new IPC connection received
Hint: Some lines were ellipsized, use -l to show in full.


问题:
1)主节点node0(gpmaster)的角色不对:role=standby,出现了2个standby,主备两个节点都是standby
2)主节点node0(gpmaster)的状态不对:status=down
3)通过VIP无法连接

定位过程:
pcp_node_info查看主备两个节点信息:
$ pcp_node_info -v -d  -n 0 -U postgres
-bash-4.2$ pcp_node_info -v -d  -n 0 -U postgres
Password: 
DEBUG: recv: tos="m", len=8
DEBUG: recv: tos="r", len=21
DEBUG: send: tos="I", len=6
DEBUG: recv: tos="i", len=71
Hostname               : gpmaster
Port                   : 5432
Status                 : 3
Weight                 : 0.500000
Status Name            : down
Role                   : standby
Replication Delay      : 0
Replication State      : 
Replication Sync State : 
Last Status Change     : 2021-10-22 22:47:53
DEBUG: send: tos="X", len=4
-bash-4.2$ 

-bash-4.2$ pcp_node_info -v -d  -n 1 -U postgres 
Password: 
DEBUG: recv: tos="m", len=8
DEBUG: recv: tos="r", len=21
DEBUG: send: tos="I", len=6
DEBUG: recv: tos="i", len=70
Hostname               : pgslave
Port                   : 5432
Status                 : 2
Weight                 : 0.500000
Status Name            : up
Role                   : standby
Replication Delay      : 0
Replication State      : 
Replication Sync State : 
Last Status Change     : 2021-10-23 11:23:09
DEBUG: send: tos="X", len=4
-bash-4.2$ 

try1,再尝试重启所有节点的 PostgreSQL & pgpool-II 服务,都没有得到解决:
# systemctl stop pgpool-II-12
# systemctl status pgpool-II-12
# systemctl stop postgresql-12
# systemctl status postgresql-12

# systemctl start postgresql-12
# systemctl status postgresql-12
# systemctl start pgpool-II-12
# systemctl tatus pgpool-II-12

注意:重新启动pgpool时,需要等PostgreSQL服务重启完成、状态显示正确以后,再启动pgpool
否则启动pgpool会报错,systemctl tatus pgpool-II-12 会看到相关 failed。psql连接数据库失败:
-bash-4.2$ psql -hpgmaster -p9999 -Upostgres
Password for user postgres: 
psql: error: FATAL:  failed to create a backend connection
DETAIL:  executing failover on backend
-bash-4.2$ 

主、备上查看日志,没有报错以后,服务就启动完成了
# tail -100f /var/log/messages

try2,查看日志和服务状态等信息,排查问题,没有解决

try3,尝试解除关联&重新关联节点(detach & attach)
$ pcp_detach_node -n 0 -U postgres
$ pcp_attach_node -v -d -n 0 -U postgres

主节点(node0)无法解除、只能解除&关联备节点(node1)

try4,先解决VIP的问题
清空日志
# echo "" > /var/log/message
# systemctl stop pgpool-II-12
# echo "--------" >> /var/log/message
# systemctl start pgpool-II-12
# vi /var/log/message

仔细分析停止和启动的pgpool日志打印信息,重点关注watchdog的相关日志信息

pgpool-II的所有关注相关端口:
9999                  Pgpool-II accepts connections
9898                  PCP process accepts connections
9000                  watchdog accepts connections
9694                  UDP port for receiving Watchdog's heartbeat signal


日志信息如下:

Oct 23 19:07:03 pgmaster pgpool: 2021-10-23 19:07:03: pid 2037: LOG:  Watchdog is shutting down
Oct 23 19:07:04 pgmaster pgpool: .done.
Oct 23 19:07:04 pgmaster systemd: Stopped PGPool-II Middleware Between PostgreSQL Servers And PostgreSQL Database Clients.
----------------------
Oct 23 19:07:22 pgmaster systemd: Started PGPool-II Middleware Between PostgreSQL Servers And PostgreSQL Database Clients.
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2112: LOG:  Backend status file /var/log/pgpool-II-12/pgpool_status discarded
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2112: LOG:  memory cache initialized
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2112: DETAIL:  memcache blocks :64
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2112: LOG:  pool_discard_oid_maps: discarded memqcache oid maps
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2112: LOG:  waiting for watchdog to initialize
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2114: LOG:  setting the local watchdog node name to "pgmaster:9999 Linux pgmaster"
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2114: LOG:  watchdog cluster is configured with 1 remote nodes
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2114: LOG:  watchdog remote node:0 on pgslave:9000
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2114: LOG:  interface monitoring is disabled in watchdog
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2114: LOG:  watchdog node state changed from [DEAD] to [LOADING]
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2114: LOG:  new outbound connection to pgslave:9000
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2114: LOG:  setting the remote node "pgslave:9999 Linux pgslave" as watchdog cluster master
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2114: LOG:  watchdog node state changed from [LOADING] to [INITIALIZING]
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2114: LOG:  new watchdog node connection is received from "192.168.100.94:12478"
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2114: LOG:  new node joined the cluster hostname:"pgslave" port:9000 pgpool_port:9999  ==>收到节点加入集群请求
Oct 23 19:07:22 pgmaster pgpool: 2021-10-23 19:07:22: pid 2114: DETAIL:  Pgpool-II version:"4.1.4" watchdog messaging version: 1.1
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2114: LOG:  watchdog node state changed from [INITIALIZING] to [STANDBY]             ==>watchdog STANDBY 状态确认
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2114: LOG:  successfully joined the watchdog cluster as standby node                 ==>watchdog STANDBY 加入集群OK
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2114: DETAIL:  our join coordinator request is accepted by cluster leader node "pgslave:9999 Linux pgslave"
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2112: LOG:  watchdog process is initialized
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2112: DETAIL:  watchdog messaging data version: 1.1
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2114: LOG:  new IPC connection received
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2112: LOG:  we have joined the watchdog cluster as STANDBY node
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2112: DETAIL:  syncing the backend states from the MASTER watchdog node
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2114: LOG:  new IPC connection received
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2114: LOG:  new IPC connection received
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2114: LOG:  received the get data request from local pgpool-II on IPC interface
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2114: LOG:  get data request from local pgpool-II node received on IPC interface is forwarded to master watchdog
node "pgslave:9999 Linux pgslave"
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2114: DETAIL:  waiting for the reply...
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2115: LOG:  2 watchdog nodes are configured for lifecheck
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2115: LOG:  watchdog nodes ID:0 Name:"pgmaster:9999 Linux pgmaster"  =====> watchdog-node-0
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2115: DETAIL:  Host:"pgmaster" WD Port:9000 pgpool-II port:9999
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2115: LOG:  watchdog nodes ID:1 Name:"pgslave:9999 Linux pgslave"    =====> watchdog-node-1
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2115: DETAIL:  Host:"pgslave" WD Port:9000 pgpool-II port:9999
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2112: LOG:  master watchdog node "pgslave:9999 Linux pgslave" returned status for 2 backend nodes  =====> pgslave为watchdog-主
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2112: LOG:  backend:0 is set to down status
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2112: DETAIL:  backend:0 is DOWN on cluster master "pgslave:9999 Linux pgslave"
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2112: LOG:  Setting up socket for 0.0.0.0:9999
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2112: LOG:  Setting up socket for :::9999
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2115: LOG:  watchdog lifecheck trusted server "pgmaster" added for the availability check
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2115: LOG:  watchdog lifecheck trusted server "pgslave" added for the availability check
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2112: LOG:  find_primary_node_repeatedly: waiting for finding a primary node
Oct 23 19:07:23 pgmaster pgpool: 2021-10-23 19:07:23: pid 2112: LOG:  find_primary_node: standby node is 1
Oct 23 19:07:24 pgmaster pgpool: 2021-10-23 19:07:24: pid 2116: LOG:  failed to create watchdog heartbeat receive socket.    ==========> watchdog 心跳接收 socket创建失败
Oct 23 19:07:24 pgmaster pgpool: 2021-10-23 19:07:24: pid 2116: DETAIL:  setsockopt(SO_BINDTODEVICE) requies root privilege  ==========> SO_BINDTODEVICE 绑定失败,权限不足,需要root权限
Oct 23 19:07:24 pgmaster pgpool: 2021-10-23 19:07:24: pid 2116: LOG:  set SO_REUSEPORT option to the socket
Oct 23 19:07:24 pgmaster pgpool: 2021-10-23 19:07:24: pid 2116: LOG:  creating watchdog heartbeat receive socket.
Oct 23 19:07:24 pgmaster pgpool: 2021-10-23 19:07:24: pid 2116: DETAIL:  set SO_REUSEPORT
Oct 23 19:07:24 pgmaster pgpool: 2021-10-23 19:07:24: pid 2117: LOG:  creating socket for sending heartbeat                 ==========>  sending heartbeat socket创建
Oct 23 19:07:24 pgmaster pgpool: 2021-10-23 19:07:24: pid 2117: DETAIL:  setsockopt(SO_BINDTODEVICE) requires root privilege =========> SO_BINDTODEVICE绑定失败,权限不足,需要root权限
Oct 23 19:07:24 pgmaster pgpool: 2021-10-23 19:07:24: pid 2117: LOG:  set SO_REUSEPORT option to the socket
Oct 23 19:07:24 pgmaster pgpool: 2021-10-23 19:07:24: pid 2117: LOG:  creating socket for sending heartbeat
Oct 23 19:07:24 pgmaster pgpool: 2021-10-23 19:07:24: pid 2117: DETAIL:  set SO_REUSEPORT
Oct 23 19:07:24 pgmaster pgpool: 2021-10-23 19:07:24: pid 2112: LOG:  find_primary_node: standby node is 1
Oct 23 19:07:25 pgmaster pgpool: 2021-10-23 19:07:25: pid 2112: LOG:  find_primary_node: standby node is 1


查找关于pgpool的处理过程,重点了解一下健康检查机制和failover切换:

pgpool健康检查:
通过创建pgpool到后端数据库服务的连接实施健康检查
如果连接创建失败,会抛出异常,进而跳转到统一的异常处理点,如果超过重试次数,将后端降级,并最终调用 pgpool.conf 配置文件中的 failover_command 处理

pgpool failover切换:
切换前会再次确认后端状态,如无效,更新后端的 backend_status 为 CON_DOWN
获取第一个状态正常的后端作为 new_master
杀掉所有子进程(pgpool可以可靠的切断所有来自客户端的连接,隔离故障节点)
对down掉的后端执行 pgpool.conf 配置文件里设置的 failover_command
如果down掉的是 primary,搜索新的 primary,即第一个执行 "SELECT pg_is_in_recovery()" 返回不是t的后端
重启所有子进程
发送 restart 通知给 worker 进程
通知 PCP 子进程 failover 处理完毕
发送 restart 通知给 pcp 进程


找到官方相关的说明:
https://www.pgpool.net/docs/pgpool-II-3.5.4/doc/pgpool-zh_cn.html
看门狗进程由 pgpool-II 自动启动/停止,也就是说,没有单独的命令来启动/停止它。
看门狗功能启动时必须拥有管理员权限(root) 来控制虚拟 IP 接口。 方法之一是使用 root 权限启动 pgpool-II。
不过,考虑安全原因,推荐通过设置设置自定义命令 if_up_cmd、 if_up_cmd 和 if_up_cmd 为使用 sudo 或者 setuid 的方法。
在等待到所有的 pgpool-II 启动后,内置的存活监测将启动。

我的pgpool-II-12服务以及是root启动的,应该没有问题
再仔细检查 pgpool.conf 配置中和虚拟网卡命令相关的配置,找到相关配置,我最初配置的为:
if_up_cmd = '/usr/bin/sudo /sbin/ip addr add $_IP_$/24 dev ens160 label ens160:0'
if_down_cmd = '/usr/bin/sudo /sbin/ip addr del $_IP_$/24 dev ens160'
arping_cmd = '/usr/bin/sudo /usr/sbin/arping -U $_IP_$ -w 1 -I ens160'

可疑点:
1)我的Centos7没有配置sudo,无法使用sudo
2)配置使用的命令为 ip addr,但我最初授权的是 ifconfig 命令

修改后(主、备):
if_up_cmd = '/sbin/ip addr add $_IP_$/24 dev ens160 label ens160:0'
if_down_cmd = '/sbin/ip addr del $_IP_$/24 dev ens160'
arping_cmd = '/usr/sbin/arping -U $_IP_$ -w 1 -I ens160'

修改重启主、备节点的pgpool服务:
# systemctl restart pgpool-II-12 

查看主/备节点VIP网卡(只漂移出现在一个节点上),VIP终于出现了:

[root@pgslave ~]# ifconfig 
ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.100.94  netmask 255.255.255.0  broadcast 192.168.100.255
        inet6 fe80::cdc8:40af:873b:1a8a  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:b1:7b:88  txqueuelen 1000  (Ethernet)
        RX packets 155408  bytes 31033309 (29.5 MiB)
        RX errors 0  dropped 10  overruns 0  frame 0
        TX packets 81868  bytes 9703412 (9.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens160:0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.100.95  netmask 255.255.255.0  broadcast 0.0.0.0
        ether 00:50:56:b1:7b:88  txqueuelen 1000  (Ethernet)

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0


接下来测试一下pgpool-II能否故障迁移看能否正常访问

重启一个节点(pgslave):
# ifconfig
# systemctl  status pgpool-II-12
# systemctl restart pgpool-II-12


另外一个节点上(gpmaster)访问VIP,业务仍然能正常访问

$ psql  -h192.168.100.95 -p9999 -Upostgres
postgres=# show pool_nodes;
 node_id | hostname | port |   status   | lb_weight |  role   | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change  
---------+----------+------+------------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
 0       | gpmaster | 5432 | quarantine | 0.500000  | standby | 0          | false             | 0                 |                   |                        | 2021-10-23 21:22:42
 1       | pgslave  | 5432 | up         | 0.500000  | standby | 0          | true              | 0                 |                   |                        | 2021-10-23 21:24:51
(2 rows)

发现一种新的状态:quarantine
官方解释:
From Pgpool-II V4.1 onward, if the watchdog-leader node fails to build the consensus for primary backend node failover and the primary backend node gets into a quarantine state, then it resigns from its leader/coordinator responsibilities and lowers its wd_priority for next leader election and let the cluster elect some different new leader.


等过了一段时间由再查询状态:

postgres=# show pool_nodes;
 node_id | hostname | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change  
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+---------------------
 0       | gpmaster | 5432 | down   | 0.500000  | standby | 0          | false             | 0                 |                   |                        | 2021-10-23 21:27:26
 1       | pgslave  | 5432 | up     | 0.500000  | standby | 0          | true              | 0                 |                   |                        | 2021-10-23 21:24:51
(2 rows)

虽然VIP的问题解决了,但是2个standby的问题还是没有解决。


排查过程中遇到的其他报错问题:
pcp_detach_node & pcp_attach_node

-bash-4.2$ pcp_detach_node -n 0 -U postgres
Password: 
ERROR: connection to socket "/tmp/.s.PGSQL.9898" failed with error "No such file or directory"

执行时报错,tmp目录下的socket临时文件不存在了,重启PostgreSQL服务后(会重新生成对应的PID临时socket文件)

再次执行解关联:
-bash-4.2$ pcp_detach_node -n 0 -U postgres
Password: 
ERROR:  invalid degenerate backend request, node id : 0 status: [3] is not valid for failover

报另外一个错误:node id : 0 status: [3] is not valid for failover
网上没有找到相关资料,怀疑和pgpool主节点node0有关,查看 pgpool --help 帮助信息,有一个参数引起我的注意:
$ pgpool --help
-n, --dont-detach   Don't run in daemon mode, does not detach control tty
应该是默认启动的时候、设置了禁止detach操作"-n"的缘故。先暂停放弃解除、重新再关联的尝试,估计该方案也未必能解决我的问题,继续寻找其他解决方案。

step4:查看系统日志
# vi /var/log/message
检查是否有相关错误信息,发现有一条:
LOG:  failed to create watchdog heartbeat receive socket.

另外还发现/var/log/pgpool-II-12/目录下生成了一个状态文件:
# cat /var/log/pgpool-II-12/pgpool_status 
down
up

网上找到相关说明:
启动 pgpool-II 时,如果 pgpool_status 文件存在,pgpool-II 将从 pgpool_status 文件中读取后端状态(up/down)。
如果你想在 pgpool-II 启动时忽略 pgpool_status 文件,在 /etc/sysconfig/pgpool 的启动选项 OPTS 中添加“-D”

查看 pgpool 帮助,关注到几个参数:
$ pgpool --help
-n, --dont-detach   Don't run in daemon mode, does not detach control tty
-C: Clear query cache oidmaps when memqcache_method is memcached(If shmem, discards whenever pgpool starts.)
-D: Discard pgpool_status file and do not restore previous status

$ cat /etc/sysconfig/pgpool-II-12
OPTS=" -n -D"

显然启动参数中已经加了-D参数了,应该也不是这个状态文件、历史状态导致的问题。后来按照网上的方法执行:
$ pgpool stop 
$ pgpool -C -D 
问题还是存在。
注意:pgpool启动的服务没法通过systemctl管理,命令不要混用。

step5)
$ pg_controldata|grep cluster
Database cluster state:               in production

发现/var/log/pgpool-II-12/下有个pgpool_status状态文件:
-bash-4.2$ ls -l /var/log/pgpool-II-12/
total 4
-rw-r--r-- 1 postgres postgres 8 Oct 23 13:16 pgpool_status

查看状态文件内容:
-bash-4.2$ cat /var/log/pgpool-II-12/pgpool_status 
down
up
-bash-4.2$ 

查看pgpool-II-12服务详情(包括所有进程) & PostgreSQL服务的详情(包括所有进程):
pgmaster节点:
-bash-4.2$ systemctl status pgpool-II-12
● pgpool-II-12.service - PGPool-II Middleware Between PostgreSQL Servers And PostgreSQL Database Clients
   Loaded: loaded (/usr/lib/systemd/system/pgpool-II-12.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2021-10-22 22:42:08 CST; 13h ago
 Main PID: 14393 (pgpool)
   CGroup: /system.slice/pgpool-II-12.service
           ├─14393 /usr/pgpool-12/bin/pgpool -f /etc/pgpool-II-12/pgpool.conf -n -D
           ├─14395 pgpool: watchdog
           ├─14402 pgpool: lifecheck
           ├─14403 pgpool: heartbeat receiver
           ├─14405 pgpool: heartbeat sender
           ├─14485 pgpool: health check process(0)
           ├─14486 pgpool: health check process(1)
           ├─14530 pgpool: PCP: wait for connection request
           ├─14531 pgpool: worker process
           ├─14541 pgpool: wait for connection request
           ├─..... ......
           ├─14579 pgpool: wait for connection request
           └─15711 pgpool: wait for connection request
-bash-4.2$ 
-bash-4.2$ systemctl  status postgresql-12
● postgresql-12.service - PostgreSQL 12 database server
   Loaded: loaded (/usr/lib/systemd/system/postgresql-12.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2021-10-22 22:43:25 CST; 13h ago
     Docs: https://www.postgresql.org/docs/12/static/
  Process: 14457 ExecStartPre=/usr/pgsql-12/bin/postgresql-12-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
 Main PID: 14463 (postmaster)
   CGroup: /system.slice/postgresql-12.service
           ├─14463 /usr/pgsql-12/bin/postmaster -D /var/lib/pgsql/12/data/
           ├─14465 postgres: logger   
           ├─14467 postgres: checkpointer   
           ├─14468 postgres: background writer   
           ├─14469 postgres: walwriter   
           ├─14470 postgres: autovacuum launcher   
           ├─14471 postgres: archiver   
           ├─14472 postgres: stats collector   
           ├─14473 postgres: logical replication launcher   
           └─14474 postgres: walsender replica 192.168.100.94(56716) streaming 0/2F002228       

pgslave节点:
$ systemctl status pgpool-II-12
-bash-4.2$ systemctl status pgpool-II-12
● pgpool-II-12.service - PGPool-II Middleware Between PostgreSQL Servers And PostgreSQL Database Clients
   Loaded: loaded (/usr/lib/systemd/system/pgpool-II-12.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2021-10-22 22:42:48 CST; 12h ago
 Main PID: 12004 (pgpool)
   CGroup: /system.slice/pgpool-II-12.service
           ├─12004 /usr/pgpool-12/bin/pgpool -f /etc/pgpool-II-12/pgpool.conf -n -D
           ├─12006 pgpool: watchdog
           ├─12013 pgpool: lifecheck
           ├─12014 pgpool: heartbeat receiver
           ├─12015 pgpool: heartbeat sender
           ├─12016 pgpool: wait for connection request
           ├─..... ......
           ├─12048 pgpool: wait for connection request
           ├─12860 pgpool: PCP: wait for connection request
           ├─12862 pgpool: health check process(0)
           ├─12863 pgpool: health check process(1)
           ├─12866 pgpool: worker process
           ├─18992 pgpool: wait for connection request
           ├─..... ......
           ├─19000 pgpool: wait for connection request
           ├─22690 ping -q -c3 pgmaster
           └─22691 ping -q -c3 pgslave

-bash-4.2$
-bash-4.2$ systemctl status postgresql-12
● postgresql-12.service - PostgreSQL 12 database server
   Loaded: loaded (/usr/lib/systemd/system/postgresql-12.service; enabled; vendor preset: disabled)
   Active: active (running) since Fri 2021-10-22 22:43:16 CST; 13h ago
     Docs: https://www.postgresql.org/docs/12/static/
  Process: 12100 ExecStartPre=/usr/pgsql-12/bin/postgresql-12-check-db-dir ${PGDATA} (code=exited, status=0/SUCCESS)
 Main PID: 12107 (postmaster)
   CGroup: /system.slice/postgresql-12.service
           ├─12107 /usr/pgsql-12/bin/postmaster -D /var/lib/pgsql/12/data/
           ├─12110 postgres: logger   
           ├─12111 postgres: startup   recovering 00000001000000000000002F
           ├─12112 postgres: checkpointer   
           ├─12113 postgres: background writer   
           ├─12114 postgres: stats collector   
           └─12149 postgres: walreceiver   streaming 0/2F002228


到此,已经可以通过VIP:9999访问数据库了。但最终两个节点状态都是 standby,以及主节点(node0)的 status = down 的问题,没有定位解决,还需要继续定位
......
过了几天以后,重新检查配置,各种尝试,最终两个节点都是 standby 状态的问题解决了。详细原因已经理不清了。最终正确的配置,已经在前面部署过程中的参数配置中进行了纠正。


=========================================

三、pgpool-II常用命令

> 查看pgpool命令帮助
$ pgpool -h 

> pgpool-II的启动、关闭、重新加载
注意:pgpoll-II的顺序:启动时先主再备、关闭时先备再主


1)systemctl方式启动、关闭
$ systemctl status pgpool-II-12
$ systemctl start pgpool-II-12
$ systemctl stop  pgpool-II-12


2)pgpool方式启动、关闭
pgpool  #不加任何参数直接启动
pgpool -n -d > /tmp/pgpool.log 2>&1 &  #启动后台运行、启用debug模式输出调试信息(debug日志输出到/tmp/pgpool.log)

pgpool [-m {s[mart]|f[ast]|i[mmediate]}] stop

-m:指定关闭模式,支持三种模式:
smart:等待客户端断开后关闭
fast:不等待客户端断开,立刻关闭
immediate:等同于fast模式

pgpool stop
pgpool -m i stop

3)停止还可以通过pcp_stop_pgpool方式
pcp_stop_pgpool -v -d  -U postgres 

重新加载
pgpool reload

> pgpool连接数据库
可以通过pgpool-II的VIP & pgpool-II的端口(默认为9999)连接
$ psql -hpgmaster -p9999 -Upostgres        # pgpool-master 连接
$ psql -hpgslave -p9999 -Upostgres         # pgpool-slave 连接
$ psql -h192.168.100.95 -p9999 -Upostgres  # pgpool-vip 连接

$ psql -h 192.168.100.100 -p 9999 -d testdb01

> show命令
show pool_version;    #显示pgpoll-II版本信息
show pool_status;     #显示pgpoll-II配置参数(pgpool.conf中的配置参数)
show pool_nodes;      #显示所有已配置的节点(status 0-3。0-该状态仅仅用于初始化,PCP从不显示它。1-节点已启动,还没有连接。2-节点已启动,连接被缓冲。3-节点已关闭)
show pool_processes;  #显示所有pgpoll-II进程的列表
show pool_pools;      #显示pgpoll-II连接池列表

> pcp管理命令
pcp_node_count        #显示数据库节点的总数
pcp_detach_node -n 1  #剔除指定的节点关联
pcp_attach_node -n 1  #增加指定的节点关联
pcp_node_info [-h pg01 -U postgres] 0     #显示指定的节点信息
pcp_watchdog_info -h pg01 -U postgres     #显示pgpoll-II的watchdog状态
pcp_pool_status -h pg01 -U postgres       #显示pgpool.conf中定义的参数值
pcp_proc_count        #显示pgpoll-II子进程ID的列表
pcp_proc_info         #显示pgpoll-II子进程ID的信息。
pcp_promote_node      #指定新节点作为pgpoll-II的主节点
pcp_recovery_node     #在线恢复一个节点
pcp_stop_pgpool       #停止pgpoll-II
pcp_watchdog_info     #显示pgpoll-II的watchdog状态


> 故障迁移failover模拟测试(模拟故障时访问数据库业务不会被终端)
停止服务

服务恢复
pcp_recovery_node -n 0 -d > /tmp/recovery.log    #在正常主节点执行恢复备节点


> 查看pgpool node节点信息(pcp_node_info)
$ pcp_node_info -v -d  -n 0 -U postgres
-bash-4.2$ pcp_node_info -v -d  -n 0 -U postgres
Password: 
DEBUG: recv: tos="m", len=8
DEBUG: recv: tos="r", len=21
DEBUG: send: tos="I", len=6
DEBUG: recv: tos="i", len=71
Hostname               : gpmaster
Port                   : 5432
Status                 : 3
Weight                 : 0.500000
Status Name            : down
Role                   : standby
Replication Delay      : 0
Replication State      : 
Replication Sync State : 
Last Status Change     : 2021-10-22 22:47:53
DEBUG: send: tos="X", len=4
-bash-4.2$ 
-bash-4.2$ 
-bash-4.2$ pcp_node_info -v -d  -n 1 -U postgres 
Password: 
DEBUG: recv: tos="m", len=8
DEBUG: recv: tos="r", len=21
DEBUG: send: tos="I", len=6
DEBUG: recv: tos="i", len=70
Hostname               : pgslave
Port                   : 5432
Status                 : 2
Weight                 : 0.500000
Status Name            : up
Role                   : standby
Replication Delay      : 0
Replication State      : 
Replication Sync State : 
Last Status Change     : 2021-10-23 11:23:09
DEBUG: send: tos="X", len=4
-bash-4.2$ 

> 查看pgpool node节点信息(show pool_nodes)
show pool_nodes;
postgres=# show pool_nodes;
 node_id | hostname | port | status | lb_weight |  role   | select_cnt | load_balance_node | replication_delay | replication_state | replication_sync_state | last_status_change  
---------+----------+------+--------+-----------+---------+------------+-------------------+-------------------+-------------------+------------------------+--------------
 0       | gpmaster | 5432 | down   | 0.500000  | standby | 0          | false             | 0                 |                   |                        | 2021-10-22 22:47:53
 1       | pgslave  | 5432 | up     | 0.500000  | standby | 0          | true              | 0                 |                   |                        | 2021-10-23 11:23:09
(2 rows)

> 查看 pgpool watchdog 信息
$ pcp_watchdog_info -v -d  -U postgres
-bash-4.2$ pcp_watchdog_info -v -d  -U postgres
Password: 
DEBUG: recv: tos="m", len=8
DEBUG: recv: tos="r", len=21
DEBUG: send: tos="W", len=7
DEBUG: recv: tos="w", len=557
Watchdog Cluster Information 
Total Nodes          : 2
Remote Nodes         : 1
Quorum state         : QUORUM EXIST
Alive Remote Nodes   : 1
VIP up on local node : YES
Master Node Name     : pgmaster:9999 Linux pgmaster
Master Host Name     : pgmaster

Watchdog Node Information 
Node Name      : pgmaster:9999 Linux pgmaster
Host Name      : pgmaster
Delegate IP    : 192.168.100.95
Pgpool port    : 9999
Watchdog port  : 9000
Node priority  : 1
Status         : 4
Status Name    : MASTER

Node Name      : pgslave:9999 Linux pgslave
Host Name      : pgslave
Delegate IP    : 192.168.100.95
Pgpool port    : 9999
Watchdog port  : 9000
Node priority  : 1
Status         : 7
Status Name    : STANDBY

DEBUG: send: tos="X", len=4

> 查询连接
SELECT * FROM pg_stat_activity;

> 查询 proc
select proname, prosrc from pg_proc;
select proname, prosrc from pg_proc where proname='xxx';

> 查询是否锁表
select pid from pg_locks where relation=( select oid from pg_class where relname=your_table_name);

> 查询锁
select 
    locked.pid AS locked_pid,
    locker.pid AS locker_pid,
    locked_act.usename AS locked_user,
    locker_act.usename AS locker_user,
    locked.virtualtransaction AS locked_virtualtransaction,
    locked.transactionid AS locked_transactionid,
    relname 
from
    pg_locks locked
    LEFT OUTER JOIN pg_class ON (locked.relation = pg_class.oid),
    pg_locks locker,
    pg_stat_activity locked_act,
    pg_stat_activity locker_act 
where
    locker.granted=true AND
    locked.granted=false AND
    locked.pid=locked_act.pid AND
    locker.pid=locker_act.pid AND
    locked.relation=locker.relation;

> 查看 pgpool 连接池状态
$ pcp_pool_status -v -d  -U postgres

> 获取 pgpool 进程数和进程ID列表
$ pcp_proc_count -v -d  -U postgres

> 查看 pgpool 进程信息
$ pcp_proc_info -v -d  -U postgres

> 执行在线恢复
$ pcp_recovery_node -v -d -h 192.168.100.94 -p 9898 -U postgres  -n 1   #-p 9898为pcp端口

> 从 pgpool 提升一个节点
$ pcp_promote_node --help
$ pcp_promote_node -v -d  -h 192.168.100.94 -p 9898 -U postgres -n 1    #NODEID是从0开始的,-n 1: 指定NODEID为1,提升该节点

> 从 pgpool 分离一个节点
$ pcp_detach_node -n 1 -U postgres

> 给 pgpool 关联一个节点
$ pcp_attach_node -v -d -n 1 -U postgres
$ psql -hpgmaster -p9999 -Upostgres
关联节点后,通过 show pool_nodes;  查看刚关联的节点状态是 status=waiting ,退出重新登录查看状态就正常显示up了。

pcp_attach_node 工具是 pgpool 自带的集群管理工具,pcp_attach_node 工具可以将集群中的节点重新注册到集群中,对于通过 show_pools 显示的 status 状态不正常的 node ,可以尝试通过此工具进行处理。用法如下:

pcp_attach_node --help
pcp_attach_node - attach a node from pgpool-II
Usage:
pcp_attach_node [OPTION...] [node-id]
Options:
  -U, --username=NAME    username for PCP authentication
  -h, --host=HOSTNAME    pgpool-II host
  -p, --port=PORT        PCP port number
  -w, --no-password      never prompt for password
  -W, --password         force password prompt (should happen automatically)
  -n, --node-id=NODEID   ID of a backend node
  -d, --debug            enable debug message (optional)
  -v, --verbose          output verbose messages
  -?, --help             print this help

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐