前言

PostgreSQL自身只提供了流复制的功能,想要搭建高可用集群的话,需要借助第三方库pgpool来实现。pgpool之间互相通信,并且监控PostgreSQL数据库,当有一个数据库节点宕机时,可以保证整个集群可用。如果是primary节点宕机,则让另外的standby节点提升为primary节点。如果是standby节点宕机,则对整体集群无影响。以此来保证数据库集群的高可用。

为了保证pgpool自身的高可用,所以pgpool也可以搭建多个节点,分为master节点和standby节点。并且设置一个vip(虚拟IP),用虚拟ip对外提供服务,当master节点宕机时,该虚拟IP漂移到其他机器上,保证pgpool的高可用。

本文讲解使用pgpool搭建PostgreSQL高可用集群的步骤,前提是已经在各个节点安装了PostgreSQL数据库,并且配置好了异步流复制。

安装PostgreSQL和配置异步流复制,之前写过两篇文章,可以查看之前的教程。

  • PostgreSQL版本:12.2
  • pgpool版本:4.1

主机规划

主机名IP角色端口作用
pg1192.168.211.142主节点PostgreSQL:5432
pgpool:9999
pcp:9898<br/>wathchdog:9000
运行数据库和pgpool
pg2192.168.211.145备节点PostgreSQL:5432
pgpool:9999
pcp:9898<br/>wathchdog:9000
运行数据库和pgpool
pg3192.168.211.144备节点PostgreSQL:5432
pgpool:9999
pcp:9898<br/>wathchdog:9000
运行数据库和pgpool
vip192.168.211.215虚拟IP端口为pgpool的端口:9999该IP要选一个局域网中实际并不存在的IP

因为在虚拟机里面做的测试,虚拟机给分配的IP不连续,这个不用管,按照自己的实际情况配置即可。

搭建异步流复制

异步流复制比较简单,不涉及到pgpool,请参考之前的教程。

如果这一步通不过的话,就不要往下看了,因为这一步是基础。

加载pgpool_recovery插件

# 在主节点上执行下面的命令,加载pgpool_recovery插件
psql template1
create extension pgpool_recovery;

设置免密登录

配置别名

为方便以后的配置,给每个节点设置别名,分别编辑3个节点的/etc/hosts文件,并补充以下内容:

192.168.211.142 pg1
192.168.211.145 pg2
192.168.211.144 pg3
192.168.211.215 vip

设置免密登录

需要设置3个节点之间postgres用户的免密登录,下面以pg1节点的设置为例,设置pg2、pg3节点对pg1节点postgres用户的免密登录,其他两个节点设置方法类似,按需修改以下节点名称即可。

# 注意切换到postgres用户执行

# 生成id_rsa.pub
ssh-keygen
# 一路回车

# 上传到需要免密的节点上
ssh-copy-id -i ~/.ssh/id_rsa.pub postgres@pg2
ssh-copy-id -i ~/.ssh/id_rsa.pub postgres@pg3

# 测试
# 如果设置正确的话,此处不需要输入密码
ssh postgres@pg2 uptime
ssh postgres@pg3 uptime

pg2节点设置免密登录:

# 注意切换到postgres用户执行

# 生成id_rsa.pub
ssh-keygen
# 一路回车

# 上传到需要免密的节点上
ssh-copy-id -i ~/.ssh/id_rsa.pub postgres@pg1
ssh-copy-id -i ~/.ssh/id_rsa.pub postgres@pg3

# 测试
# 如果设置正确的话,此处不需要输入密码
ssh postgres@pg1 uptime
ssh postgres@pg3 uptime

pg3节点设置免密登录:

# 注意切换到postgres用户执行

# 生成id_rsa.pub
ssh-keygen
# 一路回车

# 上传到需要免密的节点上
ssh-copy-id -i ~/.ssh/id_rsa.pub postgres@pg1
ssh-copy-id -i ~/.ssh/id_rsa.pub postgres@pg2

