PostgreSQL流复制配置实战:主从同步与Patroni自动故障转移搭建

PostgreSQL流复制架构:WAL日志与同步机制

PostgreSQL数据库高可用架构的核心是流复制(Streaming Replication)。主库将WAL(Write-Ahead Log)日志实时传输到备库,备库接收后回放日志保持数据一致。与MySQL基于binlog的复制不同,PostgreSQL流复制传输的是物理WAL记录,备库是主库的完整物理副本,包含所有数据文件、索引和控制文件。

流复制支持两种模式:异步复制和同步复制。异步模式下主库写入WAL后立即返回客户端确认,不等备库接收,性能最优但存在数据丢失窗口。同步模式下主库等待至少一个备库确认接收WAL后才返回,数据零丢失但写入延迟增加。生产环境通常采用同步复制+自动故障转移(Patroni)的组合方案。

主库配置:WAL归档与复制权限

流复制的前提是正确配置WAL相关参数。以下为生产环境推荐的postgresql.conf配置:

# postgresql.conf (主库)
listen_addresses = '*'
port = 5432
max_connections = 200
shared_buffers = 8GB
effective_cache_size = 24GB
work_mem = 64MB

# WAL配置
wal_level = replica              # 流复制最低要求
max_wal_senders = 10             # 最大WAL发送进程数
wal_keep_size = 2048             # 保留2GB WAL供备库追赶
hot_standby = on                 # 允许备库查询(虽然主库不需要,但后续可能切换角色)
archive_mode = on                # 开启归档
archive_command = 'cp %p /data/pg_archive/%f'
max_replication_slots = 10       # 复制槽数量

# 同步复制配置
synchronous_standby_names = 'FIRST 1 (standby1)'  # 至少1个备库同步
# 或使用 '*' 表示任意备库

# 性能相关
checkpoint_timeout = 15min
max_wal_size = 4GB
min_wal_size = 1GB
wal_compression = on             # WAL压缩传输,节省带宽
wal_sender_timeout = 60s         # WAL发送超时

创建专用复制用户并赋予复制权限:

-- 在主库执行
CREATE ROLE replicator WITH REPLICATION LOGIN PASSWORD 'ReplSecure@2026';

-- pg_hba.conf 添加复制连接规则
-- host  replication  replicator  192.168.1.0/24  scram-sha-256

-- 创建复制槽(防止备库断连后WAL被清理)
SELECT pg_create_physical_replication_slot('standby1_slot');

复制槽的作用是确保主库不清理备库尚未接收的WAL。无复制槽时,若备库断连时间过长,主库可能清理掉旧WAL导致备库无法追上,需要重建。复制槽的代价是WAL堆积——备库长期断连会导致主库磁盘撑满。需监控复制槽的活跃状态,及时清理过期槽。

备库搭建:pg_basebackup初始化与流复制启动

使用pg_basebackup从主库拉取基础备份,是搭建流复制备库的标准方式:

# 1. 停止备库PostgreSQL服务
systemctl stop postgresql

