Postgresql+Keepalived高可用方案

一、变更计划与方案

1.1 概述
现有postgresql数据库为单一数据库,没有备份数据,为保证数据安全正常运行,现将给定的3台服务器,组成一个1主2从的高可用架构。
1.2 基本信息

主机名 IP地址 服务器角色 系统信息 数据库目录
72_123 192.168.247.123 Postgresql主节点 Red Hat7.7 /data
72_124 192.168.247.124 Postgresql从节点 Red Hat7.7 /data
72_125 192.168.247.125 Postgresql从节点 Red Hat7.7 /data

1.3实施计划
先将247.124和247.125设置为247.123的从库,然后安装Keepalived 高可用组件,搭建高可用架构

二、实施方案

2.1 各节点安装postgres (root用户)
准备postgresql-11-10.tar.gz软件包
https://www.postgresql.org/ftp/source/v11.10/
安装相关依赖包

yum -y install readline readline-devel zlib zlib-devel

创建用户、安装目录、数据库目录

useradd  postgres
password postgres

mkdir /opt/pg11/
mkdir /data/
chown -R postgres:postgres /opt/pg11/
chown -R postgres:postgres /data/

解压并编译安装

tar -xvf postgresql-11.10.tar.gz 
cd postgresql-11.10/
./configure --prefix=/opt/pg11/
make world
make install-word

设置环境变量

su - postgres
vim .bashrc
export LD_LIBRARY_PATH=/opt/pg11/lib
export PGDATA=/data/
export PGHOME=/opt/pg11/
export PATH=$PATH:/opt/pg11/bin/

初始化数据库

/opt/pg11/bin/initdb -D /data/   

修改配置文件(参数值根据服务器配置填写)

listen_addresses = '*' 
port = 5432 
max_connections = 100 
shared_buffers = 128MB
dynamic_shared_memory_type = posix 
wal_level = replica 
max_wal_size = 1GB  
min_wal_size = 80MB
track_commit_timestamp = on    
log_timezone = 'PRC'
datestyle = 'iso, mdy'
timezone = 'PRC'
lc_messages = 'en_US.UTF-8'                
lc_monetary = 'en_US.UTF-8'    
lc_numeric = 'en_US.UTF-8'    
lc_time = 'en_US.UTF-8' 
default_text_search_config = 'pg_catalog.english'

启动数据库

pg_ctl -D /data/ -l logfile start

如果是新建数据库可以将以下主从同步一同配置后再启动数据库

2.2 主库配置(postgres用户配置)
创建replicator 用户进行主从同步

create role replicator with login replication password 'replicator'; 

修改pg_hba.conf,允许replicator 用户来同步

host    all             all             192.168.247.0/24        md5  
host    replication     replicator      192.168.247.0/24        md5     

修改postgresql.conf,修改或添加以下内容

wal_level = replica  #热备模式
max_wal_senders= 10  #设置最达流复制链接,控制主库最多可以有多少个并发standby数据库)
wal_keep_segments = 512   #重要配置(配置保存wal日志大小) 
wal_sender_timeout = 60s 

重启数据库生效

pg_ctl restart 

2.3 从库配置(postgres用户配置)
将主库数据拷贝至从库(247.124,247.125)

pg_basebackup -h 192.168.247.123 -D /home/postgres/data/ -F p -X stream -v -P -U replicator 
输入密码:replicator 

修改或添加postgresql.conf以下内容

max_connections = 1100 #一般从库的最大连接数要大于主库
hot_standby = on #说明这台机器不仅仅是用于数据归档,也用于数据查询
max_standby_streaming_delay = 30s #数据流备份的最大延迟时间
wal_receiver_status_interval = 10s #多久向主报告一次从的状态,当然从每次数据复制都会向主报告状态,这里只是设置最长的间隔时间

配置recovery.conf

standby_mode = on    
primary_conninfo = ‘host=192.168.247.123 port=5432 user=replicator password=replicator’
recovery_target_timeline = ‘latest’

启动数据库(247.124,247.125)

pg_ctl start

2.4 安装keepalived(root用户配置)
主节点247.123,从节点247.124,247.125

yum -y install keepalived
touch /etc/keepalived/pg_check.sh
chmod +x /etc/keepalived/pg_check.sh

pg_check.sh脚本

#!/bin/bash
#PG is alive or not?
A=`ps -ef | grep postgres | grep "/opt/pg11/bin/postgres*" |grep -v grep| wc -l`
# where the VIP floats to
B=`ip a | grep 192.168.247.121 | wc -l`
# the slave  is in a waiting state?
C=`ps -ef | grep postgres | grep 'startup process' |grep -v grep| wc -l`
#the secondary  is positive for linking to the master ?
D=`ps -ef | grep postgres | grep 'receiver' |grep -v grep | wc -l`
#he connection between the master and the slave library is normal?
E=`ps -ef | grep postgres | grep 'sender'  |grep -v grep| wc -l`
#If pg dies, log the message and turn off keepalived
if [ $A -eq 0 ];then
    echo "`date "+%Y-%m-%d--%H:%M:%S"` postgresql stop so vip stop " >> /etc/keepalived/log/check_pg.log
    systemctl stop keepalived
else
        #When the master is dead, the VIP floats to slave, elevating slave's status to make him read and write
        if [ $B -eq 1 -a $C -eq 1 -a $D -eq 0 ];then
                su - postgres -c "/opt/pg11/bin/pg_ctl promote -D /data/"
                echo "`date "+%Y-%m-%d--%H:%M:%S"` standby promote " >> /etc/keepalived/log/check_pg.log
        fi

        #Judge yourself as Lord and lose contact with him
        if [ $B -eq 1 -a $C -eq 0 -a $D -eq 0 -a $E -eq 0 ];then
                                sleep 10
                echo "`date "+%Y-%m-%d--%H:%M:%S"` can't find standby " >> /etc/keepalived/log/check_pg.log
        fi
