专注,勤学,慎思。戒骄戒躁,谦虚谨慎

just do it

导航

Ubuntu 20 环境下 pg_auto_failover 自动化安装,一分钟快速搭建pg_auto_failover集群

 

1,前提是要对pg_auto_failover的架构和工作原理有着非常清晰的认识,至少手动搭建过3次以上,自动化只是手段不是目的
2,该脚本在Ubuntu 20 下做过详尽的测试,pg17+pg_auto_failover 2.2,可极大简化pg_auto_failover的安装过程,全程自动完成pg_auto_failover的搭建
3,欢迎试用,有建议或者问题请留言

该脚本可以在一分钟之内可以搭建一个完整的pg_auto_failover 集群,展开数据库的下一步工作,而不是浪费大量时间在环境的搭建上。

 

0,环境 

1,先编译好PostgreSQL服务,然后停止相关实例,因为pg_auto_failover初始化的时候会自动重新初始化数据
2,Ubuntu 20,PostgreSQL 17.6,pg_auto_failover 2.2,pg_auto_failover 启动的是会创建数据目录,因此需要关闭各节点已有的PostgreSQL实例(如果有)。
3,下载好pg_auto_failover 安装包,与脚本同一目录
4,先安装Monitor节点,然后依次安装2~N个数据节点,会自动基于Monitor节点创建集群


静态主机映射如下

root@ubuntu11:/usr/local/pg_install_package# cat /etc/hosts
127.0.0.1 localhost
127.0.1.1 ubuntu11

# The following lines are desirable for IPv6 capable hosts
::1     ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters

192.168.152.121 ubuntu11
192.168.152.122 ubuntu12
192.168.152.123 ubuntu13
192.168.152.124 ubuntu14

 

1,monitor节点安装

monitor节点安装脚本,根据情况,仅需修改 #配置变量 部分参数

#!/bin/bash
set -euo pipefail

# 配置变量
PG_VERSION="17"
PG_HOME="/usr/local/pgsql${PG_VERSION}/server"
PG_BASE="/usr/local/pgsql${PG_VERSION}"
PG_DATA="/usr/local/pgsql${PG_VERSION}/pg25432/data"
PAF_DIR="/usr/local/pg_install_package"
PKG_FILE="pg_auto_failover-2.2"
MONITOR_HOSTNAME="ubuntu11"
MONITOR_PORT="25432"
SERVICE_NAME="pgautofailover"

# 自定义 pg_hba 规则,这个是数据节点连接至Monitor节点的访问规则
CUSTOM_HBA_RULES="
# Custom rules for pg_auto_failover
#host    postgres        postgres        192.168.152.0/24      trust
host    pg_auto_failover autoctl_node   192.168.152.0/24       trust
"


echo "=== setup env ==="
export LANG=en_US.utf8
export PGDATA="${PG_DATA}"
export PGHOME="${PG_HOME}"
export PATH="${PG_HOME}/bin:$PATH"
export LD_LIBRARY_PATH="${PG_HOME}/lib"

echo "PGHOME=${PGHOME}"
echo "PATH=${PATH}"

echo "=== uncompress tar ==="
cd "${PAF_DIR}"
tar -xvf "${PKG_FILE}.tar.gz" >/dev/null 2>&1

echo "=== switch into paf source code dir ==="
cd "${PAF_DIR}/${PKG_FILE}"

echo "=== make && make install ==="
make clean >/dev/null 2>&1 || true  
make >/dev/null 2>&1
make install >/dev/null 2>&1

echo "=== chown ==="
chown -R postgres:postgres "${PG_BASE}/"

echo "=== verify install ==="
pg_autoctl --version


echo "=== create monitor node ==="
# check data dir is empty
if [ -d "${PG_DATA}" ] && [ "$(ls -A ${PG_DATA})" ]; then
    echo "Warning: Data directory ${PG_DATA} exists and is not empty."
    read -p "Directory has existing files. Do you want to delete it? (yes/no): " choice
    if [ "$choice" = "yes" ] || [ "$choice" = "y" ]; then
        echo "Force deleting existing data directory..."
        su - postgres -c "pg_autoctl stop --pgdata ${PG_DATA}" >/dev/null 2>&1 || true
        rm -rf "${PG_DATA}"
        echo "Data directory deleted"
    else
        echo "Skipping deletion, exit "
        exit 1  
    fi
