跳至内容
19.4 版本与数据库初始化契约

19.4 版本与数据库初始化契约

安装包可以升级,初始化事实却不一定能在线改。版本与初始化契约要在第一次 创建数据目录前冻结,并在创建后从 PostgreSQL 自己读取回来。

本节正式契约是:

Pigsty release       v4.4.0
PostgreSQL major     18
captured patch       18.4 / server_version_num 180004
encoding             UTF8
locale/provider      C.UTF-8 / builtin
data checksums       on
block size           8192 bytes
WAL segment size     16777216 bytes
timezone             Etc/UTC
password verifier    scram-sha-256
TLS                  on

这里的 captured patch 是验收时观察值,不是允许集群成员长期运行不同小版本。

19.4.1 PostgreSQL、locale、collation、编码与 checksum

“PostgreSQL 18”不是完整版本身份

至少要区分:

major version       18
patch version       18.4
package release     distribution/vendor build revision
server build        configure options, compiler, architecture
client version      psql/libpq/driver
extension version   vector/PostGIS/... each separately
automation release  Pigsty 4.4.0

major 决定磁盘格式、系统目录、SQL/行为兼容边界;patch 主要承载 bug 与安全 修复。扩展和操作系统包又有各自版本。只写“PG18”无法重建环境。

从 server 读取:

SELECT version();
SELECT current_setting('server_version') AS server_version,
       current_setting('server_version_num')::integer AS server_version_num;

从 package manager、容器 image digest 或 artifact repository 记录 package 身份。不要用 psql --version 代替 server 版本;它只说明客户端。

database cluster、database 与 locale 的层次

PostgreSQL 官方 initdb 创建一个 database cluster:数据目录、共享系统目录和 postgrestemplate1template0。随后 CREATE DATABASE 通常从模板 复制。

因此初始化默认会向后传播:

initdb default
    -> template databases
        -> new database defaults
            -> per-column/per-expression COLLATE override

不要把 OS 的 LANG、cluster 默认和某个 database 的 locale 混为一谈。

encoding 解决字节到字符,不解决语言排序

UTF8 定义字符编码。它不自动定义:

  • “ä”排在什么位置;
  • 大小写转换规则;
  • 字符类别;
  • 模糊/前缀查询的索引语义;
  • Unicode 版本变化后的排序稳定性。

这些主要属于 collation/provider。

查当前 database:

SELECT datname,
       pg_encoding_to_char(encoding) AS encoding,
       datlocprovider,
       datcollate,
       datctype,
       datlocale,
       datcollversion
FROM pg_database
WHERE datname = current_database();

PG18 的字段反映 provider 与 locale;跨版本工具不要假设每个字段都存在。

collation 是数据语义,不是显示偏好

PostgreSQL 的 Collation Support 说明 collation 会参与:

ORDER BY / comparison
lower / upper / initcap
pattern matching
collatable expression
index ordering and uniqueness semantics

这会产生一个重要结论:

改变 collation provider 或版本,可能改变既有索引所依据的顺序;不能把 它当成客户端展示参数。

生产选择至少比较:

provider来源优势需要管理的变化
builtinPostgreSQL 内建跨 OS 可预测,部署依赖少受 PostgreSQL major 语义约束
libc操作系统 C library与 OS locale 集成OS/glibc locale 版本漂移
icuICU library多语言与定制能力强ICU 版本、包与索引刷新

本章选 PG17+ 可用的内建 C.UTF-8。Pigsty 的 资源准备建议 也推荐 PG17+ 以它作为默认。这个选择偏向稳定、可预测的数据库基础排序; 它不声称提供每种自然语言的用户期望顺序。需要语言相关排序时,应明确 column/expression collation,并有业务样例。

C.UTF-8C 不能只看名字

需要记录:

locale string
locale provider
encoding
collation version
PostgreSQL major

相同 C.UTF-8 字符串由不同 provider 提供时,不应靠名称推断行为完全一致。 本章验收同时要求:

encoding=UTF8
locale_provider=builtin
datlocale/datcollate/datctype contains C.UTF-8

初始化时显式选择,创建后从目录复核

PG18 initdb 的 provider 默认仍是 libc;选 builtin 必须显式指定合法 builtin locale。不要因为 Pigsty wizard 给出了合理结果,就误记成 PostgreSQL 自己的默认。

等价意图可以表达为:

--encoding=UTF8
--locale-provider=builtin
--builtin-locale=C.UTF-8

在 Pigsty 中由 pg_encodingpg_locale 及生成的 Patroni bootstrap 配置承载。最终证据仍是 pg_database,不是模板文件。

checksum 检测静默页损坏,不创造副本

