信创环境下PostgreSQL高可用架构实践

难度:高级 阅读时间:约 16 分钟 更新日期:2026-06-09

目录

  1. 信创替代背景与选型依据
  2. PG流复制+Patroni高可用架构
  3. 国产OS适配性验证步骤
  4. 性能调优与监控
  5. 故障演练与恢复验证

一、信创替代背景与选型依据

在金融、能源、政务等关键信息基础设施领域,Oracle/MySQL 商业替换已成为政策强制要求。PG 凭借协议兼容 MySQL(pg_dump、FDW)、ACID 完整、插件生态丰富,成为信创替换首选。

核心选型维度对比:

维度OracleMySQL(社区版)PostgreSQL 16
ACID 支持完整仅 InnoDB完整(MVCC 全链路)
复杂查询能力最强强(窗口函数、CTE)
JSON 支持需付费基础原生 JSONB(索引优化)
高可用方案RAC(昂贵)MGR/PXC流复制+Patroni(免费)
国产适配关闭授权部分UOS/Kylin 旗舰适配
⚠️ 信创合规要点:选择 PG 时,需确认是否具备国密算法支持(pgcrypto 插件)和等保三级认证的配套运维工具。

二、PG流复制+Patroni高可用架构

2.1 架构拓扑

// 推荐架构(3节点)
// +------------------+     +------------------+     +------------------+
// |  pg-node-1       |     |  pg-node-2       |     |  pg-node-3       |
// |  (Primary)       |<--->|  (Replica)       |<--->|  (Replica)       |
// |  192.168.1.10    |     |  192.168.1.11    |     |  192.168.1.12    |
// |  :5432           |     |  :5432           |     |  :5432           |
// +--------+---------+     +------------------+     +------------------+
//          |
// +--------+---------+
// |  etcd-1          |   // etcd 集群(3节点,保存 leader 状态)
// |  192.168.1.20    |
// +-------------------+
// 访问层:HAProxy --> 自动路由到 Primary :5432

// etcd 自动主从切换原理:
// 1. 节点挂掉 → etcd 失去心跳 10s
// 2. etcd 发起 Leader Election
// 3. 剩余节点数 >= 2 时可选出新 Primary
// 4. Patroni 执行 promote,新主从备升至 Active
// 5. HAProxy 自动更新后端(通过 API 或 Consul Template)

2.2 环境初始化(3台服务器)

// 每台服务器执行(替换 hostname)
// pg-node-1: export NODE_NAME=pg1; PG_VERSION=16
// pg-node-2: export NODE_NAME=pg2
// pg-node-3: export NODE_NAME=pg3

// 1. 安装依赖(以 Ubuntu/Kylin 为例)
apt-get update && apt-get install -y \
  postgresql-16 postgresql-contrib-16 postgresql-16-repack \
  etcd patroni python3-yaml haproxy curl

// 2. 配置 etcd(/etc/etcd/etcd.conf)
ETCD_NAME=$NODE_NAME
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.1.20:2379"
ETCD_INITIAL_CLUSTER="pg1=http://192.168.1.10:2380,pg2=http://192.168.1.11:2380,pg3=http://192.168.1.12:2380"
ETCD_INITIAL_CLUSTER_TOKEN="pg-ha-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

// 3. 启动 etcd
systemctl enable etcd && systemctl start etcd
etcdctl --endpoints=http://192.168.1.10:2379 member list
// 预期:3个成员状态 healthy

2.3 Patroni 配置

# /etc/patroni.yml (pg-node-1 示例)
scope: pg-ha-cluster
namespace: /service/
name: pg1

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

etcd:
  hosts: 192.168.1.10:2379,192.168.1.11:2379,192.168.1.12:2379

bootstrap:
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576  # 1MB,防止脑裂
    postgresql:
      use_pg_rewind: true
      parameters:
        max_connections: 200
        shared_buffers: 4GB
        wal_level: replica
        hot_standby_feedback: on
        max_wal_senders: 10
        max_replication_slots: 10

postgresql:
  listen: 0.0.0.0:5432
  connect_address: 192.168.1.10:5432
  data_dir: /var/lib/postgresql/16/main
  authentication:
    replication:
      username: replicator
      password: "replicator_pass"  # 生产用 Vault 管理
    superuser:
      username: postgres
      password: "your_secure_password"
    rewind:
      username: rewind_user
      password: "rewind_pass"

2.4 HAProxy 负载均衡

# /etc/haproxy/haproxy.cfg
global
    log /dev/log local0
    maxconn 2000

