暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PostgreSQL高可用系列:pg_auto_failover搭建

原创 sg1234 2023-06-12
2099




概述 :什么是pg_auto_failover?

pg_auto_failover is an extension for PostgreSQL that monitors and manages failover for a postgres clusters. It is optimised for simplicity and correctness.

这是官方的介绍,它只是一个扩展,提供监控和管理集群中的故障转移。为了简单和正确性,进行了优化。

当前版本官方文档介绍了架构主要有三种。


分别是

1 单备节点架构

2 双备节点架构

3 三个备节点,一个异步节点的多备架构


单备节点架构

img

如官方架构图,假设这个架构需要三个节点。

  • PostgreSQL主节点

  • PostgreSQL第二节点,使用流复制进行同步

  • 一个既能充当见证者又充当协调者的pg_auto_failover Monitor节点。

pg_auto_failover监视器实现一个状态机,并依赖于PostgreSQL内核来管理HA。例如:当检测到备用节点不可用时,或者报告备库同步滞后, WAL超过定义的阈值时(默认为1个WAL文件或16MB,可在Monitor上查看 pgautofailover.promote_wal_log_threshold GUC参数的设置,Montior会从主节点的synchronous_standby_names参数中移除备节点。在备节点恢复正常运行之前,不允许进行故障转移和切换操作,以防止数据丢失。

那么今天我们就安装一下 单备节点架构 体验一下。


环境准备

主机名IP地址初始角色
paf1192.168.56.93Monitor
paf2192.168.56.94主节点
paf3192.168.56.95从节点


首先我们克隆3套Centos 8虚拟机,用于本次环境的安装,规划好IP地址和用途如上面表格所示。

systemctl stop firewalld.service && systemctl disable firewalld.service

hostnamectl set-hostname paf1
hostnamectl set-hostname paf2
hostnamectl set-hostname paf3

分别在三套主机上配置hostname,关闭防火墙,修改host文件。

vi /etc/hosts
192.168.56.93 paf1
192.168.56.94 paf2
192.168.56.95 paf3

1. 安装pg_auto_failover插件

我们使用官方提供的安装脚本配置,然后安装完成后,会自动给装上pg13,还有pg_auto_failover插件.

paf1-paf3三个节点都安装

curl https://install.citusdata.com/community/rpm.sh | sudo bash
sudo yum install -y pg-auto-failover14_13

[postgres@paf1 ~]$ /usr/pgsql-13/bin/pg_autoctl --version
pg_autoctl version 1.4.1
pg_autoctl extension version 1.4
compiled with PostgreSQL 13.1 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.3.1 20191121 (Red Hat 8.3.1-5), 64-bit
compatible with Postgres 10, 11, 12, and 13

img

用这种方式安装pg-auto-failover14_13,自动就给我们安装postgresql 13 server版软件.


2. 初始化pg_auto_failover Monitor

接下来我们要在paf1节点上配置Monitor,首先需要配置postgres的环境变量。

paf1-paf3都需要设置

export PGDATA=/var/lib/pgsql/13/data
export PGHOME=/usr/pgsql-13
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/pgsql-13/bin

运行pg_autoctl create monitor 创建Monitor

pg_autoctl create monitor --pgdata /var/lib/pgsql/13/data \
--pgport 5432 \
--hostname paf1 \
--auth trust \
--ssl-self-signed

img

执行两次各种报错啊.需要强行加上--auth trust和--ssl-self-signed参数.这些都是和安全相关的.

加上后再次执行,这次成功了.

img

但是还是报错找不到btree_gist.control文件.执行ps -ef也看不到postgres的进程.

这里主要原因是没安装postgresql13-contrib包的原因,手动安装一下.

yum install postgresql13-contrib

再次执行,就成功了.

img

但是还是没postgres进程,仔细观察最后是一步Stop pg_autoctl了.

需要使用--run参数,才会启动

[postgres@paf1 ~]$ nohup pg_autoctl create monitor \
--pgdata /var/lib/pgsql/13/data \
--pgport 5432 \
--hostname paf1 \
--auth trust \
--ssl-self-signed \
--run \
&



3. 验证Monitor节点

启动Monitor后,也会启动一个管理的数据库,我们可以登录进去看一下.自动创建了一个pg_auto_failover 数据库,和2个角色,还有一个pgautofailover的扩展.同时可以看到自动创建了btree_gist扩展,这也解释了前面我们一直没成功的原因.

[postgres@paf1 ~]$ psql
psql (13.1)
Type "help" for help.

postgres=# \l
                                    List of databases
      Name       | Owner   | Encoding |   Collate   |   Ctype   |   Access privileges  
------------------+----------+----------+-------------+-------------+-----------------------
pg_auto_failover | autoctl | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
postgres         | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |
template0       | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres         +
                |         |         |             |             | postgres=CTc/postgres
template1       | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres         +
                |         |         |             |             | postgres=CTc/postgres
(4 rows)

postgres=# \c pg_auto_failover
You are now connected to database "pg_auto_failover" as user "postgres".
pg_auto_failover=# \dx
                            List of installed extensions
    Name     | Version |   Schema   |                 Description                  
----------------+---------+------------+-----------------------------------------------
btree_gist     | 1.5     | public     | support for indexing common datatypes in GiST
pgautofailover | 1.4     | public     | pg_auto_failover
plpgsql       | 1.0     | pg_catalog | PL/pgSQL procedural language
(3 rows)

pg_auto_failover=# \du
                                    List of roles
Role name   |                         Attributes                         | Member of
--------------+------------------------------------------------------------+-----------
autoctl     |                                                           | {}
autoctl_node |                                                           | {}
postgres     | Superuser, Create role, Create DB, Replication, Bypass RLS | {}

最后退出来运行pg_autoctl show uri 命令可以看到monitor的连接字符串,等下在创建Primary Node和Secondary Node的时候需要用到.

[postgres@paf1 ~]$ pg_autoctl show uri
Type | Name | Connection String
-----------+---------+-------------------------------
monitor | monitor | postgres://autoctl_node@paf1:5432/pg_auto_failover?sslmode=require
formation | default |



4. 创建PrimaryNode节点

在PAF2主机上运行pg_autoctl create postgres 命令创建PrimaryNode

pg_autoctl create postgres \
--hostname paf2 \
--auth trust \
--ssl-self-signed \
--monitor 'postgres://autoctl_node@paf1:5432/pg_auto_failover?sslmode=require' \
--run

执行输出如下:

img

此时日志显示pg_autoctl service is running, current state is "single"

而此时PAF1节点上的Monitor的日志也会显示

img

在PAF1节点主机上执行pg_autoctl查看状态,此时显示single。

[postgres@paf2 ~]$ pg_autoctl show state
Name | Node | Host:Port | LSN | Reachable | Current State | Assigned State
-------+-------+------------+-----------+-----------+---------------------+--------------------
node_1 | 1 | paf2:5432 | 0/1613338 | yes | single | single



5. 创建Secondary节点

接下来我们在PAF3主机上创建Secondary节点。执行命令和Primary Node类似。

pg_autoctl create postgres \
--hostname paf3 \c
--auth trust \
--ssl-self-signed \
--monitor 'postgres://autoctl_node@paf1:5432/pg_auto_failover?sslmode=require' \
--run

img

此时日志显示New state for node 1 "node_1" (paf2:5432): primary ➜ primary

从细节上看,是先通过pg_basebackup创建了备库,接着建立了复制关系。

在主机上执行pg_autoctl查看状态,这时候就可以看到我们的主库和从库了。

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




6. 使用systemd来进行自启动

上述集群搭好之后,我们要防止主机重启之后,还需要我们手动通过pg_autoctl来启动集群,这就很麻烦。不过还好pg_auto_failover 命令自带了生成systemd服务这个功能。让我们来看一看怎么实施。

首先在Monitor节点上操作

[postgres@paf1 ~]$ pg_autoctl -q show systemd --pgdata /var/lib/pgsql/13/data > pgautofailover.service

[postgres@paf1 ~]$ cat pgautofailover.service
[Unit]
Description = pg_auto_failover

[Service]
WorkingDirectory = /var/lib/pgsql
Environment = 'PGDATA=/var/lib/pgsql/13/data'
User = postgres
ExecStart = /usr/pgsql-13/bin/pg_autoctl run
Restart = always
StartLimitBurst = 0

[Install]
WantedBy = multi-user.target


将命令生成的pgautofailover.service 文件部署到/usr/lib/systemd/system/


su - root

[root@paf1 pgsql]# mv pgautofailover.service /usr/lib/systemd/system/
[root@paf1 system]# setenforce 0
[root@paf1 system]# systemctl daemon-reload
[root@paf1 system]# systemctl enable pgautofailover.service
Created symlink /etc/systemd/system/multi-user.target.wants/pgautofailover.service → /usr/lib/systemd/system/pgautofailover.service.

注意:这里需要临时禁用一下selinux,不然服务创建不了


然后就可以停止Monitor服务,通过操作系统systemctl命令启动了

su - postgres
[postgres@paf1 ~]$ pg_autoctl stop monitor

su - root
[root@paf1 system]#systemctl start pgautofailover.service


接下来在Primary Node和Seondary Node节点上操作。

pg_autoctl -q show systemd --pgdata /var/lib/pgsql/13/data > postgresprimary.service

[postgres@paf2 ~]$ cat postgresprimary.service
[Unit]
Description = pg_auto_failover

[Service]
WorkingDirectory = /var/lib/pgsql
Environment = 'PGDATA=/var/lib/pgsql/13/data'
User = postgres
ExecStart = /usr/pgsql-13/bin/pg_autoctl run
Restart = always
StartLimitBurst = 0

[Install]
WantedBy = multi-user.target

su - root

[root@paf2 ~]# mv /var/lib/pgsql/postgresprimary.service /usr/lib/systemd/system/
[root@paf2 ~]# systemctl daemon-reload
[root@paf2 ~]# setenforce 0
[root@paf2 ~]# systemctl enable postgresprimary.service
Created symlink /etc/systemd/system/multi-user.target.wants/postgresprimary.service → /usr/lib/systemd/system/postgresprimary.service.

su - postgres
[postgres@paf2 ~]$ pg_autoctl stop

su - root
[root@paf2 ~]# systemctl start postgresprimary.service


所有的操作全部做完之后,全部停止。然后reboot服务器重新看一遍是否自动成功带起来集群。

结果我发现没带起来,直接服务都没启动。看来还是selinux的问题啊。

vi /etc/selinux/config
SELINUX=disabled

将selinux彻底禁止,再次重启所有主机,这次正常了。

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



7. 搭建问题总结

  • pg_auto_failover 搭建比较简单,在搭建中出现失败的情况,可以直接在控制台上看输出日志,结合日志能够快速定位出问题。

  • pg_auto_failover 搭建过程中最好先关闭防火墙,不然会出现连接不上加入不了集群的情况。

  • 官方下载的包没有安装postgresql13-contrib ,这会导致在部署的时候出现没有btree_gist.control 的情况。

  • 在配置systemd服务自启动的时候,需要关闭selinux,不然重启后服务也不会启动。



「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论