data checksum 在读页时帮助发现 I/O 系统造成的静默损坏。它不能:

  • 修复坏页;
  • 替代 backup;
  • 替代 replica;
  • 防止错误 SQL;
  • 证明 storage 持久性;
  • 覆盖 WAL 文件的所有损坏形态。

PG18 initdb 默认启用 checksum,也允许显式 --no-data-checksums。因此不能用“版本是 18”推断某个现存 cluster 已启用。

读取:

SHOW data_checksums;

SELECT datname, checksum_failures, checksum_last_failure
FROM pg_stat_database
ORDER BY datname;

on 表示检测机制启用,不表示从未发生 storage 问题;failure counter、 日志、scrub/backup 验证要一起看。

checksum 可以通过离线工具改变,但那仍是停机、容量和回退都要规划的 maintenance。对新平台,把它当初始化契约更简单。

本章的验证 SQL

postgresql-facts.sql 一次读取:

cluster_name
server_version_num
pg_is_in_recovery()
system identifier / timeline
checksum, block, WAL segment
timezone, password_encryption, SSL
database encoding/provider/locale
installed extensions

它以 JSON 输出,避免人眼从四台机器复制表格时错列。

19.4.2 WAL、页大小、扩展与认证前提

block size 属于二进制与磁盘格式合同

本章观察:

SHOW block_size;       -- 8192

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,而且只能初始化时设置。

本章冻结:

SHOW wal_segment_size; -- 16MB

segment 大小不改变 WAL 逻辑正确性,但会影响:

archive object granularity
directory file count
shipping/retention operations
monitoring formula
tool assumptions

改变它不是调一个 reload 参数,而是重建/迁移问题。

wal_level 等运行参数不是全部初始化事实

要区分三类:

类型例子典型改变方式
compile/initpage size、WAL segment、system identifier、默认 localerebuild/init/migrate
restartshared_preload_libraries、部分 WAL/worker 参数rolling maintenance
reload/session许多 planner/logging/timeout 参数controlled reload/role policy

同样一个配置文件中的两行,变更成本可能完全不同。变更系统应记录 context

SELECT name, setting, unit, context, pending_restart, source, sourcefile
FROM pg_settings
WHERE name IN (
  'wal_level',
  'max_wal_senders',
  'max_replication_slots',
  'shared_preload_libraries',
  'password_encryption',
  'ssl'
);

system identifier 界定物理 cluster 身份

pg_control_system() 可读取 system identifier:

SELECT system_identifier,
       pg_control_version,
       catalog_version_no
FROM pg_control_system();

本章要求:

pg-meta members   one system identifier
pg-test members   another system identifier
two clusters      identifiers differ

它能揭露把同一 data directory/复制链误报成两个服务单元的错误。它不是 secret,但属于运维身份;对外报告可只保存关系或受控 evidence。

timeline 不是 cluster identifier。promotion 后 timeline 可以改变,system identifier 保持。第 20 章会使用这个区别。

扩展契约从 package 开始,不从 CREATE EXTENSION 开始

对每个扩展记录:

supported PG majors
OS/architecture packages
package and extension version
shared_preload requirement
dependencies
superuser/trusted install boundary
backup/restore behavior
physical replica parity
rolling/minor/major upgrade path
license/security owner

四个节点能启动 core PostgreSQL,不表示某个动态库在 future promotion candidate 上存在。package parity 应在部署时验收;catalog 中 pg_extension 只说明当前 database 安装了什么。

SELECT extname, extversion, extnamespace::regnamespace
FROM pg_extension
ORDER BY extname;

第 14 章负责扩展生命周期;本章只冻结部署前提。

shared_preload_libraries 是重启边界

本章观察:

pg_stat_statements, auto_explain

预加载库会进入 server 生命周期。新增/移除通常需要 restart,并必须在每个 可能承接 primary 的节点有兼容库。配置字符串一致还不够:

package file exists
linker dependencies resolve
library matches PG major/architecture
startup succeeds
replica parity holds

authentication method 与 password verifier 是两件事

password_encryption=scram-sha-256 控制新密码保存为什么 verifier;真正 允许哪类连接,由:

listen_addresses / port / TLS
pg_hba.conf rule order
database
role
source address
auth method
client driver support

共同决定。

initdb --auth-* 会生成初始 HBA,但 Pigsty 随后声明式管理业务、复制和 管理访问。不要把 initdb 选项当作最终 access policy。

SCRAM 迁移需要客户端矩阵

本章新环境要求:

password_encryption=scram-sha-256
HBA methods use intended SCRAM policy
all drivers/pools support SCRAM
old MD5 verifier rotation is planned

只改 password_encryption 不会重写既有角色密码。role 需要重新设置密码才 生成新 verifier。不要查询或导出 pg_authid.rolpassword 到 evidence。

