pg_auto_failover 2.2 集群部署指南
pg_auto_failover 2.2 集群部署:1 monitor + 2 数据节点(一主一备)的 0→1 全流程,含 monitor 初始化、主备节点加入、状态核查、主动 failover 实测(2.9s 切换)、systemd 托管与 pg_hba.conf 排障实录,全部命令实测回显。
pg_auto_failover 2.2 集群部署指南
目标:从零搭建一个 pg_auto_failover 2.2 高可用集群(1 个 monitor + 2 个数据节点,一主一备),覆盖 monitor 初始化、主备节点加入、状态核查、故障转移验证与排障实录。所有命令与输出均在 Ubuntu 22.04 + PostgreSQL 17.11 + pg_auto_failover 2.2 环境实测通过。
一、环境信息
| 项目 | 取值 |
|---|---|
| 操作系统 | Ubuntu 22.04 LTS |
| PostgreSQL 版本 | 17.11 |
| pg_auto_failover 版本 | 2.2(扩展) / 2.2-4.pgdg22.04+1(pg_autoctl CLI) |
| 节点角色 | 1 monitor + 2 数据节点(node1 主 / node2 备) |
| 主机名 | monitor、node1、node2 |
| 监听端口 | 5432(各节点 PostgreSQL) |
| 认证方式 | trust(局域网内互信) |
| SSL | 自签名证书(sslmode=require) |
| 数据目录 | /var/lib/pgaf/data(各节点) |
说明:本指南使用 3 台独立服务器,主机名分别为 monitor、node1、node2,三者在同一局域网内可按主机名互相解析。生产环境建议 monitor 独占一台服务器,数据节点各自独立。
二、集群架构与方案选型
2.1 角色分工
pg_auto_failover 集群由 monitor 和 keeper 两类节点组成:
| 角色 | 数量 | 职责 | 运行进程 |
|---|---|---|---|
| monitor | 1 | 维护集群状态机、协调故障转移 | PostgreSQL + pgautofailover 扩展 |
| keeper(数据节点) | 2+ | 托管本地 PostgreSQL、执行状态转换 | PostgreSQL + pg_autoctl run |
最小生产形态为 1 monitor + 2 keeper,可实现一主一备的自动故障转移。
2.2 选型说明
本指南采用官方推荐的"monitor 独立 + 双数据节点"方案,理由:
- monitor 与业务库分离,避免 monitor 故障影响业务库性能;
- 双数据节点满足同步复制的最小要求(1 主 1 备),RPO=0;
- 如需要更高可用性,可扩展为 3+ 数据节点。
三、前置条件(每节点)
所有节点需完成以下准备:
- Ubuntu 22.04 系统,主机名已配置且可互相解析;
- 已安装 PostgreSQL 17 与 pg_auto_failover 2.2 软件包;
- 防火墙放通 5432 端口(节点间通信);
- postgres 用户可正常登录。
3.1 软件安装
添加 PostgreSQL 官方软件源并安装:
# 安装基础依赖
apt-get update
apt-get install -y curl ca-certificates gnupg lsb-release
# 添加 PostgreSQL 官方源
echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg
# 禁止创建默认 main 集群
apt-get install -y postgresql-common
echo 'create_main_cluster = false' > /etc/postgresql-common/createcluster.conf
# 安装 PostgreSQL 17 + pg_auto_failover
apt-get update
apt-get install -y postgresql-17 postgresql-17-auto-failover pg-auto-failover-cli
⚠️ 注意:
create_main_cluster = false必须在安装postgresql-17之前写入/etc/postgresql-common/createcluster.conf,否则 Debian 系会自动创建一个名为 main 的默认集群,干扰 pg_auto_failover 的初始化。
验证安装:
pg_autoctl --version
实测回显:
pg_autoctl version 2.2-4.pgdg22.04+1
pg_autoctl extension version 2.2
compiled with PostgreSQL 18.4 (Ubuntu 18.4-1.pgdg22.04+1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0, 64-bit
compatible with Postgres 13, 14, 15, 16 and 17
💡 技术拓展:pg_auto_failover 的软件包分为两部分——
postgresql-17-auto-failover提供pgautofailover扩展(monitor 节点需要),pg-auto-failover-cli提供pg_autoctl命令行工具(所有节点都需要)。安装时两者都要装。
四、初始化 monitor 节点
monitor 是整个集群的"大脑",必须第一个启动。
4.1 创建 monitor
在 monitor 节点上以 postgres 用户执行:
mkdir -p /var/lib/pgaf
chown postgres:postgres /var/lib/pgaf
su - postgres
pg_autoctl create monitor \
--pgdata /var/lib/pgaf/data \
--hostname monitor \
--pgport 5432 \
--auth trust \
--ssl-self-signed \
--run
参数说明:
--pgdata:PostgreSQL 数据目录;--hostname:monitor 被数据节点访问的主机名;--pgport:PostgreSQL 监听端口;--auth trust:数据节点连接 monitor 的认证方式(局域网内可用 trust,生产建议 scram-sha-256);--ssl-self-signed:使用自签名证书加密通信;--run:创建完成后立即启动 monitor 进程。
实测回显(节选):
INFO Using default --ssl-mode "require"
INFO Using --ssl-self-signed: pg_autoctl will create self-signed certificates
WARN Self-signed certificates provide protection against eavesdropping; this setup does NOT protect against Man-In-The-Middle attacks nor Impersonation attacks.
INFO Initialising a PostgreSQL cluster at "/var/lib/pgaf/data"
INFO Started pg_autoctl postgres service with pid 32
INFO Postgres is now serving PGDATA "/var/lib/pgaf/data" on port 5432 with pid 38
INFO Granting connection privileges on 10.89.57.0/24
INFO Your pg_auto_failover monitor instance is now ready on port 5432.
INFO Monitor has been successfully initialized.
4.2 验证 monitor
pg_autoctl show state --pgdata /var/lib/pgaf/data
实测回显(monitor 刚初始化,尚无数据节点):
Name | Node | Host:Port | TLI: LSN | Connection | Reported State | Assigned State
------+------+-----------+----------+------------+----------------+-----------------
此时状态表为空属正常,因为还没有数据节点注册。
五、数据节点加入集群
数据节点需逐个加入。先加入第一个节点(将成为主库),再加入第二个节点(将成为备库)。
5.1 加入 node1(主库)
在 node1 节点上以 postgres 用户执行:
mkdir -p /var/lib/pgaf
chown postgres:postgres /var/lib/pgaf
su - postgres
pg_autoctl create postgres \
--pgdata /var/lib/pgaf/data \
--pghost localhost \
--hostname node1 \
--pgport 5432 \
--listen 0.0.0.0 \
--monitor postgres://autoctl_node@monitor:5432/pg_auto_failover \
--auth trust \
--pg-hba-lan \
--ssl-self-signed \
--run
参数说明:
--pghost localhost:PostgreSQL 本地连接使用 localhost(走 trust 认证,避免 pg_hba.conf 拒绝本地连接);--hostname node1:其他节点(monitor、备库)通过此主机名访问本节点;--listen 0.0.0.0:PostgreSQL 监听所有网络接口;--monitor:monitor 的连接串,固定格式为postgres://autoctl_node@<monitor主机>:<端口>/pg_auto_failover;--pg-hba-lan:自动在 pg_hba.conf 中添加局域网网段的访问规则。
实测回显(节选):
INFO Registering node 1 "node_1" (node1:5432) to formation "default"
INFO Setting goal state of node 1 "node_1" (node1:5432) to single as there is no other node.
INFO FSM transition from "init" to "single": Start as a single node
INFO Initialising postgres as a primary
INFO Granting connection privileges on 10.89.57.0/24
INFO Postgres is now serving PGDATA "/var/lib/pgaf/data" on port 5432
⚠️ 排障实录:若
--pghost设为节点自身主机名(如node1),pg_autoctl 在初始化时会尝试通过主机名连接本地 PostgreSQL,但此时 pg_hba.conf 可能尚未放通该主机名对应的 IP,导致no pg_hba.conf entry错误。解决方案:--pghost用localhost(本地连接走默认的 trust 规则),--hostname用节点对外主机名(供其他节点访问),同时加--pg-hba-lan自动放通局域网。
5.2 加入 node2(备库)
在 node2 节点上以 postgres 用户执行(命令与 node1 基本一致,仅主机名不同):
mkdir -p /var/lib/pgaf
chown postgres:postgres /var/lib/pgaf
su - postgres
pg_autoctl create postgres \
--pgdata /var/lib/pgaf/data \
--pghost localhost \
--hostname node2 \
--pgport 5432 \
--listen 0.0.0.0 \
--monitor postgres://autoctl_node@monitor:5432/pg_auto_failover \
--auth trust \
--pg-hba-lan \
--ssl-self-signed \
--run
实测回显(节选):
INFO Registering node 2 "node_2" (node2:5432) to formation "default"
INFO New state is reported by node 2 "node_2" (node2:5432): "wait_standby"
INFO FSM transition from "init" to "wait_standby": Start as a standby node
INFO Taking a base backup from "node1:5432"
INFO Setting goal state of node 2 "node_2" (node2:5432) to catchingup
INFO New state is reported by node 2 "node_2" (node2:5432): "catchingup"
INFO Setting goal state of node 2 "node_2" (node2:5432) to secondary after it caught up.
六、状态核查
6.1 查看集群状态
在 monitor 节点上执行:
pg_autoctl show state --pgdata /var/lib/pgaf/data
实测回显:
Name | Node | Host:Port | TLI: LSN | Connection | Reported State | Assigned State
-------+-------+------------+----------------+--------------+---------------------+--------------------
node_1 | 1 | node1:5432 | 1: 0/3000130 | read-write | primary | primary
node_2 | 2 | node2:5432 | 1: 0/3000130 | read-only | secondary | secondary
状态解读:
node_1为primary(主库,read-write);node_2为secondary(备库,read-only);- 两者
TLI: LSN一致,说明数据同步正常。
6.2 查看连接 URI
pg_autoctl show uri --pgdata /var/lib/pgaf/data
实测回显:
Type | Name | Connection String
-------------+---------+-------------------------------
monitor | monitor | postgres://autoctl_node@monitor:5432/pg_auto_failover?sslmode=require
formation | default | postgres://node1:5432,node2:5432/postgres?target_session_attrs=read-write&sslmode=require
formation 行给出了应用连接串,包含主备两个节点,target_session_attrs=read-write 表示应用只连主库(故障转移后自动指向新主)。
6.3 查看复制配置
pg_autoctl show settings --pgdata /var/lib/pgaf/data
实测回显:
Context | Name | Setting | Value
----------+---------+---------------------------+-----------------------------------
formation | default | number_sync_standbys | 0
primary | node_1 | synchronous_standby_names | 'ANY 1 (pgautofailover_standby_2)'
node | node_1 | candidate priority | 50
node | node_2 | candidate priority | 50
node | node_1 | replication quorum | true
node | node_2 | replication quorum | true
6.4 验证数据复制
在主库(node1)写入测试数据:
psql -h localhost -p 5432 -d postgres -c "CREATE TABLE repl_test(id serial, msg text); INSERT INTO repl_test(msg) VALUES ('hello');"
回显:
CREATE TABLE
INSERT 0 1
在备库(node2)查询:
psql -h localhost -p 5432 -d postgres -c "SELECT * FROM repl_test;"
回显:
id | msg
----+-------
1 | hello
(1 row)
数据已同步。清理测试表:
psql -h localhost -p 5432 -d postgres -c "DROP TABLE repl_test;"
七、高可用与故障演练
7.1 主动故障转移(pg_autoctl perform failover)
在 monitor 节点执行:
pg_autoctl perform failover --pgdata /var/lib/pgaf/data --formation default --group 0
实测回显(节选):
INFO Waiting 60 secs for a notification with state "primary" in formation "default" and group 0
Time | Name | Node | Host:Port | Current State | Assigned State
---------+--------+-------+------------+---------------------+--------------------
12:08:01 | node_1 | 0/1 | node1:5432 | primary | draining
12:08:01 | node_2 | 0/2 | node2:5432 | secondary | prepare_promotion
12:08:02 | node_2 | 0/2 | node2:5432 | stop_replication | wait_primary
12:08:02 | node_1 | 0/1 | node1:5432 | demote_timeout | demoted
12:08:03 | node_1 | 0/1 | node1:5432 | catchingup | secondary
12:08:03 | node_2 | 0/2 | node2:5432 | wait_primary | primary
切换后状态:
Name | Node | Host:Port | TLI: LSN | Connection | Reported State | Assigned State
-------+-------+------------+----------------+--------------+---------------------+--------------------
node_1 | 1 | node1:5432 | 2: 0/3091720 | read-only | secondary | secondary
node_2 | 2 | node2:5432 | 2: 0/3091720 | read-write | primary | primary
实测耗时:约 2.9 秒(time 命令实测 real 0m2.857s)。切换后 node_2 成为新主库(read-write),node_1 降级为备库(read-only),TLI 从 1 变为 2。
7.2 平滑切换(pg_autoctl perform switchover)
switchover 与 failover 的区别在于:switchover 是计划性切换(主库正常运行时主动切换),failover 是故障性切换(主库宕机时自动切换)。
pg_autoctl perform switchover --pgdata /var/lib/pgaf/data --formation default --group 0
切换后 node_1 重新成为主库,node_2 回到备库。
八、systemd 托管
生产环境建议用 systemd 托管 pg_autoctl 进程。生成 systemd 单元文件:
pg_autoctl show systemd --pgdata /var/lib/pgaf/data
实测回显:
[Unit]
Description = pg_auto_failover
[Service]
WorkingDirectory = /var/lib/postgresql
Environment = 'PGDATA=/var/lib/pgaf/data'
User = postgres
ExecStart = /usr/bin/pg_autoctl run
Restart = always
StartLimitBurst = 0
ExecReload = /usr/bin/pg_autoctl reload
[Install]
WantedBy = multi-user.target
部署步骤:
pg_autoctl -q show systemd --pgdata "/var/lib/pgaf/data" | tee /etc/systemd/system/pgautofailover.service
systemctl daemon-reload
systemctl enable pgautofailover
systemctl start pgautofailover
验证:
systemctl is-active pgautofailover
回显应为 active。
九、常见问题
9.1 no pg_hba.conf entry for host ... user "postgres" database "template1"
现象:pg_autoctl create postgres 时报 no pg_hba.conf entry for host "x.x.x.x", user "postgres", database "template1"。
原因:--pghost 设为节点主机名,pg_autoctl 通过主机名连接本地 PostgreSQL,但 pg_hba.conf 未放通该 IP。
解决:--pghost 用 localhost,--hostname 用对外主机名,同时加 --pg-hba-lan 自动放通局域网网段。
9.2 create_main_cluster 导致默认集群干扰
现象:安装 postgresql-17 后自动创建了 main 集群,占用 5432 端口。
解决:在安装 postgresql-17 前,先安装 postgresql-common 并写入 create_main_cluster = false。
9.3 SSL choice is required
现象:pg_autoctl create 时报 Explicit SSL choice is required。
解决:必须显式指定 --ssl-self-signed(自签名)、--no-ssl(不加密,不推荐)或提供自定义证书(--server-key/--server-cert)。
9.4 monitor 单点故障
现象:monitor 宕机后,数据节点仍正常运行,但无法执行故障转移。
解决:定期备份 monitor 的数据库(pg_dump pg_auto_failover),monitor 宕机时从备份恢复。生产环境可考虑为 monitor 配置流复制备库。