# 测试
# 如果设置正确的话,此处不需要输入密码
ssh postgres@pg1 uptime
ssh postgres@pg2 uptime

安装pgpool

每个节点上均需要安装pgpool,此处使用的版本是pgpool-II-4.1.0.tar.gz,安装包可自行下载。

pg1节点安装pgpool

以一个节点为例,需要执行如下命令:

# root用户执行以下命令
mkdir /usr/local/pgpool

# 将pgpool上传到任意目录
tar -xzvf pgpool-II-4.1.0.tar.gz
./configure --prefix=/usr/local/pgpool
make -j$(nproc)
make install

# 如果下面的语句报错,pg_config找不到,请将pgsql/bin路径加入到环境变量中
# export PATH=/usr/local/pgsql/bin:$PATH
cd src/sql
make
make install

chown -R postgres.postgres /usr/local/pgpool/

配置postgres用户的环境变量

# 以postgres用户执行
# 注意此处,不要覆盖了之前搭建异步流复制时pg的环境变量,应该在上面追加。

vim ~/.bashrc

export PGPOOL_HOME=/usr/local/pgpool
export PATH=$PGPOOL_HOME/bin:$PATH

pg2节点安装pgpool

安装步骤相同,不再赘述。

pg2节点安装pgpool

安装步骤相同,不再赘述。

配置pgpool

此处配置比较复杂,3个节点都需要配置,所以一般在1个节点上配好之后,把需要配置的东西拷贝到其他节点上,然后稍微做一些修改。

每个节点均需要配置4个配置文件、3个脚本、2个可执行程序。

4个配置文件为:

  • pool_hba.conf
  • pcp.conf
  • pool_passwd
  • pgpool.conf

3个脚本为:

  • failover.sh
  • follow-master.sh
  • pgpool_remote_start

2个可执行程序为:

  • ip
  • arping

下面以pg1节点为例,将pg1节点配置好之后,将配置文件同步到其他节点,稍作修改。

pg1节点配置

配置文件(4个)

