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搭建,完美通过
浙公网安备 33010602011771号