else
    echo "Data directory ${PG_DATA} does not exist or is empty, ready to create..."
    mkdir -p "${PG_DATA}"
fi

chown -R  postgres:postgres "${PG_BASE}"
chmod 700 "${PG_BASE}"



echo "=== remove remaining configurations ==="
rm -rf /home/postgres/.local/


echo "=== create monitor node ==="
su - postgres -c "pg_autoctl create monitor \
    --pgdata ${PG_DATA} \
    --auth trust \
    --ssl-self-signed \
    --hostname ${MONITOR_HOSTNAME} \
    --pgport ${MONITOR_PORT}" >/dev/null 2>&1



echo "=== adding custom HBA rules ==="
echo "$CUSTOM_HBA_RULES" >> "${PG_DATA}/pg_hba.conf"


echo "=== create systemd service ==="
pg_autoctl -q show systemd --pgdata "${PG_DATA}" | tee /etc/systemd/system/${SERVICE_NAME}.service >/dev/null
systemctl daemon-reload >/dev/null 2>&1
systemctl enable ${SERVICE_NAME} >/dev/null 2>&1
systemctl start ${SERVICE_NAME} >/dev/null 2>&1
sleep 1


echo "=== check service status ==="
systemctl status ${SERVICE_NAME} --no-pager

echo "=== install completed ==="
echo "Monitor node is running on ${MONITOR_HOSTNAME}:${MONITOR_PORT}"
echo "Check status: systemctl status ${SERVICE_NAME}"

 monitor节点安装日志