配置文件官方均给出了模板,如果上面安装pgpool正确的话,模板文件在/usr/local/pgpool/etc路径下面。可以把模板文件拷贝一份,然后修改。

  1. pool_hba.conf

    pool_hba.conf是对pgpool验证的,类似与PostgreSQL的pg_hba.conf。

    # 用postgres用户执行以下命令
    cd /usr/local/pgpool/etc
    
    cp pool_hba.conf.sample pool_hba.conf
    
    vim pool_hba.conf
    
    # 添加如下行
    # 此处配置的为trust,表示不用密码,在对外提供服务的互联网上,请把trust设置成md5.
    host    all         all         0/0                   trust
    host    replication all         0/0                   trust
  2. pcp.conf

    该配置文件用来验证pcp工具的用户名和密码,pcp工具用来查看节点信息、节点恢复、节点的添加与删除等。

    # 用postgres用户执行以下命令
    cd /usr/local/pgpool/etc
    
    cp pcp.conf.sample pcp.conf
    
    # 使用pg_md5生成配置的用户名密码
    pg_md5 postgres
    e8a48653851e28c69d0506508fb27fc5
    
    #编辑pcp.conf文件,添加如下内容
    postgres:e8a48653851e28c69d0506508fb27fc5
    
  3. pool_passwd

    # 用postgres用户执行以下命令
    cd /usr/local/pgpool/etc
    
    pg_md5 -p -m -u postgres pool_passwd
    #输入数据库登录用户postgres密码,生成pool_passwd文件
    
  4. pgpool.conf(核心文件)

    该文件为pgpool最重要的文件,配置的时候一定要小心。

    下面仅列出了该文件中需要修改的配置项,不需要修改的请保持默认配置即可。

    # 用postgres用户执行以下命令
    cd /usr/local/pgpool/etc
    
    cp pgpool.conf.sample-master-slave pgpool.conf
    
    # 使用vim编辑
    vim pgpool.conf
    
    # 需要修改的配置如下:
    
    #------------------------------------------------------------------------------
    # CONNECTIONS
    #------------------------------------------------------------------------------
    # - pgpool Connection Settings -
    listen_addresses = '*'
    port = 9999
    
    # - pgpool Communication Manager Connection Settings -
    pcp_listen_addresses = '*'
    pcp_port = 9898
    
    # - Backend Connection Settings -
    # 此处填写各个pg数据库的配置参数,注意端口和路径要根据自己的实际情况填写
    backend_hostname0 = 'pg1'
    backend_port0 = 5432
    backend_weight0 = 1
    # 此处填写pg1数据库的数据存储路径
    backend_data_directory0 = '/home/postgres/pgdata'
    backend_flag0 = 'ALLOW_TO_FAILOVER'
    
    backend_hostname1 = 'pg2'
    backend_port1 = 5432
    backend_weight1 = 1
    # 此处填写pg2数据库的数据存储路径
    backend_data_directory1 = '/home/postgres/pgdata'
    backend_flag1 = 'ALLOW_TO_FAILOVER'
    
    backend_hostname2 = 'pg3'
    backend_port2 = 5432
    backend_weight2 = 1
    # 此处填写pg3数据库的数据存储路径
    backend_data_directory2 = '/home/postgres/pgdata'
    backend_flag2 = 'ALLOW_TO_FAILOVER'
    
    # - Authentication -
    enable_pool_hba = on
    # 此处的pool_passwd不是密码,而是文件的名字,见上面同章节的第3个配置文件。
    pool_passwd = 'pool_passwd'
    
    
    #------------------------------------------------------------------------------
    # FILE LOCATIONS
    #------------------------------------------------------------------------------
    pid_file_name = '/usr/local/pgpool/pgpool.pid'
    
    #------------------------------------------------------------------------------
    # LOAD BALANCING MODE
    #------------------------------------------------------------------------------
    load_balance_mode = on
    
    #------------------------------------------------------------------------------
    # MASTER/SLAVE MODE
    #------------------------------------------------------------------------------
    master_slave_mode = on
    # 因为是流复制模式,所以此处修改成stream
    master_slave_sub_mode = 'stream'
    
    # - Streaming -
    sr_check_period = 10
    sr_check_user = 'postgres'
    sr_check_password = 'postgres'
    sr_check_database = 'postgres'
    
    # - Special commands -
    # 此处配置的脚本具体内容见下面脚本小节
    follow_master_command = '/usr/local/pgpool/follow_master.sh %d %h %p %D %m %H %M %P %r %R %N %S'
    
    #------------------------------------------------------------------------------
    # HEALTH CHECK GLOBAL PARAMETERS
    #------------------------------------------------------------------------------
    health_check_period = 10
    health_check_timeout = 20
    health_check_user = 'postgres'
    health_check_password = 'postgres'
    health_check_database = 'postgres'
    
    
    #------------------------------------------------------------------------------
    # FAILOVER AND FAILBACK
    #------------------------------------------------------------------------------
    # 此处配置的脚本具体内容见下面脚本小节
    failover_command = '/usr/local/pgpool/failover.sh %d %h %p %D %m %H %M %P %r %R %N %S'
    
    
    #------------------------------------------------------------------------------
    # ONLINE RECOVERY
    #------------------------------------------------------------------------------
    recovery_user = 'postgres'
    recovery_password = 'postgres'
    
    #------------------------------------------------------------------------------
    # WATCHDOG
    #------------------------------------------------------------------------------
    use_watchdog = on
    ping_path = '/bin'
    wd_hostname = 'pg1'
    wd_port = 9000
    
    # - Virtual IP control Setting -
    # 虚拟ip,要求局域网中无机器使用该ip
    delegate_IP = '192.168.211.215'
    
    # 此处几个参数比较重要,容易出错,需要配置ip、arping两个程序的命令,当发生vip漂移的时候会调用下面的命令
    # 1、首先查看ip和arping在系统里面是否存在,然后检查其路径是否正确。如果不存在要安装对应的包
    # 2、$_IP_$字段对应的就是上面的delegate_IP字段,不用变,
    # 3、ens33为对应的网络连接,使用ip命令可以查看自己的网络信息,一般为eth0,但是我的网络连接为ens33,按照自己实际情况的填写。
    # 4、原来的配置文件中有/usr/bin/sudo前缀,记得删掉。
    if_cmd_path = '/sbin'
    if_up_cmd = '/sbin/ip addr add $_IP_$/24 dev ens33'
    if_down_cmd = '/sbin/ip addr del $_IP_$/24 dev ens33'
    arping_path = '/usr/bin'
    arping_cmd = '/usr/bin/arping -U $_IP_$ -w 1 -I ens33'
    
    
    # - Lifecheck Setting -
    # -- common --
    # 此处网络连接按照自己的实际情况填写
    wd_monitoring_interfaces_list = 'ens33'
    
    # -- heartbeat mode --
    wd_heartbeat_port = 9694
    heartbeat_destination0 = 'pg2'
    heartbeat_destination_port0 = 9694
    # 根据自己的实际网络连接填写
    heartbeat_device0 = 'ens33'
    
    heartbeat_destination1 = 'pg3'
    heartbeat_destination_port1 = 9694
    # 根据自己的实际网络连接填写
    heartbeat_device1 = 'ens33'
    
    # -- query mode --
    wd_lifecheck_user = 'postgres'
    wd_lifecheck_password = 'postgres'
    
    # - Other pgpool Connection Settings -
    # 注意此处,官方给的模板中other_pgpool_port0的端口为5432,一定要修改成自己端口,此处为9999,否则pgpool集群会起不来。
    other_pgpool_hostname0 = 'pg2'
    other_pgpool_port0 = 9999
    other_wd_port0 = 9000
    
    other_pgpool_hostname1 = 'pg3'
    # 注意此处,官方给的模板中other_pgpool_port1的端口为5432,一定要修改成自己端口,此处为9999,否则pgpool集群会起不来。
    other_pgpool_port1 = 9999
    other_wd_port1 = 9000
    

