19.4 版本与数据库初始化契约
安装包可以升级,初始化事实却不一定能在线改。版本与初始化契约要在第一次 创建数据目录前冻结,并在创建后从 PostgreSQL 自己读取回来。
本节正式契约是:
这里的 captured patch 是验收时观察值,不是允许集群成员长期运行不同小版本。
19.4.1 PostgreSQL、locale、collation、编码与 checksum
“PostgreSQL 18”不是完整版本身份
至少要区分:
major 决定磁盘格式、系统目录、SQL/行为兼容边界;patch 主要承载 bug 与安全 修复。扩展和操作系统包又有各自版本。只写“PG18”无法重建环境。
从 server 读取:
从 package manager、容器 image digest 或 artifact repository 记录 package
身份。不要用 psql --version 代替 server 版本;它只说明客户端。
database cluster、database 与 locale 的层次
PostgreSQL 官方
initdb
创建一个 database cluster:数据目录、共享系统目录和
postgres、template1、template0。随后 CREATE DATABASE 通常从模板
复制。
因此初始化默认会向后传播:
不要把 OS 的 LANG、cluster 默认和某个 database 的 locale 混为一谈。
encoding 解决字节到字符,不解决语言排序
UTF8 定义字符编码。它不自动定义:
- “ä”排在什么位置;
- 大小写转换规则;
- 字符类别;
- 模糊/前缀查询的索引语义;
- Unicode 版本变化后的排序稳定性。
这些主要属于 collation/provider。
查当前 database:
PG18 的字段反映 provider 与 locale;跨版本工具不要假设每个字段都存在。
collation 是数据语义,不是显示偏好
PostgreSQL 的 Collation Support 说明 collation 会参与:
这会产生一个重要结论:
改变 collation provider 或版本,可能改变既有索引所依据的顺序;不能把 它当成客户端展示参数。
生产选择至少比较:
| provider | 来源 | 优势 | 需要管理的变化 |
|---|---|---|---|
builtin |
PostgreSQL 内建 | 跨 OS 可预测,部署依赖少 | 受 PostgreSQL major 语义约束 |
libc |
操作系统 C library | 与 OS locale 集成 | OS/glibc locale 版本漂移 |
icu |
ICU library | 多语言与定制能力强 | ICU 版本、包与索引刷新 |
本章选 PG17+ 可用的内建 C.UTF-8。Pigsty 的
资源准备建议
也推荐 PG17+ 以它作为默认。这个选择偏向稳定、可预测的数据库基础排序;
它不声称提供每种自然语言的用户期望顺序。需要语言相关排序时,应明确
column/expression collation,并有业务样例。
C.UTF-8 与 C 不能只看名字
需要记录:
相同 C.UTF-8 字符串由不同 provider 提供时,不应靠名称推断行为完全一致。
本章验收同时要求:
初始化时显式选择,创建后从目录复核
PG18 initdb 的 provider 默认仍是 libc;选 builtin 必须显式指定合法
builtin locale。不要因为 Pigsty wizard 给出了合理结果,就误记成 PostgreSQL
自己的默认。
等价意图可以表达为:
在 Pigsty 中由 pg_encoding、pg_locale 及生成的 Patroni bootstrap
配置承载。最终证据仍是 pg_database,不是模板文件。
checksum 检测静默页损坏,不创造副本
data checksum 在读页时帮助发现 I/O 系统造成的静默损坏。它不能:
- 修复坏页;
- 替代 backup;
- 替代 replica;
- 防止错误 SQL;
- 证明 storage 持久性;
- 覆盖 WAL 文件的所有损坏形态。
PG18 initdb 默认启用 checksum,也允许显式
--no-data-checksums。因此不能用“版本是 18”推断某个现存 cluster 已启用。
读取:
on 表示检测机制启用,不表示从未发生 storage 问题;failure counter、
日志、scrub/backup 验证要一起看。
checksum 可以通过离线工具改变,但那仍是停机、容量和回退都要规划的 maintenance。对新平台,把它当初始化契约更简单。
本章的验证 SQL
postgresql-facts.sql
一次读取:
它以 JSON 输出,避免人眼从四台机器复制表格时错列。
19.4.2 WAL、页大小、扩展与认证前提
block size 属于二进制与磁盘格式合同
本章观察:
8 KiB 是常见构建值。它影响 relation page、buffer、部分容量公式和工具 兼容。不要假设所有自编译发行版都相同,也不要把 OS filesystem block size 当成 PostgreSQL page size。
恢复、物理复制、低层工具与扩展需要与 server build 兼容。
WAL segment size 只能在初始化时选择
PG18
initdb --wal-segsize
接受 1–1024 MiB 的 2 次幂,默认 16 MiB,而且只能初始化时设置。
本章冻结:
segment 大小不改变 WAL 逻辑正确性,但会影响:
改变它不是调一个 reload 参数,而是重建/迁移问题。
wal_level 等运行参数不是全部初始化事实
要区分三类:
| 类型 | 例子 | 典型改变方式 |
|---|---|---|
| compile/init | page size、WAL segment、system identifier、默认 locale | rebuild/init/migrate |
| restart | shared_preload_libraries、部分 WAL/worker 参数 |
rolling maintenance |
| reload/session | 许多 planner/logging/timeout 参数 | controlled reload/role policy |
同样一个配置文件中的两行,变更成本可能完全不同。变更系统应记录
context:
system identifier 界定物理 cluster 身份
pg_control_system() 可读取 system identifier:
本章要求:
它能揭露把同一 data directory/复制链误报成两个服务单元的错误。它不是 secret,但属于运维身份;对外报告可只保存关系或受控 evidence。
timeline 不是 cluster identifier。promotion 后 timeline 可以改变,system identifier 保持。第 20 章会使用这个区别。
扩展契约从 package 开始,不从 CREATE EXTENSION 开始
对每个扩展记录:
四个节点能启动 core PostgreSQL,不表示某个动态库在 future promotion
candidate 上存在。package parity 应在部署时验收;catalog 中
pg_extension 只说明当前 database 安装了什么。
第 14 章负责扩展生命周期;本章只冻结部署前提。
shared_preload_libraries 是重启边界
本章观察:
预加载库会进入 server 生命周期。新增/移除通常需要 restart,并必须在每个 可能承接 primary 的节点有兼容库。配置字符串一致还不够:
authentication method 与 password verifier 是两件事
password_encryption=scram-sha-256 控制新密码保存为什么 verifier;真正
允许哪类连接,由:
共同决定。
initdb --auth-* 会生成初始 HBA,但 Pigsty 随后声明式管理业务、复制和
管理访问。不要把 initdb 选项当作最终 access policy。
SCRAM 迁移需要客户端矩阵
本章新环境要求:
只改 password_encryption 不会重写既有角色密码。role 需要重新设置密码才
生成新 verifier。不要查询或导出 pg_authid.rolpassword 到 evidence。
TLS on 不是 TLS 完成
SHOW ssl = on 仅证明 server 可接受 TLS。完整合同还要在第 31 章验证:
本章只把 ssl=on 作为部署前提,不宣称传输安全审计已经完成。
不安全的初始化捷径
生产拒绝:
官方文档明确把 --no-sync 定位为测试用途;系统崩溃可能让初始化后的目录
损坏。自动化快几秒不是持久性理由。
19.4.3 版本矩阵、升级窗口与勘误入口
一条“版本号”要展开成兼容矩阵
建议基线:
| 层 | 当前身份 | 兼容/升级问题 |
|---|---|---|
| OS | Ubuntu 24.04.4 aarch64 | kernel、glibc、OpenSSL、locale |
| automation | Pigsty v4.5.0 exact tag | inventory/schema/playbook behavior |
| PostgreSQL | 18.6 | patch rollout、major upgrade |
| HA | Patroni package/version | DCS/API/config compatibility |
| DCS | etcd package/version | quorum、snapshot、client compatibility |
| proxy/pool | HAProxy/PgBouncer | protocol, auth, routing semantics |
| backup | pgBackRest + repo format | restore target/version |
| extensions | per extension | PG ABI, SQL update scripts |
| clients | driver/pool version | protocol, SCRAM, TLS, type behavior |
| observability | exporter/dashboard rules | metric name/label changes |
矩阵必须标:
“支持 PG18”不等于“当前所有 extension build、driver 和 restore path 已在 PG18.6 测过”。
primary 与 standby 尽量保持同一 patch
PostgreSQL standby planning 指出 physical log shipping 不能跨 major,并建议尽量保持相同 release level。短暂 rolling patch 差异需要:
- 官方升级说明;
- package availability;
- replica-first 顺序;
- rollback/forward-only 判断;
- extension parity;
- promotion eligibility;
- 限定窗口与监控。
不能把“minor 通常磁盘格式兼容”扩大成无限期混跑承诺。
patch 与 major 使用不同 runbook
patch upgrade 常见路径:
major upgrade可能需要:
本章只建立矩阵;第 30 章执行版本升级。
maintenance window 不只是“可以重启”
窗口要写:
如果升级需要 40 分钟,而窗口只有 30 分钟,“尽量完成”不是计划。
source pinning 与 dirty working tree
本章部署没有直接使用维护者本地 dirty Pigsty checkout,而是:
这避免把未提交修改偷偷带进正式证据。
source pinning 仍不是 supply-chain 完整方案。生产还要验证:
文档与实验也要有版本范围
书中命令页应标:
本节验证日期是 2026-07-29。读者使用更新版本时,应先查官方 release note 和参数文档,不应因为 URL 仍可访问就假设行为不变。
勘误入口是一条可执行路径
发现差异时记录:
修订后要更新:
- 正文;
- lab requirements/baseline;
- validator 与 negative case;
- verified matrix/date;
- migration note。
只改一句 prose 而不改 validator,会让书和实验分叉。
初始化契约的 release gate
本章正式 validator 要求四个 PostgreSQL 成员都满足:
并运行反例:
这证明规则能拒绝一个已知错误,不只证明正常样本能被脚本读出来。
通过后的结论仍是:
上一节:操作系统与主机基线 · 返回本章目录 · 下一节:拓扑、命名与故障域 · 查看全书目录 · 查看索引中心