14.5 用 Pigsty 管理扩展可用性
Pigsty 能把仓库、包、配置和数据库声明统一管理,但平台声明不是 PostgreSQL 事实的替代品。正确用法是:
declare intent in Pigsty
-> converge nodes and databases
-> verify live package/config/catalog/query evidence本节以 Pigsty 4.4 文档为基线。参数与扩展目录会变化,目标集群变更前应使用 同版本文档和 inventory,而不是照抄本章时间点。
14.5.1 包、仓库、模板与节点差异
Pigsty 中的四步模型
当前 Pigsty 扩展文档把过程分成:
Download
从上游仓库取得包,或同步到本地仓库
Install
在 PGSQL cluster 的所有相关节点安装 OS 包
Configure
处理 shared_preload_libraries 和扩展参数
Create
在指定数据库执行 CREATE EXTENSION这与上一节三层状态一致:
| Pigsty 动作 | 主要对象 | 原生验证 |
|---|---|---|
| Download | repo/cache | repo metadata、artifact、checksum |
| Install | node package/files | package inventory、control/library |
| Configure | Patroni/PostgreSQL 参数 | pg_settings、restart、日志 |
| Create | database object | pg_extension、成员、查询 |
不是每个扩展都需要 preload,也不是每个已安装插件都需要创建数据库对象。
pg_packages 与 pg_extensions
Pigsty 4.4 文档区分:
pg_packages:
- pgsql-main pgsql-common
pg_extensions:
- postgis timescaledb pgvectorpg_packages:通用基础包组,通常用于所有 cluster 的核心组件;pg_extensions:特定 PGSQL cluster 需要的扩展软件包,初始化时安装, 也可对已存在 cluster 执行pg_extensiontag 收敛。
示例:
pg-meta:
hosts:
10.10.10.10: { pg_seq: 1, pg_role: primary }
10.10.10.11: { pg_seq: 2, pg_role: replica }
vars:
pg_cluster: pg-meta
pg_extensions: [pgvector]对于已运行 cluster,先修改受版本控制的声明,再执行目标明确的 playbook:
./pgsql.yml -l pg-meta -t pg_extension临时命令行覆盖:
./pgsql.yml -l pg-meta -t pg_extension \
-e '{"pg_extensions":["pgvector"]}'适合受控应急或实验,但若不回写 inventory,下一位维护者看不到持久意图。
参见 Pigsty: Install Extensions。
包别名是跨发行版映射
Pigsty 使用稳定别名:
pgvector
postgis
timescaledb映射到 PG major 与 OS 对应包,例如:
pgvector
-> pgvector_18* # EL
-> postgresql-18-pgvector # Debian/Ubuntu还提供 pgsql-rag、pgsql-gis、pgsql-fts 等类别别名。类别安装范围大,
实验便利不等于生产应一次装整类。生产 ADR 优先列精确候选,避免供应面无意
扩大。
包别名与 SQL 名必须在清单中同时保存:
| 项目 | package alias | SQL extension |
|---|---|---|
| pgvector | pgvector | vector |
| PostGIS | postgis | postgis、postgis_topology 等 |
| pg_trgm | 随 pgsql-main/默认包集合供应 | pg_trgm |
参见 Pigsty: Extension Package Aliases。
默认供应与默认启用不是同一层
Pigsty 4.4 当前默认文档说明:
pgvector随默认pgsql-main包集合安装;pg_trgm位于pg_default_extensions,默认在数据库的publicschema 启用;pg_stat_statements、auto_explain等进入默认 preload/观测集合。
这些默认值会随 Pigsty release 演进。目标环境要检查自身 inventory,而不是 从“4.4 默认”反推一个已升级多次的 cluster。
还要注意:若 pg_trgm 已在数据库 public 创建,就不能再在
app_ext 创建第二份同名扩展。自定义 schema 前必须协调
pg_default_extensions,不能让两个声明互相竞争。
参见 Pigsty: Default Extensions。
仓库可达性与本地仓库
在线环境可能直接从配置的上游/第三方仓库下载。受限环境通常由 Pigsty infra 节点维护本地软件仓库。无论哪种模式,验证:
inventory requests alias
-> alias resolves for OS + PG major + architecture
-> artifact exists in chosen repository snapshot
-> every PG node installs same build
-> future restore/new-node path can obtain it“主库现在有文件”不能证明:
- 新副本能加入;
- 灾备站点能恢复;
- 离线仓库仍保留旧版本;
- major upgrade 目标包已经可用。
扩展变更单应附 repo snapshot/version,而不只附公共下载 URL。
参见 Pigsty: Download Extensions。
节点漂移要按拓扑检查
至少覆盖:
primary
all synchronous/asynchronous standbys
delayed standby
disaster-recovery nodes
backup/restore worker image
future replacement node template可以用 Pigsty/Ansible 采包事实:
ansible pg-meta -b -a 'pig ext status -c -v 18'具体 pig 子命令以目标版本为准。更稳妥的检查还包括:
pg_config --version
pg_config --sharedir
pg_config --pkglibdir对 control/library 取 hash,结果按 host 保存。不要只看 play recap:
ok=...
changed=...它说明自动化执行状态,不说明数据库能加载文件。
漂移矩阵
| host | role | PG build | package build | control hash | library hash | preload live |
|---|---|---|---|---|---|---|
| pg-1 | primary | |||||
| pg-2 | replica | |||||
| pg-3 | replica |
任一 host 不同,先修供应层,不急着执行数据库 DDL。
14.5.2 声明安装与数据库内 CREATE EXTENSION
三个参数分别回答三个问题
pg_extensions: [pgvector]
pg_libs: 'pg_stat_statements, auto_explain'
pg_databases:
- name: pg36_shop
extensions:
- { name: vector, schema: app_ext }含义:
| 参数 | 问题 |
|---|---|
pg_extensions | cluster 节点要安装哪些扩展软件包 |
pg_libs | server 启动时要 preload 哪些库 |
pg_databases[].extensions | 某数据库要创建哪些 SQL extension |
三者不能互换:
- 把
vector写进pg_extensions会把 SQL 名误作包别名; - 只写
pgvectorpackage 不会自动保证每个已有数据库都创建对象; - 把不需 preload 的库塞进
pg_libs会增加启动耦合; - 只执行
CREATE EXTENSION,备库节点可能仍缺包。
Pigsty 当前数据库声明示例:
pg_databases:
- name: meta
extensions:
- { name: vector }
- { name: postgis, schema: public }
- { name: pg_stat_statements, schema: monitor }这里用的是 SQL extension name。参见 Pigsty: Create Extensions。
本章声明片段
pigsty-declaration.example.yml 刻意写成:
pg_extensions:
- pgvector
pg_databases:
- name: pg36_shop
schemas:
- { name: app_ext, owner: pg36_owner }
extensions:
- { name: vector, schema: app_ext }它没有重复声明 pg_trgm,因为 stock Pigsty 默认已经在 public 启用。
本地直连实验为了让 namespace 与成员集中可见,把:
pg_trgm + vector -> shop_ch14放在同一 schema。这是教学 fixture,不要求读者破坏 Pigsty 的合理默认。 平台实践可以是:
pg_trgm -> public (default)
vector -> app_ext (per-database declaration)只要 ADR、查询、dump 与权限证据反映真实布局。
声明不应夹带对象版本假设
仓库安装“最新可用包”与数据库对象 VERSION 是两个控制面。Pigsty 初始化
声明能创建扩展,但生产需要单独的 SQL migration:
CREATE EXTENSION vector
WITH SCHEMA app_ext
VERSION '0.8.4';或:
ALTER EXTENSION vector UPDATE TO 'reviewed-version';是否在 Pigsty YAML 固定 version 要以该版本参数 schema 和初始化实现为
准;即使声明能写版本,已有数据库升级仍应通过有证据的迁移流程,而不是
假设重新跑初始化会更新。
推荐职责:
Pigsty inventory:
repository/package/preload/database intent
SQL migration repository:
exact CREATE/ALTER statements
owner/schema/ACL
pre/post catalog and behavior assertions
evidence:
node + live config + database facts预加载变更的发布顺序
需要 preload 的扩展:
1. install package on every node
2. update pg_libs/parameters in inventory
3. apply Patroni/PostgreSQL config
4. rolling restart under HA policy
5. verify live setting and logs on every node
6. CREATE EXTENSION in intended databases
7. verify query/metrics/failover先 CREATE EXTENSION 再补 preload 可能直接失败;先改 preload 而节点缺库
可能导致 restart 失败。
本章两项扩展不要求 preload,因此声明不应为了“统一”加入它们。最小配置面 也是可靠性。
owner 与 schema
Pigsty 能创建角色、数据库与 schema;扩展 migration 仍要检查最终 owner:
SELECT
e.extname,
e.extversion,
pg_get_userbyid(e.extowner) AS owner,
n.nspname AS nominal_schema
FROM pg_extension AS e
JOIN pg_namespace AS n
ON n.oid = e.extnamespace;对 untrusted extension,管理员创建后可能由高权限角色拥有。不要为了让 应用迁移工具“方便”而把 extension owner 交给 LOGIN 应用角色。
已有 cluster 的收敛
不要只编辑 inventory 后等下一次重建:
review declaration diff
-> download/sync repository if needed
-> run package convergence on exact cluster
-> configure/restart if needed
-> run database migration
-> verify all layers
-> record evidence and commit identity如果 playbook 只能在部分节点成功,停止数据库对象更新,先修节点一致性。
14.5.3 从监控和日志识别加载失败
一张三层检查表
供应层
pg_config --version
pg_config --sharedir
pg_config --pkglibdir
# 目标文件存在、owner/mode 正确、hash 与基线一致数据库看到的 control:
SELECT
name,
default_version,
installed_version,
comment
FROM pg_available_extensions
WHERE name IN ('pg_trgm', 'vector');若查不到,先看 server 实际 sharedir,不要先查 search_path。
进程层
SELECT
name,
setting,
source,
sourcefile,
pending_restart
FROM pg_settings
WHERE name = 'shared_preload_libraries';再看每个实例启动日志:
could not access file ...
could not load library ...
undefined symbol ...
must be loaded via shared_preload_libraries ...配置声明、Patroni dynamic config、磁盘配置与 live setting 可能暂时不同。 以 live + restart history + log 为准。
数据库层
SELECT
current_database(),
e.extname,
e.extversion,
pg_get_userbyid(e.extowner),
n.nspname
FROM pg_extension AS e
JOIN pg_namespace AS n
ON n.oid = e.extnamespace;再查:
SELECT * FROM pg_extension_update_paths('pg_trgm');最后跑真正业务 probe。\dx 只证明 catalog 里有一行,不证明索引有效或
查询正确。
失败模式到动作
| 观察 | 解释 | 安全动作 |
|---|---|---|
pg_available_extensions 无记录 | 当前 server 看不到 control | 核对节点/PG major/安装目录 |
| available 有、installed 为空 | 包在,当前数据库未创建 | 走审批后的 CREATE EXTENSION |
| default > installed | 支持文件较新、对象仍旧 | 评审 update path,不自动升级 |
| installed 有、library 缺 | 节点漂移,failover 风险 | 阻断晋升,恢复 exact package |
pending_restart=true | 配置尚未生效 | 按 HA 策略滚动重启 |
| primary 成功、replica 加载失败 | 主备供应不一致 | 停止变更/晋升,修所有副本 |
must be owner | 生命周期权限边界生效 | 用受控 owner/admin migration |
must be superuser | untrusted/control 要求 | 管理员评审,禁止给 app 提权 |
| object already exists | schema/历史手工对象冲突 | 盘点依赖,禁止 CASCADE 硬装 |
| no update path | package 脚本图不支持 | 选择受支持中间版本或迁移方案 |
监控哪些事实
低基数状态:
extension_expected{cluster,db,name,version}
extension_installed{cluster,db,name,version}
extension_package_parity{cluster,name,build}
extension_preload_live{cluster,instance,name}
extension_probe_success{cluster,db,name}不要把每个 SQL 对象或 hash 都做成高基数时序标签。详细成员、文件 hash 和 包清单保存在 inventory/evidence;监控只暴露是否与期望一致,并链接 runbook。
事件/日志告警:
- postmaster 因库加载失败重启;
undefined symbol/ABI 错误;- extension update DDL 失败;
- recovery/replica 上 extension function 报错;
- extension 相关查询错误率突增;
- ANN/特殊索引 invalid;
- 更新后 P95/P99、WAL、内存、replica lag 越界。
L1 验证包
本章本地 evidence 明确写 pigsty_l1=not-run。在真实 L1 补齐:
00-inventory-commit.txt
01-repository-snapshot.txt
02-node-package-matrix.csv
03-control-library-hashes.csv
04-pg-settings-all-instances.csv
05-pg-available-versions.csv
06-pg-extension-all-databases.csv
07-member-and-index-catalog.csv
08-query-plan-and-correctness.txt
09-replica/failover-probe.txt
10-clean-restore-report.txt
11-reset-or-rollback-report.txt每份 evidence 带:
captured_at
cluster/database/host
server and package build
command/tool version
change/commit identity
operator凭证不得进入 evidence。
Pigsty 管理扩展的停止线
- inventory 别名无法解析到目标 OS/PG major;
- 本地仓库没有灾备/新节点需要的包;
- 任一 replica 包/hash 不一致;
- preload 变更未完成滚动重启;
- 只在
postgres数据库验证,业务数据库未盘点; - 默认
pg_trgm与自定义 schema 声明冲突; - playbook 成功但原生 catalog/query probe 失败;
- 没有 clean restore 与 major-upgrade 路线。
平台自动化可以缩短执行时间,不能降低验收标准。
本节结论
Pigsty 提供的是可声明、可重复的控制面:
package alias + cluster intent + preload + database declarationPostgreSQL 提供的是 live 数据面事实:
files + settings + pg_extension + members + query behavior两者一致,扩展才“可用”;再加升级、恢复和退出证据,才“可运营”。
上一节:生命周期与升级耦合 · 返回本章目录 · 下一节:建立可复用扩展 ADR · 查看全书目录 · 查看索引中心