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_failoverPostgreSQL数据库高可用2026/10/25

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 两类节点组成:

角色数量职责运行进程
monitor1维护集群状态机、协调故障转移PostgreSQL + pgautofailover 扩展
keeper(数据节点)2+托管本地 PostgreSQL、执行状态转换PostgreSQL + pg_autoctl run

最小生产形态为 1 monitor + 2 keeper,可实现一主一备的自动故障转移。

2.2 选型说明

本指南采用官方推荐的"monitor 独立 + 双数据节点"方案,理由:

  • monitor 与业务库分离,避免 monitor 故障影响业务库性能;
  • 双数据节点满足同步复制的最小要求(1 主 1 备),RPO=0;
  • 如需要更高可用性,可扩展为 3+ 数据节点。

三、前置条件(每节点)

所有节点需完成以下准备:

  1. Ubuntu 22.04 系统,主机名已配置且可互相解析;
  2. 已安装 PostgreSQL 17 与 pg_auto_failover 2.2 软件包;
  3. 防火墙放通 5432 端口(节点间通信);
  4. 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 配置流复制备库。

十、参考链接