fi

配置Keepalived日志

vim /etc/sysconfig/keepalived
# Options for keepalived. See `keepalived --help' output and keepalived(8) and
# keepalived.conf(5) man pages for a list of all options. Here are the most
# common ones :
#
# --vrrp               -P    Only run with VRRP subsystem.
# --check              -C    Only run with Health-checker subsystem.
# --dont-release-vrrp  -V    Dont remove VRRP VIPs & VROUTEs on daemon stop.
# --dont-release-ipvs  -I    Dont remove IPVS topology on daemon stop.
# --dump-conf          -d    Dump the configuration data.
# --log-detail         -D    Detailed log messages.
# --log-facility       -S    0-7 Set local syslog facility (default=LOG_DAEMON)

KEEPALIVED_OPTIONS="-D -d -S 0"

修改/etc/rsyslog.conf文件,在末尾添加如下配置

local0.*    /var/log/keepalived.log

重启日志记录服务

systemctl restart rsyslog

查看Keepalived日志

tail -f /var/log/keepalived.log

修改Keepalived配置文件
(主节点247.123)

mv /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
   notification_email {
     **@qq.com
   }
   notification_email_from **@163.com
   smtp_server smtp.163.com
   smtp_connect_timeout 30
   router_id postgres_master
}
vrrp_script check_pg_alived {
    script "/etc/keepalived/pg_check.sh"
    interval 10
    weight 2
}
vrrp_instance VI_1 {
    state MASTER
    interface ens33
    virtual_router_id 66
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1234
    }
      track_script {
        check_pg_alived
     }
    virtual_ipaddress {
        192.168.247.121
    }
}

(从节点247.124,247.125)

! Configuration File for keepalived

global_defs {
   notification_email {
     **@qq.com
   }
   notification_email_from **@163.com
   smtp_server smtp.163.com
   smtp_connect_timeout 30
   router_id postgres_master
}

vrrp_script check_pg_alived {
    script "/etc/keepalived/pg_check.sh"
    interval 10
    fall 5
}

vrrp_instance VI_1 {
    state BACKUP
    nopreempt
    interface ens33
    virtual_router_id 66
    priority 90
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1234
    }
      track_script {
        check_pg_alived
     }
    virtual_ipaddress {
        192.168.247.121
    }
}

所有节点启动keepalived服务,并查看状态(root用户)

systemctl restart keepalived
systemctl enable keepalived
systemctl status keepalived

3 高可用验证(测试环境)

3.1各节点postgres进程正常,keepalived状态正常,查看VIP节点

[root@72-123 keepalived]# ip a |grep ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.247.123/24 brd 192.168.247.255 scope global noprefixroute ens33
inet 192.168.247.121/32 scope global ens33

3.2 主节点宕机模拟

[postgres@72-123 ~]$ pg_ctl stop
waiting for server to shut down....2021-10-23 01:29:37.950 PDT [59281] LOG:  received fast shutdown request
2021-10-23 01:29:37.952 PDT [59281] LOG:  aborting any active transactions
2021-10-23 01:29:37.953 PDT [59281] LOG:  background worker "logical replication launcher" (PID 59288) exited with exit code 1
2021-10-23 01:29:37.953 PDT [59283] LOG:  shutting down
2021-10-23 01:29:37.972 PDT [59281] LOG:  database system is shut down
 done
server stopped

3.3 VIP迁移到从节点

[postgres@72-125 ~]$2021-10-23 01:29:42.846 PDT [62019] FATAL:  could not connect to the primary server: could not connect to server: Connection refused
                Is the server running on host "192.168.247.121" and accepting
                TCP/IP connections on port 5432?
2021-10-23 01:29:47.855 PDT [62052] LOG:  connection received: host=192.168.247.121 port=53342
2021-10-23 01:29:47.856 PDT [62053] LOG:  connection received: host=192.168.247.124 port=59440
2021-10-23 01:29:47.856 PDT [62052] LOG:  replication connection authorized: user=replicator
2021-10-23 01:29:47.857 PDT [62053] LOG:  replication connection authorized: user=replicator
2021-10-23 01:29:47.857 PDT [62051] LOG:  started streaming WAL from primary at 0/A000000 on timeline 1

查看VIP

[postgres@72-125 ~]$ ip a |grep ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.247.125/24 brd 192.168.247.255 scope global noprefixroute ens33
    inet 192.168.247.121/32 scope global ens33

3.4连接测试

[postgres@72-124 ~]$ psql -h 192.168.247.121 -U postres -p 
psql (11.10)
Type "help" for help.
postgres=# 

3.5恢复节点,启动数据库,并启动keepalived服务

[postgres@72-123 ~]$ pg_ctl start
waiting for server to start....2021-10-23 01:37:13.120 PDT [60997] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2021-10-23 01:37:13.120 PDT [60997] LOG:  listening on IPv6 address "::", port 5432
2021-10-23 01:37:13.122 PDT [60997] LOG:  listening on Unix socket "/tmp/.s.PGSQL.5432"
2021-10-23 01:37:13.132 PDT [60998] LOG:  database system was shut down at 2021-10-23 01:29:37 PDT
2021-10-23 01:37:13.134 PDT [60997] LOG:  database system is ready to accept connections
 done
server started
[root@72-123 keepalived]# systemctl start keepalived
[root@72-123 keepalived]# ip a |grep ens33
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 192.168.247.123/24 brd 192.168.247.255 scope global noprefixroute ens33
    inet 192.168.247.121/32 scope global ens33
上一篇:PostgreSQL安装教程(CentOS)


下一篇:PostgreSQL数据库Imgr——Relation Lock