脚本(3个)

3个脚本文件协助出现故障在线恢复时使用,failover.sh,follow_master.sh,pgpool_remote_start,3个文件官方均给出了模板,在模板上修改即可。

  1. failover.sh

    # 使用postgres用户执行
    cd /usr/local/pgpool
    cp etc/failover.sh.sample ./failover.sh
    
    vim failover.sh
    
    # 修改大约35行位置的PGHOME变量为自己安装PostgreSQL数据库的位置
    # 根据自己的实际情况修改
    PGHOME=/usr/local/pgsql
    
    # 保存退出
    # 添加可执行权限
    chmod a+x failover.sh
    
  2. follow_master.sh

    # 使用postgres用户执行
    cd /usr/local/pgpool
    cp etc/follow_master.sh.sample ./follow_master.sh
    
    vim follow_master.sh
    
    # 修改大约34行位置的PGHOME,PGPOOL_PATH两个变量的值
    # 根据自己的实际情况修改
    PGHOME=/usr/local/pgsql
    PGPOOL_PATH=/usr/local/pgpool/bin
    
    # 保存退出
    # 添加可执行权限
    chmod a+x follow_master.sh
    
  3. pgpool_remote_start

    需要特别注意此文件,此文件是放置在数据目录下的,上面2个脚本文件放置在了pgpool目录下,路径不同。而且这个配置文件不带.sh后缀。

    # 使用postgres用户执行
    cd ~/pgdata
    cp /usr/local/pgpool/etc/pgpool_remote_start.sample ./pgpool_remote_start
    
    vim pgpool_remote_start
    
    # 修改大约第10行,PGHOME变量的值
    # 根据自己的实际情况修改
    PGHOME=/usr/local/pgsql
    
    # 保存退出
    # 添加可执行权限
    chmod a+x pgpool_remote_start
    

