PostgreSQL通过流复制(Streaming Replication)实现主从同步,配合Patroni自动故障转移工具可以构建生产级高可用集群。数据库高可用架构设计的核心目标是:主节点故障时自动选举新主节点、数据零丢失、业务无感知切换。本文从流复制基础配置到Patroni集群编排,完整搭建PostgreSQL高可用方案。
PostgreSQL流复制原理与主节点配置
流复制是PostgreSQL原生支持的物理复制方式,主节点将WAL(Write-Ahead Log)日志流实时发送到备节点,备节点重放WAL实现数据同步。与逻辑复制不同,流复制是实例级全量复制,备节点为只读状态。数据库运维中,流复制常用于读负载分离和故障转移。同步级别通过synchronous_commit参数控制,remote_apply提供最强一致性保证。
# postgresql.conf - 主节点配置
wal_level = replica
max_wal_senders = 10
wal_keep_size = 1024 # 保留1GB WAL用于备节点追赶
synchronous_standby_names = 'FIRST 2 (pg-slave1, pg-slave2)'
synchronous_commit = remote_apply # 同步级别:remote_apply最高
archive_mode = on
archive_command = 'test ! -f /data/wal_archive/%f && cp %p /data/wal_archive/%f'
hot_standby = on
listen_addresses = '*'
port = 5432
# pg_hba.conf - 允许备节点连接
host replication replicator 10.0.1.0/24 md5
host all all 10.0.1.0/24 md5
# 创建复制用户
psql -c "CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'repl_pass';"
备节点搭建与基线备份初始化
备节点的搭建需要从主节点创建基线备份,然后配置recovery参数启动流复制。数据备份恢复中,pg_basebackup工具是创建物理备份的标准方法,它会在备节点创建standby.signal文件并配置primary_conninfo连接信息。
# 方法一:pg_basebackup(推荐)
pg_basebackup -h 10.0.1.10 -U replicator -D /data/pgdata -Fp -Xs -P -R
# -Fp: 平面文件格式
# -Xs: 流式传输WAL
# -P: 显示进度
# -R: 自动生成standby.signal和primary_conninfo配置
# 生成的postgresql.auto.conf内容
# primary_conninfo = 'host=10.0.1.10 port=5432 user=replicator password=repl_pass application_name=pg-slave1'
# primary_slot_name = 'slave1_slot'
# 方法二:手动创建基础备份
# 在主节点执行
psql -c "SELECT pg_start_backup('base_backup', true);"
# 复制数据目录到备节点
rsync -av /data/pgdata/ pg-slave1:/data/pgdata/
# 在主节点执行
psql -c "SELECT pg_stop_backup();"
# 备节点配置
# /data/pgdata/postgresql.auto.conf
primary_conninfo = 'host=10.0.1.10 port=5432 user=replicator password=repl_pass application_name=pg-slave1'
restore_command = 'cp /data/wal_archive/%f %p'
recovery_target_timeline = 'latest'
# 创建复制槽(防止WAL被过早清理)
psql -c "SELECT pg_create_physical_replication_slot('slave1_slot');"
# 启动备节点
pg_ctl -D /data/pgdata start
# 验证复制状态(主节点执行)
psql -c "SELECT * FROM pg_stat_replication;"
psql -c "SELECT application_name, state, sync_state, sent_lsn, write_lsn, flush_lsn, replay_lsn FROM pg_stat_replication;"
Patroni集群管理与自动故障转移配置
Patroni是PostgreSQL高可用管理工具,基于分布式配置存储(etcd/ZooKeeper/Consul)实现集群协调。当主节点故障时,Patroni自动选举最优备节点提升为新主,并更新连接路由。数据迁移实战中,Patroni支持手动switchover(计划内切换)和自动failover(故障切换)两种模式。
# patroni.yml - 节点1配置
scope: pg-cluster
name: pg-node1
restapi:
listen: 0.0.0.0:8008
connect_address: 10.0.1.10:8008
etcd:
hosts: 10.0.1.20:2379,10.0.1.21:2379,10.0.1.22:2379
bootstrap:
initdb:
- encoding: UTF8
- locale: C.UTF-8
- data-checksums
post_bootstrap: /opt/pg_scripts/post_bootstrap.sh
dcs:
ttl: 30
loop_wait: 10
retry_timeout: 20
maximum_lag_on_failover: 1048576
synchronous_mode: true
synchronous_mode_strict: false
postgresql:
use_pg_rewind: true
parameters:
wal_level: replica
max_wal_senders: 10
synchronous_commit: remote_apply
postgresql:
listen: 0.0.0.0:5432
connect_address: 10.0.1.10:5432
data_dir: /data/pgdata
bin_dir: /usr/lib/postgresql/16/bin
config_dir: /data/pgdata
pg_hba:
- host replication replicator 10.0.1.0/24 md5
- host all all 10.0.1.0/24 md5
authentication:
replication:
username: replicator
password: repl_pass
superuser:
username: postgres
password: pg_pass
parameters:
max_connections: 200
shared_buffers: 4GB
effective_cache_size: 12GB
work_mem: 64MB
maintenance_work_mem: 1GB
checkpoint_completion_target: 0.9
wal_buffers: 16MB
default_statistics_target: 100
random_page_cost: 1.1
effective_io_concurrency: 200
tags:
nofailover: false
noloadbalance: false
clonefrom: false
nosync: false
HAProxy连接路由与读写分离配置
Patroni配合HAProxy实现读写分离:写请求路由到主节点,读请求分发到备节点。HAProxy通过Patroni的REST API健康检查端点判断节点角色,动态调整后端路由。数据库高可用架构中,连接层的高可用是应用无感知切换的关键。
# haproxy.cfg
global
maxconn 2000
log /dev/log local0
defaults
log global
mode tcp
option tcplog
timeout connect 5s
timeout client 30s
timeout server 30s
# 主节点连接(写请求)
frontend pg_write
bind *:5432
default_backend pg_master
backend pg_master
option httpchk
httpchk GET /primary
server pg-node1 10.0.1.10:5432 check port 8008 inter 2s fall 2 rise 2
server pg-node2 10.0.1.11:5432 check port 8008 inter 2s fall 2 rise 2
server pg-node3 10.0.1.12:5432 check port 8008 inter 2s fall 2 rise 2
# 备节点连接(读请求)
frontend pg_read
bind *:5433
default_backend pg_replicas
backend pg_replicas
option httpchk
httpchk GET /replica
balance roundrobin
server pg-node1 10.0.1.10:5432 check port 8008 inter 2s fall 2 rise 2
server pg-node2 10.0.1.11:5432 check port 8008 inter 2s fall 2 rise 2
server pg-node3 10.0.1.12:5432 check port 8008 inter 2s fall 2 rise 2
故障转移测试与数据一致性验证
高可用方案上线前必须进行故障转移测试,验证切换时间和数据一致性。Patroni提供了switchover和failover两种切换方式。SQL查询优化场景中,备节点上的长查询可能影响切换速度,需要合理设置max_standby_streaming_delay参数。
# 手动switchover(计划内切换)
patronictl switchover --master pg-node1 --candidate pg-node2 --force pg-cluster
# 模拟主节点故障
# 在主节点停止PostgreSQL
pg_ctl -D /data/pgdata stop -m fast
# 观察Patroni自动failover
patronictl list pg-cluster
# +---------+--------+---------+----+-----------+
# | Member | Role | State | TL | Lag in MB |
# +---------+--------+---------+----+-----------+
# | pg-node1| Unkn | Stopped | | unknown |
# | pg-node2| Leader | Running | 12 | 0|
# | pg-node3| Replica| Streaming| 12 | 0|
# +---------+--------+---------+----+-----------+
# 验证数据一致性
# 在新主节点执行
psql -c "SELECT pg_current_wal_lsn();"
# 在备节点执行
psql -c "SELECT pg_last_wal_replay_lsn();"
# 检查复制延迟
psql -c "
SELECT application_name,
pg_wal_lsn_diff(pg_current_wal_lsn(), replay_lsn) AS lag_bytes,
state, sync_state
FROM pg_stat_replication;"
# 配置参数减少备节点查询对切换的影响
max_standby_streaming_delay = 30s
max_standby_archive_delay = 30s
hot_standby_feedback = on
PostgreSQL高可用架构的核心价值在于数据零丢失和业务连续性。流复制保证数据实时同步,Patroni实现自动故障转移,HAProxy完成连接路由。数据库运维中,定期演练故障转移流程是保障系统韧性的必要手段。配合pgBackRest或WAL-G进行物理备份,可以在极端故障场景下实现时间点恢复,进一步提升数据安全级别。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/postgresql-gao-ke-yong-jia-gou-shi-zhan-liu-fu-zhi-zhu-cong/