root@ubuntu11:/usr/local/pg_install_package# bash paf_monitor_install.sh
=== setup env ===
PGHOME=/usr/local/pgsql17/server
PATH=/usr/local/pgsql17/server/bin:/usr/local/pgsql17/server/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
=== uncompress tar ===
=== switch into paf source code dir ===
=== make && make install ===
=== chown ===
=== verify install ===
pg_autoctl version
pg_autoctl extension version 2.2
compiled with PostgreSQL 17.6 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0, 64-bit
compatible with Postgres 13, 14, 15, 16 and 17
=== create monitor node ===
Warning: Data directory /usr/local/pgsql17/pg25432/data exists and is not empty.
Directory has existing files. Do you want to delete it? (yes/no): yes
Force deleting existing data directory...
Data directory deleted
=== remove remaining configurations ===
=== create monitor node ===
=== append access rule ===
=== Adding custom HBA rules ===
=== create systemd service ===
=== check service status ===
● pgautofailover.service - pg_auto_failover
     Loaded: loaded (/etc/systemd/system/pgautofailover.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2026-05-18 03:17:36 UTC; 1s ago
   Main PID: 1509064 (pg_autoctl)
      Tasks: 14 (limit: 4550)
     Memory: 30.4M
     CGroup: /system.slice/pgautofailover.service
             ├─1509064 /usr/local/pgsql17/server/bin/pg_autoctl run
             ├─1509068 pg_autoctl: start/stop postgres
             ├─1509069 pg_autoctl: monitor listener
             ├─1509098 /usr/local/pgsql17/server/bin/postgres -D /usr/local/pgsql17/pg25432/data -p 25432 -h *
             ├─1509099 postgres: pg_auto_failover monitor: logger
             ├─1509100 postgres: pg_auto_failover monitor: checkpointer
             ├─1509101 postgres: pg_auto_failover monitor: background writer
             ├─1509103 postgres: pg_auto_failover monitor: walwriter
             ├─1509104 postgres: pg_auto_failover monitor: autovacuum launcher
             ├─1509105 postgres: pg_auto_failover monitor: pg_auto_failover monitor
             ├─1509106 postgres: pg_auto_failover monitor: logical replication launcher
             ├─1509107 postgres: pg_auto_failover monitor: pg_auto_failover monitor healthcheck worker postgres
             ├─1509108 postgres: pg_auto_failover monitor: pg_auto_failover monitor healthcheck worker pg_auto_failover
             └─1509110 postgres: pg_auto_failover monitor: autoctl_node pg_auto_failover [local] idle

May 18 03:17:36 ubuntu11 pg_autoctl[1509064]: 03:17:36 1509064 INFO  Started pg_autoctl postgres service with pid 1509068
May 18 03:17:36 ubuntu11 pg_autoctl[1509064]: 03:17:36 1509064 INFO  Started pg_autoctl listener service with pid 1509069
May 18 03:17:36 ubuntu11 pg_autoctl[1509069]: 03:17:36 1509069 INFO   /usr/local/pgsql17/server/bin/pg_autoctl do service listener --pgdata /usr/local/pgsql17/pg25432/data -v
May 18 03:17:36 ubuntu11 pg_autoctl[1509068]: 03:17:36 1509068 INFO   /usr/local/pgsql17/server/bin/pg_autoctl do service postgres --pgdata /usr/local/pgsql17/pg25432/data -v
May 18 03:17:36 ubuntu11 pg_autoctl[1509069]: 03:17:36 1509069 INFO  Managing the monitor at postgres://autoctl_node@ubuntu11:25432/pg_auto_failover?sslmode=require
May 18 03:17:36 ubuntu11 pg_autoctl[1509069]: 03:17:36 1509069 INFO  Reloaded the new configuration from "/home/postgres/.config/pg_autoctl/usr/local/pgsql17/pg25432/data/pg_autoctl.cfg"
May 18 03:17:36 ubuntu11 pg_autoctl[1509098]: 03:17:36 1509098 INFO   /usr/local/pgsql17/server/bin/postgres -D /usr/local/pgsql17/pg25432/data -p 25432 -h *
May 18 03:17:36 ubuntu11 pg_autoctl[1509068]: 03:17:36 1509068 INFO  Postgres is now serving PGDATA "/usr/local/pgsql17/pg25432/data" on port 25432 with pid 1509098
May 18 03:17:37 ubuntu11 pg_autoctl[1509069]: 03:17:37 1509069 INFO  The version of extension "pgautofailover" is "2.2" on the monitor
May 18 03:17:37 ubuntu11 pg_autoctl[1509069]: 03:17:37 1509069 INFO  Contacting the monitor to LISTEN to its events.
=== install completed ===
Monitor node is running on ubuntu11:25432
Check status: systemctl status pgautofailover
root@ubuntu11:/usr/local/pg_install_package#

 

2,data 1节点安装

data 1节点安装脚本,根据具体环境,仅需修改 #配置变量 部分参数

#!/bin/bash
set -euo pipefail

# 配置变量
PG_VERSION="17"
PG_HOME="/usr/local/pgsql${PG_VERSION}/server"
PG_BASE="/usr/local/pgsql${PG_VERSION}"
PG_DATA="/usr/local/pgsql${PG_VERSION}/pg25432/data"
PAF_DIR="/usr/local/pg_install_package"
PKG_FILE="pg_auto_failover-2.2"
MONITOR_HOSTNAME="ubuntu11"
MONITOR_PORT="25432"

NODE_HOSTNAME="ubuntu12"
NODE_PORT="25432"
SERVICE_NAME="pgautofailover"

# 自定义 pg_hba 规则,数据节点对外的访问规则
CUSTOM_HBA_RULES="
# Custom rules for pg_auto_failover
host    postgres        postgres        0.0.0.0/0      scram-sha-256
"


# 监控节点连接字符串
MONITOR_URI="postgres://autoctl_node@${MONITOR_HOSTNAME}:${MONITOR_PORT}/pg_auto_failover?sslmode=require"

echo "=== setup env ==="
export LANG=en_US.utf8
export PGDATA="${PG_DATA}"
export PGHOME="${PG_HOME}"
export PATH="${PG_HOME}/bin:$PATH"
export LD_LIBRARY_PATH="${PG_HOME}/lib"

echo "PGHOME=${PGHOME}"
echo "MONITOR_URI=${MONITOR_URI}"

echo "=== uncompress tar ==="
cd "${PAF_DIR}"
tar -xvf "${PKG_FILE}.tar.gz" >/dev/null 2>&1

echo "=== switch to paf source code dir ==="
cd "${PAF_DIR}/${PKG_FILE}"

echo "=== make && make install ==="
make clean >/dev/null 2>&1 || true  
make >/dev/null 2>&1
make install >/dev/null 2>&1

echo "=== chown ==="
chown -R postgres:postgres "${PG_BASE}/"

echo "=== verify install ==="
pg_autoctl --version



echo "=== create monitor node ==="
# check data dir is empty
if [ -d "${PG_DATA}" ] && [ "$(ls -A ${PG_DATA})" ]; then
    echo "Warning: Data directory ${PG_DATA} exists and is not empty."
    read -p "Directory has existing files. Do you want to delete it? (yes/no): " choice
    if [ "$choice" = "yes" ] || [ "$choice" = "y" ]; then
        echo "Force deleting existing data directory..."
        su - postgres -c "pg_autoctl stop --pgdata ${PG_DATA}" >/dev/null 2>&1 || true
        rm -rf "${PG_DATA}"
        echo "Data directory deleted"
    else
        echo "Skipping deletion, exit "
        exit 1  
    fi
else
else
    echo "Data directory ${PG_DATA} does not exist or is empty, ready to create..."
    mkdir -p "${PG_DATA}"
fi

chown -R  postgres:postgres "${PG_BASE}"
chmod 700 "${PG_BASE}"



echo "=== remove remaining configurations ==="
rm -rf /home/postgres/.local/


echo "=== create data node ==="
su - postgres -c "pg_autoctl create postgres \
    --pgdata ${PG_DATA} \
    --monitor ${MONITOR_URI} \
    --auth trust \
    --ssl-self-signed \
    --hostname ${NODE_HOSTNAME} \
    --pgport ${NODE_PORT}"


echo "=== adding custom HBA rules ==="
echo "$CUSTOM_HBA_RULES" >> "${PG_DATA}/pg_hba.conf"


echo "=== create systemd service ==="
pg_autoctl -q show systemd --pgdata "${PG_DATA}" | tee /etc/systemd/system/${SERVICE_NAME}.service >/dev/null
systemctl daemon-reload >/dev/null 2>&1
systemctl enable ${SERVICE_NAME} >/dev/null 2>&1
systemctl start ${SERVICE_NAME} >/dev/null 2>&1
sleep 1


echo "=== check service status ==="
systemctl status ${SERVICE_NAME} --no-pager

echo "=== install completed ==="
echo "Data node is running on ${NODE_HOSTNAME}:${NODE_PORT}"
echo "Check status: systemctl status ${SERVICE_NAME}"

data 1节点安装日志

root@ubuntu12:/usr/local/pg_install_package# bash paf_install.sh
=== setup env ===
PGHOME=/usr/local/pgsql17/server
MONITOR_URI=postgres://autoctl_node@ubuntu11:25432/pg_auto_failover?sslmode=require
=== uncompress tar ===
=== switch to paf source code dir ===
=== make && make install ===
=== chown ===
=== verify install ===
pg_autoctl version
pg_autoctl extension version 2.2
compiled with PostgreSQL 17.6 on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 9.4.0-1ubuntu1~20.04.2) 9.4.0, 64-bit
compatible with Postgres 13, 14, 15, 16 and 17
=== create monitor node ===
Warning: Data directory /usr/local/pgsql17/pg25432/data exists and is not empty.
Directory has existing files. Do you want to delete it? (yes/no): yes
Force deleting existing data directory...
Data directory deleted
=== remove remaining configurations ===
=== create data node ===
03:18:31 601246 INFO  Using default --ssl-mode "require"
03:18:31 601246 INFO  Using --ssl-self-signed: pg_autoctl will create self-signed certificates, allowing for encrypted network traffic
03:18:31 601246 WARN  Self-signed certificates provide protection against eavesdropping; this setup does NOT protect against Man-In-The-Middle attacks nor Impersonation attacks.
03:18:31 601246 WARN  See https://www.postgresql.org/docs/current/libpq-ssl.html for details
03:18:31 601246 INFO  Started pg_autoctl postgres service with pid 601252
03:18:31 601246 INFO  Started pg_autoctl node-init service with pid 601254
03:18:31 601252 INFO   /usr/local/pgsql17/server/bin/pg_autoctl do service postgres --pgdata /usr/local/pgsql17/pg25432/data -v
03:18:31 601254 INFO  Registered node 1 "node_11" (ubuntu12:25432) in formation "default", group 0, state "single"
03:18:31 601254 INFO  Writing keeper state file at "/home/postgres/.local/share/pg_autoctl/usr/local/pgsql17/pg25432/data/pg_autoctl.state"
03:18:31 601254 INFO  Writing keeper init state file at "/home/postgres/.local/share/pg_autoctl/usr/local/pgsql17/pg25432/data/pg_autoctl.init"
03:18:31 601254 INFO  Successfully registered as "single" to the monitor.
03:18:31 601254 INFO  FSM transition from "init" to "single": Start as a single node
03:18:31 601254 INFO  Initialising postgres as a primary
03:18:31 601254 INFO  Initialising a PostgreSQL cluster at "/usr/local/pgsql17/pg25432/data"
03:18:31 601254 INFO  /usr/local/pgsql17/server/bin/pg_ctl initdb -s -D /usr/local/pgsql17/pg25432/data --option '--auth=trust'
03:18:31 601254 INFO   /usr/bin/openssl req -new -x509 -days 365 -nodes -text -out /usr/local/pgsql17/pg25432/data/server.crt -keyout /usr/local/pgsql17/pg25432/data/server.key -subj "/CN=ubuntu12"
03:18:31 601283 INFO   /usr/local/pgsql17/server/bin/postgres -D /usr/local/pgsql17/pg25432/data -p 25432 -h *
03:18:32 601252 INFO  Postgres is now serving PGDATA "/usr/local/pgsql17/pg25432/data" on port 25432 with pid 601283
03:18:32 601254 INFO  The user "postgres" already exists, skipping.
03:18:32 601254 INFO  CREATE USER postgres
03:18:32 601254 INFO  CREATE DATABASE postgres;
03:18:32 601254 INFO  The database "postgres" already exists, skipping.
03:18:32 601254 INFO  CREATE EXTENSION pg_stat_statements;
03:18:32 601254 INFO  Disabling synchronous replication
03:18:32 601254 INFO  Reloading Postgres configuration and HBA rules
03:18:32 601254 INFO  Reloading Postgres configuration and HBA rules
03:18:32 601254 INFO  Transition complete: current state is now "single"
03:18:32 601254 INFO  keeper has been successfully initialized.
03:18:32 601246 WARN  pg_autoctl service node-init exited with exit status 0
03:18:32 601252 INFO  Postgres controller service received signal SIGTERM, terminating
03:18:32 601252 INFO  Stopping pg_autoctl postgres service
03:18:32 601252 INFO  /usr/local/pgsql17/server/bin/pg_ctl --pgdata /usr/local/pgsql17/pg25432/data --wait stop --mode fast
03:18:32 601246 INFO  Stop pg_autoctl
=== adding custom HBA rules ===
=== create systemd service ===
=== check service status ===
● pgautofailover.service - pg_auto_failover
     Loaded: loaded (/etc/systemd/system/pgautofailover.service; enabled; vendor preset: enabled)
     Active: active (running) since Mon 2026-05-18 03:18:33 UTC; 1s ago
   Main PID: 601377 (pg_autoctl)
      Tasks: 10 (limit: 4550)
     Memory: 27.0M
     CGroup: /system.slice/pgautofailover.service
             ├─601377 /usr/local/pgsql17/server/bin/pg_autoctl run
             ├─601393 pg_autoctl: start/stop postgres
             ├─601395 pg_autoctl: node active
             ├─601404 /usr/local/pgsql17/server/bin/postgres -D /usr/local/pgsql17/pg25432/data -p 25432 -h *
             ├─601405 postgres: logger
             ├─601406 postgres: checkpointer
             ├─601407 postgres: background writer
             ├─601409 postgres: walwriter
             ├─601410 postgres: autovacuum launcher
             └─601411 postgres: logical replication launcher