defaults
    log     global
    mode    tcp
    timeout connect 10s
    timeout client  1m
    timeout server  1m

frontend pg_front
    bind *:5432
    default_backend pg_back

backend pg_back
    option httpchk GET /master
    http-check expect status 200
    server pg1 192.168.1.10:5432 check port 8008
    server pg2 192.168.1.11:5432 check port 8008 backup
    server pg3 192.168.1.12:5432 check port 8008 backup

三、国产OS适配性验证

3.1 适配要点

统信 UOS 1060a麒麟 V10 SP1 为测试基准,PG16 均适配良好。但仍需关注:

验证项Ubuntu 22.04UOS 1060a麒麟 V10
apt 安装 PG16原生支持需添加 UOS 源需添加 Kylin 源
systemd 服务可用可用(rc.d)可用(rc.d)
glibc 兼容性2.352.31(需验证)2.31(需验证)
openEuler 适配N/AN/A原生支持
国密插件(sha2)需自编译需自编译需自编译

3.2 UOS 下添加 PG 源

// UOS 1060a 添加 PostgreSQL 官方源
cat <<'EOF' | sudo tee /etc/apt/sources.list.d/pgdg.list
deb http://apt.postgresql.org/pub/repos/apt/ focal-pgdg main
EOF

wget -qO - https://www.postgresql.org/media/keys/ACCC4CF8.asc | \
  sudo apt-key add -
sudo apt update
sudo apt install -y postgresql-16 postgresql-client-16

// 验证
pg_lsclusters
# 预期:Ver Cluster Port Status Owner Data directory
#       16 main    5432 online   postgres /var/lib/postgresql/16/main

四、性能调优与监控

4.1 核心参数

# postgresql.conf 核心调优(生产环境)
shared_buffers = 4GB           # 约总内存的 25%(16G机器)
work_mem = 64MB                # 复杂排序/哈希用
maintenance_work_mem = 512MB   # VACUUM/CREATE INDEX
effective_cache_size = 12GB    # 约总内存的 75%
random_page_cost = 1.1         # SSD 下调(默认4.0机械盘)
effective_io_concurrency = 200 # SSD

# 信创环境强制
ssl = on
ssl_cert_file = '/etc/ssl/certs/server.crt'
ssl_key_file = '/etc/ssl/private/server.key'

# 监控
shared_preload_libraries = 'pg_stat_statements,pg_stat_kcache'

4.2 pg_stat_statements 分析

-- 查找最耗时的 SQL(Top 10)
SELECT
  substring(query, 1, 60) AS short_query,
  round(total_exec_time::numeric, 2) AS total_time,
  calls,
  round(mean_exec_time::numeric, 2) AS mean_time,
  round(max_exec_time::numeric, 2) AS max_time
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

-- 发现慢查询后,创建索引
CREATE INDEX CONCURRENTLY idx_orders_created_at
  ON orders (created_at);

五、故障演练与恢复验证

5.1 手动触发主从切换

// 在 pg-node-1 (主) 上执行,模拟主节点宕机
patronictl pause pg-ha-cluster  # 暂停自动选主(观察用)

// 在 pg-node-2 上:手动提升
patronictl switch pg-ha-cluster --master pg2  # 强制切换到 pg2

// 确认 pg2 状态
patronictl list pg-ha-cluster
# 预期:Member -- Leader -- Member state
#       pg1   -- pg2   -- Stop leader's gracefull switchover
#       pg2   -- pg2   -- Master -- running
#       pg3   -- pg2   -- Secondary -- running

// 恢复 pg1:
patronictl resume pg-ha-cluster
# pg1 会自动跟随 pg2 变为 Replica,无需手动干预
🚫 常见失误
1. 未启用 synchronous_commit:主节点宕机时可能丢失最后 1-2 条 WAL,导致数据丢失。生产环境的正确设置:synchronous_commit = on + synchronous_standby_names = 'ANY 2 (pg2, pg3)'
2. 未测试脑裂恢复:必须每季度执行一次"kill 主节点 → 确认副主提升 → 原主恢复 → 确认同步"的全流程。
3. 备份策略缺失:流复制保护的是"机器故障",不保护"误删数据"。需要单独配置每日 pg_dump + pg_basebackup。

扩展:监控与可观测性方案

PG HA 集群的监控需要覆盖两层:PG 实例层和 Patroni 协调层:

