信创环境下PostgreSQL高可用架构实践
一、信创替代背景与选型依据
在金融、能源、政务等关键信息基础设施领域,Oracle/MySQL 商业替换已成为政策强制要求。PG 凭借协议兼容 MySQL(pg_dump、FDW)、ACID 完整、插件生态丰富,成为信创替换首选。
核心选型维度对比:
| 维度 | Oracle | MySQL(社区版) | PostgreSQL 16 |
|---|---|---|---|
| ACID 支持 | 完整 | 仅 InnoDB | 完整(MVCC 全链路) |
| 复杂查询能力 | 最强 | 弱 | 强(窗口函数、CTE) |
| JSON 支持 | 需付费 | 基础 | 原生 JSONB(索引优化) |
| 高可用方案 | RAC(昂贵) | MGR/PXC | 流复制+Patroni(免费) |
| 国产适配 | 关闭授权 | 部分 | UOS/Kylin 旗舰适配 |
二、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.04 | UOS 1060a | 麒麟 V10 |
|---|---|---|---|
| apt 安装 PG16 | 原生支持 | 需添加 UOS 源 | 需添加 Kylin 源 |
| systemd 服务 | 可用 | 可用(rc.d) | 可用(rc.d) |
| glibc 兼容性 | 2.35 | 2.31(需验证) | 2.31(需验证) |
| openEuler 适配 | N/A | N/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 实例监控:使用 pg_exporter 采集连接数、事务量、锁等待、WAL 延迟、复制延迟等关键指标。这些指标通过 Prometheus 聚合后,可以在 Grafana 中配置告警阈值。
- Patroni 协调层监控:Patroni 通过 REST API 暴露自身状态(/patroni 端点),监控其 leader 切换次数、etcd 通信延迟、Failover 触发原因等。
- 告警策略:复制延迟超过 5 秒触发 P2 告警、主节点宕机 10 秒未触发 Failover 触发 P1 告警、WAL 文件积累超过 1000 触发磁盘空间告警。
# 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
扩展:国内可替代生态对比
| 组件 | PG生态方案 | 信创兼容 | 备注 |
|---|---|---|---|
| 中间件 | PgBouncer | UOS/Kylin OK | 轻量连接池 |
| HA协调 | etcd / Repmgr | UOS OK, Kylin 需 docker | Patroni 封装了 etcd 交互 |
| 监控 | pgwatch2 / Datadog agent | 需国产化改造 | pgwatch2 有 UI 界面 |
| 延迟复制 | pglogical extension | PG 15+ OK | 用于审计跟踪 |
| 分片 | Citus (PG Extension) | UOS/Kylin OK | 水平扩展首选 |