可执行程序(2个)

  1. ip

    使用此命令可以建立虚拟ip,也可以查看ip。

    # 此处的配置对应pgpool.conf文件中的if_up_cmd、if_down_cmd两个字段
    
    # 赋予setuid权限,
    # 此处使用root执行
    chmod u+s /sbin/ip
    
    # 使用postgres用户来执行
    # 使用if_up_cmd中的命令来测试
    /sbin/ip addr add 192.168.211.215/24 dev ens33
    
    # 使用root用户来检查
    ip a
    
    # 查看是否有ens33下面是否多了192.168.211.215IP地址,或者ping以下192.168.211.215,看是否能ping通
    # 如果没有的话,请再次检查执行步骤是否少了某一步。
    
    # 使用root或者postgres用户均可
    # 使用if_down_cmd来删除vip
    /sbin/ip addr del 192.168.211.215/24 dev ens33
    
  2. arping

    此命令有的操作系统没有安装,可能需要安装,请先检查

    # 此处的配置对应pgpool.conf文件中的arping_cmd字段
    
    # 检查是否存在arping命令,如果没有的话,先安装
    apt-get install iputils-arping
    
    # 赋予setuid权限,
    # 此处使用root执行
    chmod u+s /usr/bin/arping
    

pg2节点配置

pg2节点的配置同pg1节点,共包含4个配置文件,3个脚本文件,2个可执行程序。

把上述pg1上配置好的配置文件,脚本文件用scp或者其他工具传到pg2节点上,然后做对应的修改即可。

注意点:

  • 配置文件、脚本文件可以传,但是可执行程序最好安装,不要传输。
  • 配置文件、脚本的所有者均为postgres,并且脚本文件应赋予可执行权限,可执行程序赋予设置用户setuid位。
  • 仅需修改pgpool.conf配置文件,其他配置文件,脚本文本不需要做任何修改。

pgpool.conf文件具体修改内容如下:

# 此处仅展示与pg1节点上pgpool.conf配置不同的部分,其余部分配置相同,不在此展示
#------------------------------------------------------------------------------
# WATCHDOG
#------------------------------------------------------------------------------

wd_hostname = 'pg2'

# 以下字段中需要注意网卡,确保和本机器上的网口一致
# if_up_cmd、if_down_cmd、arping_cmd、wd_monitoring_interfaces_list、heartbeat_device0、heartbeat_device1

heartbeat_destination0 = 'pg1'
heartbeat_destination1 = 'pg3'

other_pgpool_hostname0 = 'pg1'
other_pgpool_hostname1 = 'pg3'

pg3节点配置

pg3节点的配置同pg1节点,共包含4个配置文件,3个脚本文件,2个可执行程序。

把上述pg1上配置好的配置文件,脚本文件用scp或者其他工具传到pg3节点上,然后做对应的修改即可。

注意点:

  • 配置文件、脚本文件可以传,但是可执行程序最好安装,不要传输。
  • 配置文件、脚本的所有者均为postgres,并且脚本文件应赋予可执行权限,可执行程序赋予设置用户setuid位。
  • 仅需修改pgpool.conf配置文件,其他配置文件,脚本文本不需要做任何修改。

pgpool.conf文件具体修改内容如下:

# 此处仅展示与pg1节点上pgpool.conf配置不同的部分,其余部分配置相同,不在此展示
#------------------------------------------------------------------------------
# WATCHDOG
#------------------------------------------------------------------------------

wd_hostname = 'pg3'

# 以下字段中需要注意网卡,确保和本机器上的网口一致
# if_up_cmd、if_down_cmd、arping_cmd、wd_monitoring_interfaces_list、heartbeat_device0、heartbeat_device1

heartbeat_destination0 = 'pg1'
heartbeat_destination1 = 'pg2'

other_pgpool_hostname0 = 'pg1'
other_pgpool_hostname1 = 'pg2'

启动