May 18 03:18:33 ubuntu12 pg_autoctl[601377]: 03:18:33 601377 INFO  Started pg_autoctl postgres service with pid 601393
May 18 03:18:33 ubuntu12 pg_autoctl[601393]: 03:18:33 601393 INFO   /usr/local/pgsql17/server/bin/pg_autoctl do service postgres --pgdata /usr/local/pgsql17/pg25432/data -v
May 18 03:18:33 ubuntu12 pg_autoctl[601377]: 03:18:33 601377 INFO  Started pg_autoctl node-active service with pid 601395
May 18 03:18:33 ubuntu12 pg_autoctl[601395]: 03:18:33 601395 INFO   /usr/local/pgsql17/server/bin/pg_autoctl do service node-active --pgdata /usr/local/pgsql17/pg25432/data -v
May 18 03:18:33 ubuntu12 pg_autoctl[601395]: 03:18:33 601395 INFO  Reloaded the new configuration from "/home/postgres/.config/pg_autoctl/usr/local/pgsql17/pg25432/data/pg_autoctl.cfg"
May 18 03:18:33 ubuntu12 pg_autoctl[601395]: 03:18:33 601395 INFO  pg_autoctl service is running, current state is "single"
May 18 03:18:33 ubuntu12 pg_autoctl[601404]: 03:18:33 601404 INFO   /usr/local/pgsql17/server/bin/postgres -D /usr/local/pgsql17/pg25432/data -p 25432 -h *
May 18 03:18:33 ubuntu12 pg_autoctl[601393]: 03:18:33 601393 INFO  Postgres is now serving PGDATA "/usr/local/pgsql17/pg25432/data" on port 25432 with pid 601404
May 18 03:18:33 ubuntu12 pg_autoctl[601395]: 03:18:33 601395 WARN  PostgreSQL was not running, restarted with pid 601404
May 18 03:18:33 ubuntu12 pg_autoctl[601395]: 03:18:33 601395 INFO  New state for this node (node 1, "node_11") (ubuntu12:25432): single ➜ single
=== install completed ===
Data node is running on ubuntu12:25432
Check status: systemctl status pgautofailover
root@ubuntu12:/usr/local/pg_install_package#

 

