22.6 Pigsty 服务接入层
Pigsty 不发明 PostgreSQL 的主库、副本或 session 语义。它把:
组合成可交付实现。
理解 Pigsty 服务层的关键不是记命令,而是能把任何观察反向映射到原生组件。
22.6.1 服务定义、角色选择与端口
默认变量
本章参考实现的关键声明形态:
版本和自定义配置可能不同。读取实际 inventory、role defaults 与 rendered file,不要把这段当成跨版本常量。
dest
服务 destination 可以表达:
因此:
在本章 pg_default_service_dest=pgbouncer 时走连接池;如果用户改成
postgres,同一个 5433/5434 就绕过池。
端口名不能替实际路径。
check
check 是 Patroni REST health path:
HAProxy 对成员的 8008 检查,数据流则去 dest。角色判断来自 Patroni,
不是 HAProxy 解析 PostgreSQL protocol。
selector
selector 从 cluster member inventory 中选普通 backend。
表示全集。
offline 示例只选择:
这让平台能把特定 replica 标为重查询目标。selector 是期望集合,运行时健康 检查仍可能摘除不合格成员。
backup
backup selector 形成 HAProxy backup server。它决定正常集合不可用时是否 降级。
要把 backup 语义写进服务合同:
- replica 回 primary 是否允许;
- offline 回普通 replica 是否允许;
- backup 激活是否告警;
- 目标是否有容量;
- client
target_session_attrs会接受还是拒绝。
pg_service_provider
默认空值通常在每个 PostgreSQL node 上交付 local HAProxy service。
也可指定专用 HAProxy node group。此时要重新设计:
- provider 高可用;
- provider 到数据库网络;
- DNS/VIP/multi-host;
- config rollout;
- source IP/HBA;
- stats/metrics;
- 故障域。
把 HAProxy 从数据库节点移出,不自动获得入口 HA。
VIP 与 DNS
相关声明包括:
这是交付入口的机制选择。启用前要按第 22.1.3 节验证网络、仲裁、DNS cache 与证书,不能因为变量存在就宣称通过。
自定义业务服务
可以在 pg_services 添加服务,而不是修改默认列表。例如概念上:
生产声明还应补:
- backup/fail-closed;
- maxconn;
- balance;
- options/rise/fall;
- owner 和用途;
- TLS/网络;
- driver endpoint。
不要为每个应用随意开端口;只有语义或资源/失败域不同才需要新服务。
22.6.2 PgBouncer、HAProxy 与数据库的证据链
第一步:声明证据
从 reviewed inventory 提取 secret-free projection:
凭据值不进入报告,只记录:
第二步:rendered HAProxy
本章 /etc/haproxy/pg-test-*.cfg 投影:
同时核对:
只核对文件 diff 仍不够;进程可能未 reload 或 runtime state 不同。
第三步:HAProxy runtime
从 stats socket/API 看:
敏感 stats user/password 不输出。使用 local protected socket 比把管理页面凭据 写入脚本更安全。
第四步:PgBouncer config
在 local Unix admin socket:
本章 safe projection:
不要采集:
- password;
- SCRAM verifier;
- auth file 内容;
- inventory secret;
- admin credential。
数据库 LOGIN 不等于池化身份已交付
本章开发过程中故意撞到一个重要边界:
因为本章 Pigsty 默认:
PgBouncer authentication surface 由声明式用户清单管理。只有数据库 catalog 里存在 role,不等于 pooler 的 auth file/query 已经认识它。
生产用户应在 Pigsty pg_users 中声明并明确:
实际字段与 secret workflow 以当前版本文档和组织规范为准。不要手改
userlist.txt 制造不可追踪漂移。
本章 formal run 因此使用既有、Pigsty 已声明的 nonproduction test 用户,
只创建专属 schema/table;脚本永不修改或删除该 role。
若启用 pgbouncer_auth_query,还要评审:
auth_user与查询权限;- query 在 replica/primary 的行为;
- password rotation;
- role expiration;
- auth database;
- failover;
- secret exposure。
第五步:PostgreSQL 原生状态
对每个 member:
并观察连接预算:
pg_postmaster_start_time() 在本章用来把经过 local Unix socket 的 PgBouncer
session 映射回具体 member;inet_server_addr() 对 Unix backend 可能为空。
第六步:从 client 走完整路径
每个 service 用真实 database/user:
预期:
| service | recovery | read_only | path |
|---|---|---|---|
| primary 5433 | false | false | HAProxy → PgBouncer |
| replica 5434 | true | true | HAProxy → PgBouncer |
| default 5436 | false | false | HAProxy → PostgreSQL |
| offline 5438 | true | true | HAProxy → PostgreSQL |
再到每台 PgBouncer SHOW POOLS,证明 pooled endpoint 真正在对应 process
形成了 database/user pool。
第七步:行为证据
配置与角色通过后仍要测:
- 12-client/2-server queue;
- backend reassignment;
- session state 丢失/泄漏;
- protocol prepared;
- SQL PREPARE negative;
- async token visibility;
- planned switch/reconnect;
- final config/topology restore。
这才完成从声明到用户体验的链。
证据矩阵
| Claim | 声明 | 渲染 | runtime | SQL/client |
|---|---|---|---|---|
| 5433 主写 | service check/dest | primary cfg | backend status | writable |
| 5434 副本优先 | backup/selector | replica cfg | selected pool | read-only/member |
| 事务池 | pool mode | pgbouncer ini | SHOW CONFIG/POOLS | PID reassignment |
| 2 server cap | runtime override | N/A | sv_active ≤ 2 | 12 clients complete |
| prepared 支持 | max_prepared | SHOW CONFIG | two server PID | correct protocol results |
| switch recovery | Patroni/service | health config | topology/pool refresh | token reconcile |
22.6.3 配置变更、reload 与连接行为验证
不要直接编辑 rendered file
错误流程:
问题:
- inventory 不知道;
- 下次 automation 覆盖;
- 多节点不一致;
- review/rollback 不完整;
- secret/权限可能漂移。
正确流程:
service tag
参考代码中服务生成/reload 由 pg_service 相关 task/tag 管理,典型调用形态:
生产执行前必须按当前 Pigsty 版本查看 help/plan、限定 inventory 和 host。 不要从书中复制命令直接指向未知集群。
render task 会生成 service config,并在 reload 前运行 HAProxy config check。
配置校验
原生检查:
它证明语法/引用可加载,不证明路由语义正确。
PgBouncer reload:
不是所有配置都支持在线改变;某些需要 reconnect/restart。SHOW CONFIG 的
changeable 列与当前文档共同决定。
reload 与现有连接
必须回答:
“reload 成功”不能替代这些答案。
role change 与 config change 是两类变更
config change:
role change:
二者可能同时发生,但 rollback 不同。故障切换时不应顺手修改持久配置, 否则难以分辨恢复来自哪项动作。
本章 runtime pool override 只用于实验,并在切换前恢复,正是为了隔离变量。
staged rollout
多入口环境:
- 选一个无生产或低流量 provider;
- render/check;
- reload;
- direct health + client probe;
- 观察 queue/error/session;
- 扩到下一 provider;
- 完整端点矩阵;
- 保留旧配置与回滚。
若所有 provider 同时 reload,错误配置会同时摧毁入口冗余。
变更后的强制验证
如果变更涉及 role/promotion,再执行 pool role-state refresh 检查。
回滚
回滚不是把文件复制回去:
如果数据库 role 已在期间改变,旧 rendered config 的成员角色仍由 health check 动态判断,但 selector/backup/destination 可能不再合适,要重新评审。
secret 与证据
服务变更会接触:
- inventory password;
- PgBouncer userlist/verifier;
- HAProxy stats auth;
- TLS key;
- HBA/identity。
证据只保留:
不要把整个 inventory、auth file 或 config 原文无差别上传。正式 lab 对
临时 credential inventory 要求 mode 0600,使用后删除副本,报告
secret_values_exported=0。
本节检查表
参考资料
- Pigsty:PostgreSQL Service
- Pigsty:PgBouncer Administration
- PgBouncer:Configuration
- HAProxy:Configuration tutorials
上一节:连接预算与过载边界 · 返回本章目录 · 下一节:实战:写入、只读与管理三类接入 · 查看全书目录 · 查看索引中心