启动PostgreSQL

查看数据库是否在启动状态,如果没有在启动状态,则先要启动数据库

# 3个节点上均需要执行下面的命令,启动数据库
# 使用postgres用户执行

# 检查数据库进程是否存在
ps -ef | grep postgres

# 如果没有启动,则启动数据库
pg_ctl -l logfile-pg start

对数据库异步流复制状态进行检查

# 使用postgres用户执行
# 查看数据库是主库还是备库 

# 方法一
# 使用命令pg_controldata
pg_controldata | grep cluster

# 主库输出如下所示
Database cluster state:               in production

# 备库输出如下所示
Database cluster state:               in archive recovery


# 方法二,使用sql命令
psql
select pg_is_in_recovery();

# 主库输出如下所示
 pg_is_in_recovery 
-------------------
 f
(1 row)

# 备库输出如下所示
 pg_is_in_recovery 
-------------------
 t
(1 row)


# 方法三
# 在主库执行
select client_addr,state,sync_state from pg_stat_replication;

# 输出内容如下:
client_addr   |   state   | sync_state 
-----------------+-----------+------------
 192.168.211.144 | streaming | async
 192.168.211.142 | streaming | async
(2 rows)

启动pgpool

分别在3个节点上启动pgpool,不过最好先启动一台,然后查看日志,看是否存在问题,如果不存在问题,再启动另一台,如果有问题的话,先排查问题。

如果修改了pgpool.conf,记得其他节点要做同步的修改。

# postgres用户执行
pgpool -n -d -D > logfile-pgpool 2>&1 &

# 检查该节点是否有问题,如果有问题,pgpool进程会退出
tailf logfile-pgpool

稍等一会儿,如果第一个节点pgpool没有退出,且日志文件里面没有异常的话(日志里面打印连接失败不算异常,因为其他的pgpool节点还没有启动),则依次启动pg2、pg3节点的pgpool。

检查状态

依次执行下述检查,看是否存在问题。范围依次缩小。

  1. 使用PostgreSQL节点状态

    # -h指定连接哪个IP地址,这里指定连接vip
    # -p指定连接的端口,这里指定pgpool的端口
    # -U指定连接的用户
    # -d指定连接的数据库,此处不用添加
    psql -h vip -p 9999 -Upostgres
    
    # 查看所有节点
    show pool_nodes;
    

    如果配置没问题的话,会正确显示3个PostgreSQL数据库节点,其中pg1节点为primary,pg2、pg3为standby节点;3个节点的状态均为up,如果此处为down的话,说明节点挂掉了,需要进一步排查原因:

    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       | pg1      | 5432 | up     | 0.333333  | primary | 1          | true              | 0                 |                   |                        | 2022-08-19 17:09:49
     1       | pg2      | 5432 | up     | 0.333333  | standby | 0          | false             | 0                 |                   |                        | 2022-08-19 17:09:49
     2       | pg3      | 5432 | up     | 0.333333  | standby | 0          | false             | 0                 |                   |                        | 2022-08-19 17:09:49
    
  2. 检查pgpool节点状态

    # 使用pcp工具,查看所有pgpool节点的状态
    pcp_watchdog_info
    

    如果正常的话,会输出下面的内容,pg1节点为master节点,pg2、pg3节点为standby节点。

    3 NO pg1:9999 Linux Kylin pg1
    
    pg3:9999 Linux Kylin pg3 9999 9000 7 STANDBY
    pg1:9999 Linux Kylin pg1 9999 9000 4 MASTER
    pg2:9999 Linux Kylin pg2 9999 9000 7 STANDBY
    
  3. 检查PostgreSQL进程状态

    # 如果某个节点的数据库状态不正常,可以去该节点查看进程是否存在
    ps -ef | grep postgres
    
    # 如果不存在,需要进一步查看日志文件检查原因
    # 启动时用-l命令指定的日志文件
    vim logfile-pg
    
    # 问题解决后,使用pcp_recovery_node进行在线恢复该节点
    # 此处注意不要直接用pg_ctl启动,否则pgpool不认该节点
    # -h指定要恢复的节点
    # -U指定使用的账户
    # 0指定pgpool中该节点的node_id,此值请查看show pool_nodes的输出的第一列,请根据自己的实际情况恢复指定的节点
    pcp_recovery_node -h pg2 -Upostgres 0
    
  4. 检查pgpool进程状态

    # 如果pcp_watchdog_info输出的pgpool节点状态不正常的话,可以去该节点查看进程是否存在
    ps -ef | grep pgpool
    
    # 如果不存在,需要进一步查看日志文件检查原因
    # 启动时用>重定向的日志文件
    vim logfile-pgpool
    
    # 问题解决后,可以使用命令直接重启pgpool
    # 记得重启前先删除原有的日志文件,避免以后干扰排查问题
    rm -rf logfile-pgpool
    pgpool -n -d -D > logfile-pgpool 2>&1 &
    