# pg_exporter 采集的配置(prometheus.yml)
scrape_configs:
  - job_name: 'postgresql'
    static_configs:
      - targets: ['pg-node-1:9187', 'pg-node-2:9187', 'pg-node-3:9187']
    
  - job_name: 'patroni'
    static_configs:
      - targets: ['pg-node-1:8008', 'pg-node-2:8008', 'pg-node-3:8008']

扩展:信创环境下的网络隔离策略

金融和政务场景通常要求数据库层网络隔离:PG 集群仅允许内网访问,外部通过安全网关路由:

# pg_hba.conf 限制:仅允许 Patroni 节点和 HAProxy 访问
# TYPE  DATABASE        USER            ADDRESS                 METHOD
local   all             all                                     peer
host    all             replicator      192.168.1.11/32         md5
host    all             replicator      192.168.1.12/32         md5
host    all             proxy_user      192.168.1.100/32        md5  # HAProxy only
host    all             all             0.0.0.0/0               reject  # 拒绝所有其他连接

# 同时配置主机防火墙
iptables -A INPUT -p tcp --dport 5432 -s 192.168.1.0/24 -j ACCEPT
iptables -A INPUT -p tcp --dport 5432 -j DROP

总结

信创环境下的 PG HA 方案已经非常成熟:Patroni 提供自动选主与故障转移,etcd 提供集群状态共识,HAProxy 提供透明路由。关键指标:RTO(恢复时间目标)< 30秒(自动切换,依赖 etcd 心跳)、RPO(恢复点目标)= 0(全同步复制模式)。经过充分故障演练后,该架构可支撑信创系统生产级 SLA。

扩展:PG 在金融生产环境中的迁移策略

将现有业务从 Oracle 迁移到 PG 时,推荐使用双写迁移方案而非一次性切换:

第一阶段进行数据库克隆,在新 PG 集群上构建和旧库结构一致的数据副本。使用 dblink 或 CDC 工具(如 pglogical)实现主库到 PG 的实时同步。这个阶段需要验证数据一致性,对关键字段进行逐行比对,确保数值精度、字符编码、时区处理等细节完全一致。

第二阶段开启双写模式,业务代码在写入主库的同时异步写入 PG 集群。通过配置读写分离,逐步将查询流量切换到 PG。通常先切 10% 的只读流量,观察 48 小时后确认无误,再逐步提升到 50%、80%,最终 100% 切换到 PG 集群。

整个过程需要配合完善的回滚方案。双写期间主库和 PG 都保持可写状态,如果发现严重问题可以立即切回主库,业务几乎无感知。

扩展:数据库加密与备份策略

透明数据加密(TDE)

信创场景要求数据落盘加密。PG 16 原生支持 TDE(需企业版或社区补丁):

-- 开启 TDE(PG16+)
ALTER SYSTEM SET tde.enabled = on;
ALTER SYSTEM SET tde.encryption_algorithm = 'aes-256-gcm';
SELECT pg_reload_conf();

-- 创建加密表空间(敏感数据专用)
CREATE TABLESPACE encrypted_ts LOCATION '/data/tde' OWNER postgres;

-- 创建表时指定加密表空间
CREATE TABLE payment_orders (...) TABLESPACE encrypted_ts;

定时备份方案

#!/bin/bash
# /etc/cron.daily/pg-backup.sh
BACKUP_DIR="/data/pg-backups"
DATE=$(date +%Y%m%d_%H%M%S)

# 全量备份(Base Backup)
pg_basebackup -h localhost -U postgres \
  -D ${BACKUP_DIR}/base-${DATE} \
  -Ft -z -P --wal-method=stream

# 保留最近 7 天
find ${BACKUP_DIR} -name "base-*" -mtime +7 -delete

# 逻辑备份关键表(可单独恢复)
pg_dump -U postgres payment_db -t orders -t transactions \
  -f ${BACKUP_DIR}/orders-${DATE}.sql.gz --compress=9
最佳实践:Base Backup + WAL Archive 组合,RPO = 0(任意时间点恢复)。WAL 归档至独立存储(如对象存储、带 RAID 的 NFS)。

扩展:国内可替代生态对比

组件PG生态方案信创兼容备注
中间件PgBouncerUOS/Kylin OK轻量连接池
HA协调etcd / RepmgrUOS OK, Kylin 需 dockerPatroni 封装了 etcd 交互
监控pgwatch2 / Datadog agent需国产化改造pgwatch2 有 UI 界面
延迟复制pglogical extensionPG 15+ OK用于审计跟踪
分片Citus (PG Extension)UOS/Kylin OK水平扩展首选