# 2. 清空备库数据目录
rm -rf /var/lib/postgresql/15/main/*

# 3. 从主库拉取基础备份
pg_basebackup \
  -h 192.168.1.10 \
  -p 5432 \
  -U replicator \
  -D /var/lib/postgresql/15/main \
  -Fp -Xs -P -R \
  -S standby1_slot

# 参数说明:
# -Fp: plain格式,直接写入文件系统
# -Xs: 使用stream方式传输WAL
# -P: 显示进度
# -R: 自动创建standby.signal和配置连接信息
# -S: 指定复制槽

-R参数会在数据目录下生成standby.signal文件和postgresql.auto.conf,后者包含primary_conninfo连接信息。手动配置方式:

# postgresql.auto.conf (备库自动生成)
primary_conninfo = 'host=192.168.1.10 port=5432 user=replicator password=ReplSecure@2026 application_name=standby1'
primary_slot_name = 'standby1_slot'

# 备库postgresql.conf
hot_standby = on              # 允许备库只读查询
max_standby_streaming_delay = 30s   # 备库查询与主库冲突时的等待时间
max_standby_archive_delay = 30s
# 4. 启动备库
systemctl start postgresql

# 5. 验证流复制状态(在主库执行)
SELECT
    client_addr,
    application_name,
    state,
    sync_state,
    sent_lsn,
    write_lsn,
    flush_lsn,
    replay_lsn,
    write_lag,
    flush_lag,
    replay_lag
FROM pg_stat_replication;

-- 正常输出示例:
-- client_addr: 192.168.1.11
-- application_name: standby1
-- state: streaming
-- sync_state: sync
-- write_lag: 00:00:00.001
-- flush_lag: 00:00:00.003
-- replay_lag: 00:00:00.005

四个LSN字段反映复制进度:sent_lsn是主库已发送的WAL位置,write_lsn是备库已写入的,flush_lsn是已刷盘的,replay_lsn是已回放完成的。理想状态下四者应该接近,差距过大说明备库存在延迟。三个lag字段以秒为单位量化延迟,write_lag是写入延迟,flush_lag是刷盘延迟,replay_lag是回放延迟。

Patroni自动故障转移:集群管理与主从切换

PostgreSQL原生不提供自动故障转移。Patroni是主流的高可用管理工具,基于etcd/ZooKeeper/Consul作为分布式配置存储,实现自动健康检查和主从切换。Patroni架构中每个节点运行Patroni守护进程,定期向DCS上报状态,主库持有leader锁。主库故障时,备库竞争leader锁完成切换。

Patroni配置文件patroni.yml:

scope: pg_cluster          # 集群名称
namespace: /service/      # DCS命名空间
name: node1               # 当前节点名

restapi:
  listen: 0.0.0.0:8008
  connect_address: 192.168.1.10:8008

etcd:
  hosts: 192.168.1.20:2379,192.168.1.21:2379,192.168.1.22:2379

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 20
    maximum_lag_on_failover: 1048576    # 1MB,故障转移时最大允许延迟
    synchronous_mode: true              # 同步模式
    postgresql:
      use_pg_rewind: true               # 允许pg_rewind修复旧主库
      parameters:
        wal_level: replica
        max_wal_senders: 10
        hot_standby: on
        synchronous_commit: on

postgresql:
  listen: 0.0.0.0:5432
  connect_address: 192.168.1.10:5432
  data_dir: /var/lib/postgresql/15/main
  bin_dir: /usr/lib/postgresql/15/bin
  authentication:
    superuser:
      username: postgres
      password: PgAdmin@2026
    replication:
      username: replicator
      password: ReplSecure@2026
  parameters:
    shared_buffers: 8GB
    max_connections: 200

tags:
  nofailover: false
  noloadbalance: false
  clonefrom: false
  replicatefrom: false

启动Patroni并检查集群状态:

# 启动Patroni
patroni /etc/patroni/patroni.yml &

# 查看集群状态
patronictl -c /etc/patroni/patroni.yml list

# 输出示例:
# + Cluster: pg_cluster (7000...) --+---------+----+-----------+
# | Member | Host          | Role    | State   | TL | Lag in MB |
# +--------+---------------+---------+---------+----+-----------+
# | node1  | 192.168.1.10  | Leader  | running | 12 |           |
# | node2  | 192.168.1.11  | Replica | streaming| 12 |         0 |
# | node3  | 192.168.1.12  | Replica | streaming| 12 |         0 |
# +--------+---------------+---------+---------+----+-----------+

# 手动切换主库(维护场景)
patronictl switchover /etc/patroni/patroni.yml

# 自动故障转移验证(模拟主库宕机)
systemctl stop postgresql  # Patroni会在loop_wait+retry_timeout后触发选举

故障转移后旧主库修复:pg_rewind操作

故障转移后,旧主库上的WAL与新主库可能分叉。直接将旧主库作为备库启动会报错。pg_rewind工具可以从新主库拉取差异WAL,将旧主库数据回退到分叉点,使其可以作为新主库的备库重新加入集群:

# 1. 停止旧主库PostgreSQL
systemctl stop postgresql

# 2. 执行pg_rewind
pg_rewind \
  --target-pgdata=/var/lib/postgresql/15/main \
  --source-server='host=192.168.1.11 port=5432 user=postgres password=PgAdmin@2026'

# 3. 更新primary_conninfo指向新主库
cat >> /var/lib/postgresql/15/main/postgresql.auto.conf << 'EOF'
primary_conninfo = 'host=192.168.1.11 port=5432 user=replicator password=ReplSecure@2026 application_name=node1'
primary_slot_name = 'node1_slot'
EOF

touch /var/lib/postgresql/15/main/standby.signal

# 4. 启动PostgreSQL(作为备库)
systemctl start postgresql

# 5. 确认Patroni接管
patronictl -c /etc/patroni/patroni.yml list

Patroni配置了use_pg_rewind: true时,故障恢复会自动执行pg_rewind。手动操作时需确保旧主库已完全停止,且源库(新主库)可通过复制连接访问。pg_rewind要求旧主库的postgresql.conf中启用了full_page_writes(默认开启),否则可能无法正确计算差异。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/postgresql-liu-fu-zhi-pei-zhi-shi-zhan-zhu-cong-tong-bu-yu/

(0)
小编小编
上一篇 19小时前
下一篇 19小时前

相关推荐