测试

PostgreSQL数据库宕机

  1. 模拟主库宕机

    # 查看主节点在哪台机器上
    psql -h vip -p 9999 -Upostgres
    show pool_nodes;
    
    # 显示pg1为primary
    
    # 去pg1节点上,执行命令,停止PostgreSQL数据库,模拟数据库主节点宕机
    pg_ctl -m fast stop
    
    # 然后再查看所有节点的状态
    psql -h vip -p 9999 -Upostgres
    show pool_nodes;
    
    # 此时显示pg1、pg3均为down的状态,
    # pg1节点因为手动停掉,所以显示为宕机
    # pg3节点因为原来连接的主库pg1,现在pg1停掉了,所以连接失败了,也没有重新连接上新主库pg2,所以状态也不正常
    
    # 恢复pg1
    # 因为pg1之前为主节点,所以恢复pg1之前,先要配置成新主库pg2的备节点
    cd ~/pgdata
    touch standby.signal
    vim postgresql.auto.conf
    
    # 添加如下内容
    # 其中的pg2为主库所在节点
    primary_conninfo = 'user=postgres passfile=''/home/postgres/.pgpass'' host=pg2 port=5432 sslmode=disable sslcompression=0 gssencmode=disable krbsrvname=postgres target_session_attrs=any'
    
    # 此处可以先在pg1节点上手动启动一下数据库试试
    # 如果报错的话,先解决错误
    # 我碰到了requested timeline 2 is not a child of this server's history
    # 解决方法是把pg1节点下的pgdata/pg_wal/下的00000002.history删掉即可
    
    # 然后通过pcp_recovery_node重新恢复该节点
    pcp_recovery_node -h pg1 -Upostgres 0
    
    # 输入密码
    # 输出结果
    pcp_recovery_node -- Command Successful
    
    # 此时再查看节点的状态,pg1节点被正常拉起
    psql -h vip -p 9999 -Upostgres
    show pool_nodes;
    
    # 同样的方法恢复pg3
    # 先把pg3正常停止
    pg_ctl -m fast stop
    
    # 修改连接的配置文件
    # 将其中的配置指向新的主节点pg2
    cd ~/pgdata
    vim postgresql.auto.conf
    
    #删除日志并重启测试
    cd ~/pgdata
    rm -rf ~/logfile-pg
    pg_ctl -l logfile-pg start
    
    # 如果能正常启动的话,关闭即可,然后通过pcp_recovery_node来恢复,如果启动不了的话,根据日志文件,解决问题
    pcp_recovery_node -h pg3 -Upostgres 2
    
    # 此时再查看节点的状态,pg3节点被正常拉起
    psql -h vip -p 9999 -Upostgres
    show pool_nodes;
    
  2. 模拟备库宕机

    # 此时备节点为pg1、pg3,随便停一个即可
    # 该场景同上面恢复pg3,不再赘述
    

