跳至内容
14.5 用 Pigsty 管理扩展可用性

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 动作主要对象原生验证
Downloadrepo/cacherepo metadata、artifact、checksum
Installnode package/filespackage inventory、control/library
ConfigurePatroni/PostgreSQL 参数pg_settings、restart、日志
Createdatabase objectpg_extension、成员、查询

不是每个扩展都需要 preload,也不是每个已安装插件都需要创建数据库对象。

pg_packagespg_extensions

Pigsty 4.4 文档区分:

pg_packages:
  - pgsql-main pgsql-common

pg_extensions:
  - postgis timescaledb pgvector
  • pg_packages:通用基础包组,通常用于所有 cluster 的核心组件;
  • pg_extensions:特定 PGSQL cluster 需要的扩展软件包,初始化时安装, 也可对已存在 cluster 执行 pg_extension tag 收敛。

示例:

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-ragpgsql-gispgsql-fts 等类别别名。类别安装范围大, 实验便利不等于生产应一次装整类。生产 ADR 优先列精确候选,避免供应面无意 扩大。

包别名与 SQL 名必须在清单中同时保存:

项目package aliasSQL extension
pgvectorpgvectorvector
PostGISpostgispostgispostgis_topology
pg_trgmpgsql-main/默认包集合供应pg_trgm

参见 Pigsty: Extension Package Aliases

默认供应与默认启用不是同一层

Pigsty 4.4 当前默认文档说明:

  • pgvector 随默认 pgsql-main 包集合安装;
  • pg_trgm 位于 pg_default_extensions,默认在数据库的 public schema 启用;
  • pg_stat_statementsauto_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=...

它说明自动化执行状态,不说明数据库能加载文件。

漂移矩阵

hostrolePG buildpackage buildcontrol hashlibrary hashpreload live
pg-1primary
pg-2replica
pg-3replica

任一 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_extensionscluster 节点要安装哪些扩展软件包
pg_libsserver 启动时要 preload 哪些库
pg_databases[].extensions某数据库要创建哪些 SQL extension

三者不能互换:

  • vector 写进 pg_extensions 会把 SQL 名误作包别名;
  • 只写 pgvector package 不会自动保证每个已有数据库都创建对象;
  • 把不需 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 superuseruntrusted/control 要求管理员评审,禁止给 app 提权
object already existsschema/历史手工对象冲突盘点依赖,禁止 CASCADE 硬装
no update pathpackage 脚本图不支持选择受支持中间版本或迁移方案

监控哪些事实

低基数状态:

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 declaration

PostgreSQL 提供的是 live 数据面事实:

files + settings + pg_extension + members + query behavior

两者一致,扩展才“可用”;再加升级、恢复和退出证据,才“可运营”。


上一节:生命周期与升级耦合 · 返回本章目录 · 下一节:建立可复用扩展 ADR · 查看全书目录 · 查看索引中心

最后更新于