PostgreSQL 高可用集群搭建指南
Keepalived + repmgr + PostgreSQL 16.0 完整部署手册
📖 阅读指南
本文档面向技术小白和运维新手,采用”先讲概念、再给命令、每条配置都加注释”的方式,帮助你从零搭建一套生产级 PostgreSQL 高可用集群。
💡 小贴士: 每个配置项旁边的 # ← 注释会用大白话解释它的作用,不用担心看不懂。
📋 目录
- 概念速览 — 先搞懂每个组件是干什么的
- 集群环境规划 — 几台服务器、什么角色
- 安装 PostgreSQL 16.0
- 安装配置 repmgr(主从复制管理)
- 安装配置 Keepalived(VIP 漂移)
- 集群验证测试
- 故障处理:脑裂修复
- 常用命令速查
1. 概念速览
1.1 这套方案解决了什么问题?
想象你只有一台 PostgreSQL 数据库,某天它突然挂了——你的整个业务就瘫痪了。
这套方案用三个组件协作,实现 自动故障转移:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| ┌─────────────────────────────────────────────────────┐ │ 业务应用 │ │ 连接 VIP(虚拟IP) │ │ x.x.x.x(永远指向当前主库) │ └─────────────────────┬───────────────────────────────┘ │ ┌────────────┴────────────┐ │ │ ┌────▼─────┐ ┌─────▼────┐ │ 主数据库 │◄───复制───►│ 备数据库 │ │ .184.123 │ │ .183.82 │ │ (Master) │ │ (Standby) │ └────┬──────┘ └─────┬─────┘ │ │ ┌────▼─────┐ │ │keepalived│◄──────VRRP───────┘ │priority │ 心跳+健康检查 │ 100 │ └──────────┘ ┌──────────┐ │ 见证服务器 │ │ .183.95 │ │ (Witness) │ └──────────┘
|
1.2 三个组件各干什么?
| 组件 |
角色 |
大白话解释 |
| PostgreSQL |
数据库本身 |
存数据的地方,一台主库(可读写)+ 一台备库(只读复制) |
| repmgr |
复制管理器 |
自动监控主库状态,主库挂了就提升备库为新主库 |
| Keepalived |
VIP 漂移 |
提供一个”虚拟 IP”,永远自动指向当前的主库,业务不用改连接地址 |
1.3 核心概念术语表
| 术语 |
解释 |
| 主库 (Primary) |
可以读写的数据库,只有一台 |
| 备库 (Standby) |
从主库实时复制数据,只能读不能写 |
| 见证服务器 (Witness) |
不存业务数据,只在主备之间”断联”时帮忙投票决定谁当主库,防止脑裂 |
| VIP (虚拟IP) |
一个漂移的 IP 地址,永远绑在当前主库的网卡上 |
| 脑裂 (Split-Brain) |
主备都认为自己是主库,两边同时写入导致数据不一致——这是最危险的故障 |
| 故障转移 (Failover) |
主库挂了 → 备库自动升级为新主库的过程 |
| WAL |
Write-Ahead Log,预写日志,主库的每次写操作先记日志再写数据,备库通过”重放”这些日志来同步 |
| 流复制 (Streaming Replication) |
备库实时从主库”流式”接收 WAL 日志并应用 |
2. 集群环境规划
2.1 服务器清单
| 角色 |
IP 地址 |
主机名建议 |
Root 密码 |
| 主数据库 (Primary) |
192.168.184.123/24 |
pg-primary |
Aa_123qwe |
| 备数据库 (Standby) |
192.168.183.82/26 |
pg-standby |
Aa_123qwe |
| 见证服务器 (Witness) |
192.168.183.95/26 |
pg-witness |
Aa_123qwe |
| VIP(虚拟IP) |
待定(需根据网络规划) |
— |
— |
2.2 软件版本
| 软件 |
版本 |
说明 |
| PostgreSQL |
16.0 |
源码编译安装 |
| repmgr |
5.5.0 |
EnterpriseDB 出品 |
| Keepalived |
yum 最新版 |
Linux 虚拟路由冗余协议 |
2.3 关键路径一览
| 路径 |
用途 |
/usr/local/pgsql16/ |
PostgreSQL 安装目录 |
/usr/local/pgsql16/data/ |
数据库数据目录 |
/usr/local/pgsql16/bin/ |
PostgreSQL 可执行文件目录 |
/etc/repmgr.conf |
repmgr 配置文件 |
/etc/keepalived/keepalived.conf |
Keepalived 配置文件 |
/home/postgres/ |
postgres 用户家目录 |
2.4 端口规划
| 端口 |
用途 |
| 5432 |
PostgreSQL 数据库服务端口 |
| — |
VRRP 协议使用组播,无需额外开放 TCP 端口 |
3. 安装 PostgreSQL 16.0
3.1 编译安装(三台服务器都执行)
⚠️ 重要: 以下命令需要在每台服务器上以 root 用户执行。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
|
yum install -y readline-devel libxslt-devel
tar zxvf postgresql-16.0.tar.gz cd postgresql-16.0/
mkdir /usr/local/pgsql16
./configure --prefix=/usr/local/pgsql16 \ --with-ssl=openssl \ --with-icu \ --with-python \ --with-libxml \ --with-libxslt \ --with-systemd
make -j 8 make install
|
3.2 创建 postgres 用户(三台服务器都执行)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
groupadd postgres
useradd -m -g postgres postgres
passwd postgres
mkdir /usr/local/pgsql16/data
chown -R postgres:postgres /usr/local/pgsql16/
|
3.3 配置环境变量(三台服务器都执行)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
su - postgres
vim .bash_profile
export PGHOME=/usr/local/pgsql16 export PGDATA=/usr/local/pgsql16/data export PATH=$PGHOME/bin:$PATH export LD_LIBRARY_PATH=$PGHOME/lib
source .bash_profile
|
3.4 初始化数据库(主节点和见证节点执行)
⚠️ 备节点不需要初始化,后面会用 repmgr 从主节点克隆数据。
1 2 3 4 5 6 7 8 9 10 11 12 13
| su - postgres
/usr/local/pgsql16/bin/initdb -D /usr/local/pgsql16/data --encoding=UTF8
exit
|
3.5 配置 PostgreSQL 参数
3.5.1 主节点配置
文件 postgresql.conf — 路径:/usr/local/pgsql16/data/postgresql.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
listen_addresses = '*' port = 5432
max_wal_senders = 10 max_replication_slots = 10 wal_level = replica wal_log_hints = on hot_standby = on
archive_mode = on archive_command = '/bin/true'
shared_preload_libraries = 'repmgr'
|
文件 pg_hba.conf — 路径:/usr/local/pgsql16/data/pg_hba.conf
💡 pg_hba.conf 是什么? PostgreSQL 的”访客登记表”,控制谁可以连接数据库、用什么方式认证。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| # ============================================================ # 格式说明:TYPE DATABASE USER ADDRESS METHOD # TYPE:连接方式(local=本地socket, host=TCP/IP) # DATABASE:允许访问的数据库名 # USER:允许的用户 # ADDRESS:来源 IP 范围(CIDR 格式) # METHOD:认证方式(trust=免密, scram-sha-256=密码认证) # ============================================================
# 允许 repmgr 用户本地免密连接(用于 repmgr 内部操作) local replication repmgr trust local repmgr repmgr trust
# 允许 repmgr 用户通过 TCP 从内网连接,使用密码认证(更安全) host replication repmgr 192.168.0.0/16 scram-sha-256 host replication repmgr 127.0.0.1/32 scram-sha-256 host repmgr repmgr 192.168.0.0/16 scram-sha-256 host repmgr repmgr 127.0.0.1/32 scram-sha-256
|
3.5.2 见证节点配置
文件 postgresql.conf — 路径:/usr/local/pgsql16/data/postgresql.conf
1 2 3 4 5 6 7
|
listen_addresses = '*' port = 5432 shared_preload_libraries = 'repmgr'
|
文件 pg_hba.conf — 路径:/usr/local/pgsql16/data/pg_hba.conf
1 2 3 4 5 6 7 8 9 10
| # ============================================================ # 见证节点认证配置 # 允许主备节点的 repmgr 用户访问 # 注意:这里使用精确网段(/24 和 /26),比主节点的 /16 更严格 # ============================================================ host all repmgr 192.168.184.0/24 scram-sha-256 host all repmgr 192.168.183.64/26 scram-sha-256 host all repmgr 192.168.183.95/32 scram-sha-256 host replication repmgr 192.168.184.0/24 scram-sha-256 host replication repmgr 192.168.183.64/26 scram-sha-256
|
3.6 配置 systemd 服务(三台服务器都执行)
💡 为什么用 systemd? 让 PostgreSQL 可以开机自启、用 systemctl 管理启停,repmgr 也能通过 systemctl 控制数据库。
文件 postgresql.service — 路径:/lib/systemd/system/postgresql.service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| [Unit] Description=PostgreSQL 16.0 Database Server Documentation=https://www.postgresql.org/docs/16/ After=network-online.target Wants=network-online.target
[Service] Type=simple User=postgres Group=postgres
Environment=PGDATA=/usr/local/pgsql16/data Environment=PGPORT=5432
ExecStart=/usr/local/pgsql16/bin/postgres -D ${PGDATA}
ExecReload=/bin/kill -HUP $MAINPID
ExecStop=/usr/local/pgsql16/bin/pg_ctl stop -D ${PGDATA} -m fast
KillMode=mixed KillSignal=SIGINT TimeoutSec=600 Restart=on-failure LimitNOFILE=65536 LimitNPROC=65536
[Install] WantedBy=multi-user.target
|
启动 PostgreSQL:
1 2 3 4 5 6 7 8 9 10 11
| systemctl daemon-reload
systemctl start postgresql.service
systemctl enable postgresql.service
systemctl status postgresql.service
|
3.7 防火墙配置(三台服务器都执行)
1 2 3 4 5 6 7 8 9 10
|
firewall-cmd --zone=public --add-port=5432/tcp --permanent
firewall-cmd --reload
firewall-cmd --list-ports
|
3.8 创建 repmgr 用户和数据库(主节点执行,见证节点也可执行)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| su - postgres
/usr/local/pgsql16/bin/psql -c "CREATE USER repmgr WITH REPLICATION LOGIN ENCRYPTED PASSWORD 'repmgr' SUPERUSER;"
/usr/local/pgsql16/bin/psql -c "CREATE DATABASE repmgr OWNER repmgr;"
/usr/local/pgsql16/bin/psql -d repmgr -c "CREATE EXTENSION repmgr;"
|
4. 安装配置 repmgr(主从复制管理)
4.1 编译安装 repmgr(三台服务器都执行)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
wget https://github.com/EnterpriseDB/repmgr/releases/download/v5.5.0/repmgr-5.5.0.tar.gz
yum install -y libcurl-devel json-c-devel libevent-devel openssl-devel
mv repmgr-5.5.0.tar.gz /home/postgres su - postgres tar zxvf repmgr-5.5.0.tar.gz cd repmgr-5.5.0/
./configure PG_CONFIG=/usr/local/pgsql16/bin/pg_config
make -j 8 make install
/usr/local/pgsql16/bin/repmgr --version
|
4.2 配置 repmgr
4.2.1 主节点配置
文件 repmgr.conf — 路径:/etc/repmgr.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
|
node_id = 1 node_name = 'pg-primary'
conninfo = 'host=192.168.184.123 user=repmgr dbname=repmgr connect_timeout=2'
data_directory = '/usr/local/pgsql16/data' pg_bindir = '/usr/local/pgsql16/bin' repmgr_bindir = '/usr/local/pgsql16/bin'
log_level = INFO log_file = '/home/postgres/repmgrd.log'
repmgrd_pid_file = '/usr/local/pgsql16/data/repmgrd.pid'
service_start_command = 'sudo systemctl start postgresql' service_stop_command = 'sudo systemctl stop postgresql' service_restart_command = 'sudo systemctl restart postgresql' service_reload_command = 'sudo systemctl reload postgresql'
failover = automatic
promote_command = '/usr/local/pgsql16/bin/repmgr standby promote -f /etc/repmgr.conf'
follow_command = '/usr/local/pgsql16/bin/repmgr standby follow -f /etc/repmgr.conf --upstream-node-id=%n'
reconnect_attempts = 10 reconnect_interval = 10 promote_check_timeout = 60
|
4.2.2 备节点配置
文件 repmgr.conf — 路径:/etc/repmgr.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
node_id = 2 node_name = 'pg-standby' conninfo = 'host=192.168.183.82 user=repmgr dbname=repmgr connect_timeout=2' data_directory = '/usr/local/pgsql16/data' pg_bindir = '/usr/local/pgsql16/bin' repmgr_bindir = '/usr/local/pgsql16/bin'
log_level = INFO log_file = '/home/postgres/repmgrd.log'
repmgrd_pid_file = '/usr/local/pgsql16/data/repmgr.pid'
service_start_command = 'sudo systemctl start postgresql' service_stop_command = 'sudo systemctl stop postgresql' service_restart_command = 'sudo systemctl restart postgresql' service_reload_command = 'sudo systemctl reload postgresql'
failover = automatic promote_command = '/usr/local/pgsql16/bin/repmgr standby promote -f /etc/repmgr.conf' follow_command = '/usr/local/pgsql16/bin/repmgr standby follow -f /etc/repmgr.conf --upstream-node-id=%n'
reconnect_attempts = 10 reconnect_interval = 10 promote_check_timeout = 60
|
4.2.3 见证节点配置
文件 repmgr.conf — 路径:/etc/repmgr.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
node_id = 3 node_name = 'pg-witness' conninfo = 'host=192.168.183.95 user=repmgr dbname=repmgr connect_timeout=2' data_directory = '/usr/local/pgsql16/data' pg_bindir = '/usr/local/pgsql16/bin' repmgr_bindir = '/usr/local/pgsql16/bin'
log_level = INFO log_file = '/home/postgres/repmgrd.log' repmgrd_pid_file = '/usr/local/pgsql16/data/repmgr.pid'
service_start_command = 'sudo systemctl start postgresql' service_stop_command = 'sudo systemctl stop postgresql' service_restart_command = 'sudo systemctl restart postgresql' service_reload_command = 'sudo systemctl reload postgresql'
|
4.3 配置 sudo 权限(三台服务器都执行)
💡 为什么要配这个? repmgrd 以 postgres 用户运行,但 systemctl 命令需要 root 权限。通过 sudo 授权,让 postgres 用户能免密码执行 systemctl。
1 2 3 4 5 6 7 8 9 10 11 12
| visudo
Defaults:postgres !requiretty
postgres ALL = NOPASSWD: /usr/bin/systemctl start postgresql, \ /usr/bin/systemctl stop postgresql, \ /usr/bin/systemctl restart postgresql, \ /usr/bin/systemctl reload postgresql
|
4.4 配置 SSH 免密登录(三台服务器都执行)
💡 为什么要配 SSH 互信? repmgr 在执行 standby clone(克隆数据)时,需要通过 SSH 在主备之间传输数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| su - postgres
ssh-keygen -t rsa
ssh-copy-id postgres@192.168.184.123 ssh-copy-id postgres@192.168.183.82 ssh-copy-id postgres@192.168.183.95
ssh postgres@192.168.184.123 "hostname" ssh postgres@192.168.183.82 "hostname" ssh postgres@192.168.183.95 "hostname"
|
4.5 配置 .pgpass 密码文件(三台服务器都执行)
💡 为什么要配 .pgpass? repmgr 在操作数据库时,需要自动连接各节点的 repmgr 库。.pgpass 文件让 repmgr 能免交互式输入密码。
文件 .pgpass — 路径:/home/postgres/.pgpass
1 2 3 4 5 6 7 8 9 10 11 12 13
| # ============================================================ # .pgpass 格式:hostname:port:database:username:password # ============================================================
# replication 数据库的连接(用于流复制认证) 192.168.184.123:5432:replication:repmgr:repmgr 192.168.183.82:5432:replication:repmgr:repmgr 192.168.183.95:5432:replication:repmgr:repmgr
# repmgr 数据库的连接(用于集群管理) 192.168.184.123:5432:repmgr:repmgr:repmgr 192.168.183.82:5432:repmgr:repmgr:repmgr 192.168.183.95:5432:repmgr:repmgr:repmgr
|
1 2 3 4 5 6
|
chmod 600 /home/postgres/.pgpass
|
4.6 注册节点到集群
注册主节点(在主节点执行)
1 2 3 4 5 6
| su - postgres
/usr/local/pgsql16/bin/repmgr -f /etc/repmgr.conf primary register
|
注册备节点(在备节点执行)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
sudo systemctl stop postgresql rm -rf /usr/local/pgsql16/data/*
su - postgres
/usr/local/pgsql16/bin/repmgr -h 192.168.184.123 -U repmgr -d repmgr \ -f /etc/repmgr.conf standby clone --dry-run
/usr/local/pgsql16/bin/repmgr -h 192.168.184.123 -U repmgr -d repmgr \ -f /etc/repmgr.conf standby clone
sudo systemctl start postgresql
/usr/local/pgsql16/bin/repmgr -f /etc/repmgr.conf standby register
|
注册见证节点(在见证节点执行)
1 2 3 4 5 6 7 8
| su - postgres
/usr/local/pgsql16/bin/repmgr -f /etc/repmgr.conf witness -h 192.168.184.123
|
4.7 启动 repmgrd 守护进程(三台服务器都执行)
💡 repmgrd 是什么? repmgr 的守护进程,常驻后台,持续监控集群状态并在故障时自动执行切换。没有它,repgr 只能手动操作。
方案一:systemd 管理(推荐)
文件 repmgrd.service — 路径:/lib/systemd/system/repmgrd.service
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| [Unit] Description=repmgrd service After=postgresql.service
[Service] Type=simple User=postgres
ExecStart=/usr/local/pgsql16/bin/repmgrd -f /etc/repmgr.conf --daemonize=false ExecReload=/bin/kill -HUP $MAINPID KillMode=process TimeoutSec=30 Restart=always
[Install] WantedBy=multi-user.target
|
1 2 3 4 5 6 7 8 9 10 11
| systemctl daemon-reload
systemctl start repmgrd.service
systemctl enable repmgrd.service
systemctl status repmgrd.service
|
方案二:nohup 后台运行(临时测试用)
1 2
| nohup repmgr -f /etc/repmgr.conf > /dev/null 2>&1 &
|
4.8 验证集群状态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
repmgr -f /etc/repmgr.conf cluster show
repmgr -f /etc/repmgr.conf cluster event
repmgr -f /etc/repmgr.conf standby switchover
repmgr -f /etc/repmgr.conf standby promote
|
5. 安装配置 Keepalived(VIP 漂移)
💡 Keepalived 的作用: 提供一个虚拟 IP(VIP),自动绑定到当前的主库上。业务应用只需连接这个 VIP,不用关心主库是哪台服务器。
5.1 安装 Keepalived(主、备节点执行)
1 2
| yum install -y keepalived
|
5.2 创建 PostgreSQL 健康检查脚本
文件 check_postgres_healthy.sh — 路径:/usr/local/pgsql16/check_postgres_healthy.sh
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| #!/bin/bash
result=$(psql -t -c "SELECT pg_is_in_recovery();" 2>/dev/null | tr -d ' ')
if [[ "$result" == "f" ]]; then exit 0 else exit 1 fi
|
1 2
| chmod +x /usr/local/pgsql16/check_postgres_healthy.sh
|
5.3 配置 Keepalived
主节点配置
文件 keepalived.conf — 路径:/etc/keepalived/keepalived.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
| # ============================================================ # 全局定义 # ============================================================ global_defs { route_id pg_primary # ← 路由标识(用于 SMTP 告警,一般不改) script_user postgres # ← 健康检查脚本以 postgres 用户执行 }
# ============================================================ # VRRP 健康检查脚本定义 # ============================================================ vrrp_script check_postgres { script "/usr/local/pgsql16/check_postgres_healthy.sh" interval 2 # ← 每 2 秒执行一次健康检查 weight -50 # ← 检查失败时,当前节点优先级降低 50 # 这样备库(priority 90)就比主库(100-50=50)高 # VIP 会自动漂移到备库 }
# ============================================================ # VRRP 实例配置(核心) # ============================================================ vrrp_instance VI_1 { state BACKUP # ← 使用 BACKUP 模式(非抢占模式) # 主备都设为 BACKUP,配合 nopreempt nopreempt # ← 禁止抢占! # 🔑 关键:旧主库恢复后不会抢回 VIP # 避免 repmgr 已切换主库但 VIP 又漂回去的混乱 interface ens3 # ← 绑定的网卡名(用 ip a 查看你的网卡名) virtual_router_id 51 # ← VRRP 组 ID,主备必须相同(范围 1-255) priority 100 # ← 初始优先级(主库 100,备库 90) # 优先级高的持有 VIP advert_int 1 # ← VRRP 通告间隔(秒) # 每 1 秒主备互发心跳包
# ============================================================ # VRRP 认证(主备必须一致) # ============================================================ authentication { auth_type PASS # ← 认证类型:PASS(简单密码)或 AH(加密) auth_pass 1111 # ← ⚠️ 生产环境务必改为复杂密码! }
# ============================================================ # 虚拟 IP 地址 # ⚠️ 必须替换为你的实际 VIP,格式:IP/子网掩码位数 # 例如:192.168.184.200/24 # ============================================================ virtual_ipaddress { x.x.x.x/x # ← 👈 把你的 VIP 填在这里! }
# ============================================================ # 关联健康检查脚本 # ============================================================ track_script { check_postgres # ← 调用上面定义的检查脚本 } }
|
备节点配置
文件 keepalived.conf — 路径:/etc/keepalived/keepalived.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| global_defs { route_id pg_standby script_user postgres }
vrrp_script check_postgres { script "/usr/local/pgsql16/check_postgres_healthy.sh" interval 2 weight -50 }
vrrp_instance VI_1 { state BACKUP nopreempt interface ens3 virtual_router_id 51 # ← 必须和主节点相同! priority 90 # ← 备库优先级比主库低 10 advert_int 1
authentication { auth_type PASS auth_pass 1111 # ← 必须和主节点相同! }
virtual_ipaddress { x.x.x.x/x # ← 必须和主节点相同! }
track_script { check_postgres } }
|
5.4 启动 Keepalived
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| systemctl start keepalived
systemctl enable keepalived
systemctl status keepalived
ip addr show ens3
journalctl -u keepalived -f
|
6. 集群验证测试
6.1 基础检查清单
1 2 3 4 5 6 7 8 9 10 11 12 13
| repmgr -f /etc/repmgr.conf cluster show
psql -U repmgr -d repmgr -c "CREATE TABLE test_cluster(id int, msg text);" psql -U repmgr -d repmgr -c "INSERT INTO test_cluster VALUES(1, 'hello cluster');"
psql -U repmgr -d repmgr -c "SELECT * FROM test_cluster;"
ip addr show | grep <VIP地址>
|
6.2 故障转移模拟测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
systemctl stop postgresql
tail -f /home/postgres/repmgrd.log
repmgr -f /etc/repmgr.conf cluster show
ip addr show | grep <VIP地址>
systemctl start postgresql repmgr -f /etc/repmgr.conf standby follow
|
7. 故障处理:脑裂修复
⚠️ 脑裂是什么? 主备之间的网络断了,备库以为主库挂了就自己升级成主库。结果变成了两个主库,各自接受写入,数据就彻底乱了。这是最严重的数据库故障。
7.1 如何发现脑裂?
1 2
| repmgr -f /etc/repmgr.conf cluster show
|
7.2 修复方案一:保留数据最完整的节点(推荐)
适用于有一方数据更新、另一方数据较旧的情况。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
|
psql -U repmgr -d repmgr -c "SELECT pg_current_wal_lsn();"
systemctl stop repmgrd.service systemctl stop postgresql.service
pg_rewind -D /usr/local/pgsql16/data \ --source-server="host=192.168.184.123 user=repmgr dbname=repmgr" -P
systemctl start postgresql.service
repmgr -f /etc/repmgr.conf standby register --force repmgr -f /etc/repmgr.conf standby follow --force
systemctl start repmgrd.service
repmgr cluster show
|
7.3 修复方案二:删除脑裂节点重建
适用于数据差别不大或修复方案一失败的情况。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
su - postgres
sudo systemctl stop postgresql
rm -rf /usr/local/pgsql16/data/*
repmgr -h 192.168.184.123 -U repmgr -d repmgr -p 5432 standby clone --force
sudo systemctl start postgresql
repmgr standby register -f /etc/repmgr.conf --force
systemctl restart repmgrd.service
|
8. 常用命令速查
8.1 PostgreSQL
| 命令 |
说明 |
systemctl start postgresql |
启动 PostgreSQL |
systemctl stop postgresql |
停止 PostgreSQL |
systemctl restart postgresql |
重启 PostgreSQL |
systemctl status postgresql |
查看运行状态 |
psql -U repmgr -d repmgr |
以 repmgr 用户连接 repmgr 库 |
pg_ctl reload |
重新加载配置文件(不重启) |
8.2 repmgr
| 命令 |
说明 |
repmgr -f /etc/repmgr.conf cluster show |
查看集群各节点状态 |
repmgr -f /etc/repmgr.conf cluster event |
查看集群事件历史 |
repmgr -f /etc/repmgr.conf node status |
查看当前节点状态 |
repmgr -f /etc/repmgr.conf node check |
检查当前节点配置是否正确 |
repmgr -f /etc/repmgr.conf standby switchover |
计划内主备切换(安全) |
repmgr -f /etc/repmgr.conf standby promote |
紧急提升备库为主库(有脑裂风险) |
repmgr -f /etc/repmgr.conf standby follow |
让备库跟随新主库 |
repmgr -f /etc/repmgr.conf standby clone -h <主库IP> -U repmgr -d repmgr |
从主库克隆数据 |
8.3 Keepalived
| 命令 |
说明 |
systemctl start keepalived |
启动 Keepalived |
systemctl stop keepalived |
停止 Keepalived |
systemctl status keepalived |
查看运行状态 |
ip addr show | grep <VIP> |
查看 VIP 在哪个节点上 |
journalctl -u keepalived -f |
实时查看 Keepalived 日志 |
8.4 故障排查命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| tail -100 /home/postgres/repmgrd.log
tail -100 /usr/local/pgsql16/data/log/postgresql-*.log
psql -U repmgr -d repmgr -c "SELECT * FROM pg_stat_replication;"
psql -U repmgr -d repmgr -c "SELECT * FROM pg_stat_wal_receiver;"
psql -U repmgr -d repmgr -c "SELECT application_name, pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS lag_bytes FROM pg_stat_replication;"
|
🔒 安全建议
- 修改默认密码: 所有
Aa_123qwe、1111、repmgr 密码务必在部署后修改为强密码
- 限制网络访问:
pg_hba.conf 中的 IP 范围尽量精确,避免使用 0.0.0.0/0
- .pgpass 文件权限: 严格设为
600,否则 PostgreSQL 会无视该文件
- Keepalived 认证密码: 使用复杂密码(建议 8 位以上随机字符串)
- SSL 连接: 生产环境应启用 SSL 加密数据库连接
- 定期备份: 集群 ≠ 备份!高可用不能替代备份策略
🎯 快速部署顺序总结
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| 1. 三台服务器编译安装 PostgreSQL 16.0 2. 三台服务器创建 postgres 用户、配置环境变量 3. 主节点 + 见证节点初始化数据库 4. 配置主节点的 postgresql.conf + pg_hba.conf 5. 配置见证节点的 postgresql.conf + pg_hba.conf 6. 三台服务器配置 systemd 服务 + 防火墙 + 创建 repmgr 用户 7. 三台服务器编译安装 repmgr 8. 分别配置三个节点的 repmgr.conf 9. 配置 sudo + SSH 互信 + .pgpass 10. 注册主节点 → 克隆+注册备节点 → 注册见证节点 11. 三台服务器启动 repmgrd 12. 主备节点安装配置 Keepalived(含健康检查脚本) 13. 启动 Keepalived → 验证 VIP 漂移 14. 执行完整的功能验证和故障切换测试
|
📝 文档版本: v2.0(优化版)
📅 更新日期: 2026-07-21
📋 原始来源: 有道云笔记 - pgsql集群(keepalived+repmgr+postgresql)