一:背景
在项目交付中,最头疼的莫过于关系型数据库的高可用,而对于pgsql,由于它协议足够开放,所以不管是开源、闭源的都有不少高可用的方案,例如:开源的pgpool、repmgr等,但是这些高可用方案,或多或少都有不太满足需求的地方,尤其是在管理复杂度上,一线交付工程师需要学习很多知识才能独立管理,造成了方案的不可行,几经测试,最后才发现微软收购的citus 开发的pg_auto_failover,基本满足业务对高可用需求以及一线对管理复杂的需求,而更进一步,pg_auto_failover 与微软在10月份把企业版本citus data一起,更能形成一套分布式的高可用pgsql方案。
二:pgsql pg_auto_failover架构

三、相关文档:
https://github.com/citusdata/pg_auto_failover/tree/main/docs
1、在安装pgsql高可用之前,对pg_auto_failover说明点:
\1) pg_auto_failover需要pg开启ssl
2)需要btree_gist 插件(不用关心,他自己会load进去)
3)pg_autoctl得配置文件位于:如果重装,需要关注是否要清理这个配置(pg_auto_failover安装后隐藏的配置文件)
[postgres@mdb01v ~]$ pg_autoctl show file --pgdata /data1/citusdata/pgsqlmonitor/
File | Path
Config | /home/postgres/.config/pg_autoctl/data1/citusdata/pgsqlmonitor/pg_autoctl.cfg
Pid | /tmp/pg_autoctl/data1/citusdata/pgsqlmonitor/pg_autoctl.pid
4)pg_auto_failover默认开启synchronous_commit,所以写入性能一般,如果需要提升性能,需要在pgsql 设置 synchronous_commit=local(注:该参数可以不全局修改,按照会话、用户修改也可以 ,如:alter role fast_and_loose set synchronous_commit to local;)
四、编译安装
以下已centos7.9 安装pgsql高可用为例
git clone https://github.com/citusdata/pg_auto_failover.git
yum -y install postgresql12-contrib
yum -y install postgresql12-libs
yum -y install postgresql12-server
yum -y install postgresql12
yum -y install llvm5.0-devel
yum -y install centos-release-scl-rh
yum -y install llvm-toolset-7-clang
yum -y install pam-devel
yum -y install readline-devel
yum -y install libicu-devel
yum -y install libxslt-devel
yum -y install krb5-devel
yum -y install openssl-devel
wget https://download.postgresql.org/pub/repos/yum/12/redhat/rhel-7-x86_64/postgresql12-devel-12.8-1PGDG.rhel7.x86_64.rpm--no-check-certificate
rpm -ivh postgresql12-devel-12.8-1PGDG.rhel7.x86_64.rpm
export PG_CONFIG=/usr/pgsql-12/bin/pg_config
make
make install
2、添加环境变量:/usr/pgsql-12/bin (注意:postgres账户)
五、搭建集群:
注:
已三台机器
mdb01v.cpp、
mdb02v.cpp 、
mdb03v.cpp
三台机器为例
1、规划相关目录
1)monitor节点(mdb01v.cpp):
mkdir -p /data1/citusdata/pgsqlmonitor
chown -R postgres:postgres /data1/citusdata/
\2) data节点(mdb02v.cpp、mdb03v.cpp):
mkdir -p /data1/citusdata/pgsqldata
chown -R postgres:postgres /data1/citusdata/
2、搭建 (以下为su - postgres用户)
以下安装为非后台安装,注意观察输出的错误信息
1)搭建monitor节点
pg_autoctl create monitor --pgdata /data1/citusdata/pgsqlmonitor --pgport 5432 --hostname mdb01v.cpp --auth trust --ssl-self-signed
\2) data1:
pg_autoctl create postgres --pgdata /data1/citusdata/pgsqldata --pgport 5432 --hostname mdb02v.cpp --auth trust --ssl-self-signed --monitor 'postgres://autoctl_node@mdb01v.cpp:5432/pg_auto_failover?sslmode=require' --run
3)data2:
pg_autoctl create postgres --pgdata /data1/citusdata/pgsqldata --pgport 5432 --hostname mdb03v.cpp --auth trust --ssl-self-signed --monitor 'postgres://autoctl_node@mdb01v.cpp:5432/pg_auto_failover?sslmode=require' --run
3、确定是否OK
在monitor节点
pg_autoctl show state --pgdata /data1/pgsqlmonitor/ (主从状态)
pg_autoctl show uri --pgdata /data1/pgsqlmonitor/ (业务链接的参数)
4、生成随机器启动文件(3台机器)
1)monitor节点:
pg_autoctl -q show systemd --pgdata /data1/citusdata/pgsqlmonitor/ > pgautofailovermonitor.service
mv /home/postgres/pgautofailovermonitor.service /usr/lib/systemd/system/
systemctl enable pgautofailovermonitor.service
2)data节点
pg_autoctl -q show systemd --pgdata /data1/citusdata/pgsqldata/ > pgautofailoverdata.service
切到root
mv /home/postgres/pgautofailoverdata.service /usr/lib/systemd/system/
systemctl enable pgautofailoverdata.service
5、添加测试库、用户、授权
主库:
postgres=# create database music2;
CREATE DATABASE
postgres=# create user muser password 'music2test';
CREATE ROLE
postgres=# grant all privileges on database music2 to muser;
GRANT
[postgres@mdb03v ~]$ cat /data1/citusdata/pgsqldata/pg_hba.conf
host music2 muser 10.95.58.81/32 md5
reload配置:在mdb02v、mdb03v 执行pg_autoctl reload --pgdata /data1/citusdata/pgsqldata/
6、在10.95.58.81对pgsql主库进行可用性测试
mdb02v.cpp 进行写入数据并测试
sysbench --pgsql-host=mdb02v.cpp --pgsql-port=5432 --pgsql-user=* --pgsql-password=** --pgsql-db=music2 --db-driver=pgsql /usr/share/sysbench/oltp_common.lua --threads=24 --tables=24 --table_size=1000000 prepare
sysbench --pgsql-host=mdb02v.cpp --pgsql-port=5432 --pgsql-user=* --pgsql-password=** --pgsql-db=music2 --db-driver=pgsql /usr/share/sysbench/oltp_read_only.lua --threads=8 --tables=24 --table_size=100000 --time=600 run
五、暴力测试
在有systbench下压力
1)三台机器全部关机 1分钟后,启动slave、在启动master,主从正常:测试通过
2)slave节点关机 1 分钟后再启动 主从正常:测试通过
3)master节点关机 1分钟再启动 主从正常:测试通过
4)monitor节点异常无法启动:我们看到在pg_auto_failover架构中,monitor存在单点情况,当机器异常并无法启动后,我们需要对monitor进行迁移,只需要两步:
a:在每个node节点上取消注册信息: pg_autoctl disable monitor --pgdata pgdata/ --force
b:注册到新的monitor节点 pg_autoctl enable monitor --pgdata pgdata/ 'postgres://autoctl_node@new.cpp:5432/pg_auto_failover?sslmode=require'
六:业务使用
在以上的测试中,我们能看到pgsql+pg_auto_failover 形成了一套完整的高可用架构,但是当主库宕机后,业务是不是需要修改配置,链接到新的主库呢?答案是否定的,如果这样,一线工程师肯定是不满意的。这里我们在pgsql driver上用到target_session_attrs参数,这个参数是pgsql10引进的一个很好的功能,它可以让driver(libpg)对pg支持一个连接字符串,指定多个host+port,依次尝试每个host+port直到成功建立连接,我们可以把主库IP、从库IP同时配置上(这里是不是看到了mongodb的身影呢?),当然,随着发展target_session_attrs的参数也在变化,且在java、python、golang不同语言中,参数稍微有一些变化,这需要关注一下。
可参考:https://www.postgresql.org/docs/14/libpq-connect.html#LIBPQ-PARAMKEYWORDS
target_session_attrs:This option determines whether the session must have certain properties to be acceptable. It's typically used in combination with multiple host names to select the first acceptable alternative among several hosts. There are six modes:
any (default):any successful connection is acceptable
read-write:session must accept read-write transactions by default (that is, the server must not be in hot standby mode and the default_transaction_read_only parameter must be off)
read-only:session must not accept read-write transactions by default (the converse)
primary:server must not be in hot standby mode
standby:server must be in hot standby mode
prefer-standby:first try to find a standby server, but if none of the listed hosts is a standby server, try again in any mode




