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

倾情打造PostgreSQL高可用系列(一):pg_auto_failover搭建

前言

记录一下pg_auto_failover
单备节点搭建过程。

什么是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.

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

当前版本官方文档介绍了架构主要有三种。分别是单备节点架构
双备节点架构
三个备节点,一个异步节点的多备架构

单备节点架构

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

  • 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.93pg_auto_failover Monitor
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

用这种方式安装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

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

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

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

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

yum install postgresql13-contrib

再次执行,就成功了.

但是还是没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

执行输出如下:

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

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

在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

此时日志显示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

搭建问题总结

  • pg_auto_failover
    搭建比较简单,在搭建中出现失败的情况,可以直接在控制台上看输出日志,结合日志能够快速定位出问题。
  • pg_auto_failover
    搭建过程中最好先关闭防火墙,不然会出现连接不上加入不了集群的情况。
  • 官方下载的包没有安装postgresql13-contrib
    ,这会导致在部署的时候出现没有btree_gist.control
    的情况。
  • 在配置systemd服务自启动的时候,需要关闭selinux,不然重启后服务也不会启动。

最后祝大家搭建顺利。


文章转载自励志成为PostgreSQL大神,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论