TLS on 不是 TLS 完成

SHOW ssl = on 仅证明 server 可接受 TLS。完整合同还要在第 31 章验证:

certificate identity/SAN
trust root
private-key permission
expiry/rotation
minimum protocol/cipher
client sslmode and hostname verification
revocation/incident process
plaintext path policy

本章只把 ssl=on 作为部署前提,不宣称传输安全审计已经完成。

不安全的初始化捷径

生产拒绝:

initdb --auth=trust
initdb --no-sync
unknown locale inherited from shell
checksum disabled without ADR
plaintext/generated default password published in Git
mixed PG major physical replicas
extension binary only installed on current primary

官方文档明确把 --no-sync 定位为测试用途;系统崩溃可能让初始化后的目录 损坏。自动化快几秒不是持久性理由。

19.4.3 版本矩阵、升级窗口与勘误入口

一条“版本号”要展开成兼容矩阵

建议基线:

当前身份兼容/升级问题
OSUbuntu 24.04.4 aarch64kernel、glibc、OpenSSL、locale
automationPigsty v4.4.0 exact taginventory/schema/playbook behavior
PostgreSQL18.4patch rollout、major upgrade
HAPatroni package/versionDCS/API/config compatibility
DCSetcd package/versionquorum、snapshot、client compatibility
proxy/poolHAProxy/PgBouncerprotocol, auth, routing semantics
backuppgBackRest + repo formatrestore target/version
extensionsper extensionPG ABI, SQL update scripts
clientsdriver/pool versionprotocol, SCRAM, TLS, type behavior
observabilityexporter/dashboard rulesmetric name/label changes

矩阵必须标:

supported
tested
deployed
deprecated
exception
owner
next review

“支持 PG18”不等于“当前所有 extension build、driver 和 restore path 已在 PG18.4 测过”。

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 常见路径:

read release notes
stage package parity
upgrade replicas
restart/rejoin/observe
move service or controlled switchover
upgrade former primary
verify

major upgrade可能需要:

pg_upgrade
logical replication
dump/restore
new cluster + migration
extension upgrade
statistics/index refresh
application compatibility
cutover/rollback boundary

本章只建立矩阵;第 30 章执行版本升级。

maintenance window 不只是“可以重启”

窗口要写:

allowed customer impact
change start / latest abort / end
required replicas and headroom
backup/recovery prerequisite
traffic drain and connection behavior
replication catch-up limit
rollback point
owner and incident escalation
post-change observation

如果升级需要 40 分钟,而窗口只有 30 分钟,“尽量完成”不是计划。

source pinning 与 dirty working tree

本章部署没有直接使用维护者本地 dirty Pigsty checkout,而是:

resolve exact tag v4.4.0
record commit 2d5a45f759274048de0c197829228a71d0182e5c
git archive exact tag to private temporary directory
generate private inventory there
deploy from that archive

这避免把未提交修改偷偷带进正式证据。

source pinning 仍不是 supply-chain 完整方案。生产还要验证:

trusted upstream/repository
tag/release artifact authenticity
artifact checksum/signature
package repository snapshot
SBOM/vulnerability response
internal promotion process
retention/rebuild ability

文档与实验也要有版本范围

书中命令页应标:

last verified date
PostgreSQL major/patch
Pigsty release
OS/architecture
lab schema/release
known exceptions

本节验证日期是 2026-07-29。读者使用更新版本时,应先查官方 release note 和参数文档,不应因为 URL 仍可访问就假设行为不变。

勘误入口是一条可执行路径

发现差异时记录:

claim ID
book page/anchor
observed version and platform
reproduction
expected versus actual
official source
severity
workaround
owner
target release

修订后要更新:

  • 正文;
  • lab requirements/baseline;
  • validator 与 negative case;
  • verified matrix/date;
  • migration note。

只改一句 prose 而不改 validator,会让书和实验分叉。

初始化契约的 release gate

本章正式 validator 要求四个 PostgreSQL 成员都满足:

server major=18
encoding=UTF8
provider=builtin
locale=C.UTF-8
checksums=on
block=8192
WAL segment=16777216
timezone=Etc/UTC
password_encryption=scram-sha-256
ssl=on

并运行反例:

disable-data-checksums -> E_PG_INIT

这证明规则能拒绝一个已知错误,不只证明正常样本能被脚本读出来。

通过后的结论仍是:

initialization_contract=accepted-for-this-sandbox
major_upgrade_readiness=not-tested
production_security_gate=pending
production_ch19_gate=pending

上一节:操作系统与主机基线 · 返回本章目录 · 下一节:拓扑、命名与故障域 · 查看全书目录 · 查看索引中心

最后更新于