3,data 1节点安装后monitor节点状态

root@ubuntu11:/usr/local/pg_install_package# su - postgres -c "pg_autoctl show state"
   Name |  Node |      Host:Port |       TLI: LSN |   Connection |      Reported State |      Assigned State
--------+-------+----------------+----------------+--------------+---------------------+--------------------
node_11 |     1 | ubuntu12:25432 |   1: 0/1545F58 |   read-write |              single |              single

root@ubuntu11:/usr/local/pg_install_package#

 

4,data 2或则更多data 节点安装

略,根据情况,仅需修改 #配置变量 部分参数,数据路径,主机名等

 

5,data 2节点安装后monitor节点状态

root@ubuntu11:/usr/local/pg_install_package# su - postgres -c "pg_autoctl show state"
   Name |  Node |      Host:Port |       TLI: LSN |   Connection |      Reported State |      Assigned State
--------+-------+----------------+----------------+--------------+---------------------+--------------------
node_11 |     1 | ubuntu12:25432 |   1: 0/1545F58 |   read-write |              single |              single

root@ubuntu11:/usr/local/pg_install_package# su - postgres -c "pg_autoctl show state"
   Name |  Node |      Host:Port |       TLI: LSN |   Connection |      Reported State |      Assigned State
--------+-------+----------------+----------------+--------------+---------------------+--------------------
node_11 |     1 | ubuntu12:25432 |   1: 0/305F790 |   read-write |             primary |             primary
 node_2 |     2 | ubuntu13:25432 |   1: 0/305F790 |    read-only |           secondary |           secondary

root@ubuntu11:/usr/local/pg_install_package#

 

 

1,该脚本仅在Ubuntu20下做过详尽的测试,pg17+pg_auto_failover 2.2,该脚本可极大简化pg_auto_failover的安装过程,全程自动完成pg_auto_failover的搭建
2,欢迎试用,有建议或者问题请留言
3, 20260616更新:脚本微调,ubuntu24下验证pg_auto_failover搭建,完美通过

 

posted on 2026-05-18 12:08  MSSQL123  阅读(40)  评论(0)    收藏  举报