30.6 用隔离环境完成升级彩排
第一次在真实数据、真实扩展、真实配置和真实运维入口上组合升级,不应发生在生产窗口。 隔离彩排的价值不是练熟命令,而是发现:
哪些前置条件不成立
哪一步真正控制停机时间
哪些结果必须由业务解释
回退边界何时消失
平台自动化覆盖了什么、没有覆盖什么30.6.1 克隆数据与版本化配置
克隆必须回答“像生产的哪一部分”
| 克隆方式 | 保真度 | 主要用途 | 风险 |
|---|---|---|---|
| schema + synthetic data | 对象高,分布低 | 快速 pg_upgrade --check、脚本开发 | 无法预测真实时长/plan |
| logical dump/restore | 逻辑对象与行高 | 新 major 兼容、清理物理布局 | 大库慢,需脱敏 |
| physical restore | page/WAL/物理布局高 | pg_upgrade 时长、完整性、恢复 | 敏感数据与存储成本 |
| storage snapshot clone | 速度快、物理高 | 重复彩排 | 一致性、tablespace/WAL 同步边界 |
| production-sized generated corpus | 分布可控 | 性能回归与极端边界 | 难覆盖真实历史异常 |
生产升级至少需要一次真实规模的物理/恢复克隆;日常 CI 可以使用 schema + deterministic fixture。无论哪种,记录:
source_system_identifier: ...
source_backup_or_snapshot: ...
source_lsn_and_timeline: ...
captured_at: ...
data_scope: full | subset | synthetic
anonymization_version: ...
excluded_objects: ...
size_manifest: ...脱敏不能破坏 join、skew、长度、locale 与唯一性分布,否则兼容测试会得到过于乐观的 结果。隔离网络、独立 secret、禁止邮件/支付/webhook/CDC 等外部副作用同样重要。
配置不是复制旧文件
Pigsty 中应把新 cluster 作为独立 inventory 对象,显式声明:
pg_cluster: pg-new
pg_version: 18
pg_packages:
- pgsql-main
- pgsql-common
pg_extensions:
- ...
pg_conf: oltp.yml实际变量名和包 alias 以当前 Pigsty 版本为准。关键原则是:
old rendered config -> inventory of intent
release-note parameter diff -> migration decisions
new-version template -> new rendered config
catalog/native views -> effective-value verification不要把旧 postgresql.conf、postgresql.auto.conf、pg_hba.conf 原样盖到新版本上。
这样会带入已删除参数、错误 include、旧路径与旧认证边界,还会绕过 Pigsty/Patroni 的
配置 ownership。
需要版本化的输入包括:
- Pigsty inventory commit 与模板/角色版本;
- PostgreSQL/extension/OS package lock 与摘要;
- effective
pg_settings、pg_file_settings、HBA 解析; - locale/ICU/libc/architecture;
- Patroni、pgBackRest、PgBouncer、HAProxy、exporter 版本与配置;
- schema/extension ADR、query corpus 和业务 invariant 版本。
不复制生产身份
克隆环境必须重写:
cluster_name / Patroni scope / DCS path
systemd/service identifiers
ports, VIP, DNS and HAProxy service
backup stanza/repository write target
archive_command and restore_command
replication slots/subscriptions
application secrets and external endpoints
monitoring labels否则一次彩排可能向生产 archive 写 WAL、争夺同一 DCS leader、消费真实 slot 或被应用 误连。第 19/23 章的环境 marker 与权限边界应在此复用。
30.6.2 执行升级、扩展更新和服务接入验证
彩排按正式状态机执行
建议阶段:
| 阶段 | 主要动作 | 必留证据 |
|---|---|---|
| software-ready | 仓库、binary、extensions、client tools | 版本、包摘要、所有节点矩阵 |
| clone-ready | 恢复/生成数据,隔离副作用 | source identity、manifest、restore log |
| preflight | catalog/config/collation/integrity/backup | check 报告与阻断项 |
| stop-old | drain writer,clean shutdown | 最终连接、LSN、checkpoint、时间 |
| upgrade | 指定实际模式执行 | 完整 stdout/stderr、每阶段时长 |
| post-process | 脚本、extension、reindex、ANALYZE | 对象清单、错误与耗时 |
| validate | SQL、应用、监控、备份恢复 | query corpus、invariant、SLO |
| rollback-proof | 目标零写入时启动旧端 | old identity、manifest、路由未变 |
| release | 接入服务并写 canary | target identity、pool drain、write boundary |
软件下载、包签名、镜像构建和克隆恢复不应计入业务不可写窗口;但它们必须计入项目 lead time。每个阶段同时记录 wall time、CPU、I/O、WAL、额外空间和锁。
Pigsty major upgrade 有两种平台映射
新集群 + 逻辑复制:
用新 pg_version 新建独立 Pigsty cluster
-> 按第 29 章迁移 schema/data/incremental
-> Pigsty service/proxy/dashboard 先行验证
-> 业务切流这通常最符合生产最小停机目标,也让旧 cluster 保持完整。
隔离 pg_upgrade / in-place 项目:
需要同时处理:
Patroni service lifecycle
old/new data and binary paths
primary/standby upgrade or rebuild
pgBackRest stanza and backup baseline
extension packages on every node
generated PostgreSQL config and HBA
service discovery / proxy / exporter
rollback mode不要绕开 Patroni,在正在受管的 production data directory 上直接照抄一条裸
pg_ctl/pg_upgrade 命令。本章实验之所以能使用它们,是因为所有 data directory 都在
随机 /tmp 下,从未被 Pigsty 管理。
服务接入验证使用新连接
升级后的原生身份:
SELECT current_database(),
current_user,
current_setting('server_version'),
current_setting('cluster_name'),
pg_is_in_recovery(),
inet_server_addr(),
inet_server_port();
SELECT system_identifier FROM pg_control_system();再从每种入口重复:
direct primary
read service
primary service
PgBouncer transaction/session pools
HAProxy/VIP/DNS
actual application runtime
backup/exporter accounts连接成功后运行 query corpus、写/读 canary、权限负例和 failover/failback。旧池必须 drain;否则你验证的可能仍是旧 server session。
30.6.3 比较 Pigsty 面板与原生证据的前后差异
面板比较不是截图找不同
升级会重置/改变部分累计统计,system identifier、timeline、instance label 也可能变化。 因此按信号类型比较:
| 类型 | 比较方式 |
|---|---|
| 配置/容量 | 前后绝对值与 source |
| rate/latency | 相同 workload、相同窗口的分布 |
| cumulative counter | 以启动/重置点为边界,不直接比总数 |
| catalog objects | 精确 manifest |
| plan | 结果先相等,再评估 plan/resource |
| HA/replication | 角色、timeline、lag、slot 与 failover 实验 |
Pigsty dashboard 负责关联:
service availability and pool
TPS / query latency / errors
CPU / memory / I/O / disk
WAL / checkpoint / replication
autovacuum and table/index
backup and exporter health每个 release gate 同时保留原生证据。例如面板显示 index latency 正常,还要保存:
SELECT relid, indexrelid, idx_scan, idx_tup_read, idx_tup_fetch
FROM pg_stat_user_indexes
WHERE indexrelid = 'app.orders_order_code_key'::regclass;以及对应 EXPLAIN、amcheck 与 query result。面板没有报警不能证明 exporter SQL 没有
因 catalog 变化而停止采集。
建立差异解释账本
signal: buffer_cache_hit_ratio
old: 99.4%
new_first_10m: 71.2%
new_after_warmup: 99.1%
classification: expected-cold-cache
action: none
owner: dba
evidence: dashboard-window + pg_stat_io snapshot每个差异必须归类:
expected reset/warmup
approved new-version behavior
configuration drift
statistics/plan regression
monitoring incompatibility
unknown -> release blocked未知差异不能因为维护窗口快结束就自动变成 expected。
本章实验的平台边界
runner 在 pg-meta 主机上读取 managed cluster 的:
cluster_name
server_version
system_identifier
primary identity并在实验前后要求完全相同。临时 PG17/18 使用私有 Unix socket,不接入 Pigsty exporter、 HAProxy 或 PgBouncer,所以它证明的是没有误伤 managed cluster,不是“Pigsty 全套 服务已经兼容升级”。
生产彩排必须另行让新 cluster 进入 Pigsty 监控与服务体系,执行上面的面板/原生双向 验证,并从新版本建立可恢复的备份基线。
上一节:升级前检查与业务验证 · 返回本章目录 · 下一节:实战:前滚、回退与发布决策 · 查看全书目录 · 查看索引中心