pgpool节点宕机

  1. 模拟主节点宕机

    # 使用pcp_watchdog_info命令查看主节点
    pcp_watchdog_info
    
    # 输入密码,显示主节点在pg1上
    pg3:9999 Linux Kylin pg3 9999 9000 7 STANDBY
    pg1:9999 Linux Kylin pg1 9999 9000 4 MASTER
    pg2:9999 Linux Kylin pg2 9999 9000 7 STANDBY
    
    # 查看ip确认
    # 在pg1上执行
    # 从输出内容看到了vip节点的ip
    ip a
    
    # 强制关闭pgpool,模拟pgpool节点宕机
    pgpool -m fast stop
    
    # 使用pcp_watchdog_info查看所有pgpool节点的状态
    # 显示pg1上的pgpool为宕机状态,先在主节点在pg2上
    pg3:9999 Linux Kylin pg3 9999 9000 7 STANDBY
    pg1:9999 Linux Kylin pg1 9999 9000 10 SHUTDOWN
    pg2:9999 Linux Kylin pg2 9999 9000 4 MASTER
    
    # 尝试连接vip节点
    # 此时再查看节点的状态,pg3节点被正常拉起
    psql -h vip -p 9999 -Upostgres
    show pool_nodes;
    
    # 正常
    
    # 恢复pg1上的pgpool
    rm -rf logfile-pgpool
    pgpool -n -d -D > logfile-pgpool 2>&1 &
    
    # 使用pcp_watchdog_info命令查看节点的状态
    # pg1节点显示loading?
    pg3:9999 Linux Kylin pg3 9999 9000 7 STANDBY
    pg1:9999 Linux Kylin pg1 9999 9000 1 LOADING
    pg2:9999 Linux Kylin pg2 9999 9000 4 MASTER
    
  2. 模拟备节点宕机

    # 使用pcp_watchdog_info命令查看备节点
    pcp_watchdog_info
    
    # 输入密码,显示主节点在pg1上
    pg3:9999 Linux Kylin pg3 9999 9000 7 STANDBY
    pg1:9999 Linux Kylin pg1 9999 9000 1 LOADING
    pg2:9999 Linux Kylin pg2 9999 9000 4 MASTER
    
    # 停止pg3节点
    # 强制关闭pgpool,模拟pgpool节点宕机
    pgpool -m fast stop
    
    # 恢复pg3上的pgpool
    rm -rf logfile-pgpool
    pgpool -n -d -D > logfile-pgpool 2>&1 &
    
    # 使用pcp_watchdog_info查看节点的状态
    # 一切恢复正常
    pg3:9999 Linux Kylin pg3 9999 9000 7 STANDBY
    pg1:9999 Linux Kylin pg1 9999 9000 7 STANDBY
    pg2:9999 Linux Kylin pg2 9999 9000 4 MASTER
    

其他注意事项

  1. 数据恢复

    如果节点宕机后,和主节点数据不同步,可以使用pg_rewind命令进行差量拉取,仅仅拉取差量部分的数据。

    # 根据需要修改参数
    # 此命令要求postgresql.conf配置文件中wal_log_hints = on
    # 所以最好在安装好数据库时就配置好该参数
    
    pg_rewind -D $PGDATA --source-server='host=pg1 user=postgres password=postgres'
    
  2. 关闭节点

    # 关闭postgresql
    pg_ctl -m fast stop
    
    # 关闭pgpool
    pgpool -m fast stop
  3. vip节点

    vip节点的建立需要最低两个pgpool节点,如果只启动一个pgpool,则无法ping通vip节点ip,节点漂移最低需要3个节点,允许1个宕机。

  4. 当主库变成备库后

    • 新建空的standby.signal文件
    • 在postgresql.auto.conf中,填写primary_conninfo信息,为新主库的连接信息
    • 启动新备库
  5. 当备库变成新主库后

    • 把postgresql.auto.conf中的primary_conninfo注释掉,不然它下次启动的时候还以为自己是备库
    • 把standby.signal删掉

标签: none

添加新评论