编程 pg_upgrade 升级 PostgreSQL 18 失败:initdb 默认开启的 page checksums 与旧集群不一致

2026-10-14 21:02:01

pg_upgrade 升级 PostgreSQL 18 失败:initdb 默认开启的 page checksums 与旧集群不一致

PostgreSQL 18 的 initdb 把 page checksums(数据校验和)改成了默认开启。对从旧集群升级的人来说,这一条改动的直接影响是:如果旧集群当初没开校验和,pg_upgrade 会因为新旧集群校验和设置不一致而直接失败。

本文按官方 release notes 与 press kit 的内容,记录 18 在升级路径上的几处变化,以及其余不兼容点和新增能力。

官方 release notes:

一、校验和:升级前必须先对齐

pg_upgrade 要求新集群与旧集群的校验和设置一致,否则升级流程无法继续。旧集群没开校验和时,只有两条路:

  1. 新建 18 集群时用 initdb --no-data-checksums 关闭校验和,与旧集群保持一致;
  2. 先用 pg_checksums 给旧集群开启校验和,再走升级。这条路径需要停机,且对数据量大的集群来说耗时明显。

没有第三条捷径。校验和一旦在升级时对不上,就只能在「新集群关掉」和「旧集群补开」之间选一个。

二、pg_upgrade 现在保留 planner 统计信息

跨大版本升级时,优化器统计信息此前不会保留。后果是繁忙系统在升级完成后、ANALYZE 跑完之前,查询性能会出现肉眼可见的下降。

PostgreSQL 18 支持在跨大版本升级时保留 planning statistics。需要注意:扩展统计(extended statistics)不在保留范围内。新增的 --no-statistics 选项用于关闭这一保留行为。

pg_upgrade 这一轮还新增了几个选项:

  • --jobs:并行处理校验检查;
  • --swap:用交换目录代替拷贝、克隆或链接文件;
  • --set-char-signedness:设置新集群中 char 的默认符号性。

三、其他不兼容与行为变化

MD5 密码认证进入弃用流程。 用 CREATE ROLE / ALTER ROLE 设置 MD5 密码时会发出弃用告警,可用 md5_password_warnings=off 关闭告警。官方方向是改用 SCRAM。

VACUUM 与 ANALYZE 会处理父表的 inheritance children。 如果要保持旧行为,使用新增的 ONLY 选项。

COPY FROM 读取 CSV 时的 EOF 标记处理变了。 不再把 \. 当作 EOF 标记,且 \. 必须单独成行。用旧版 psql 客户端连接 18 服务器时,可能出现 \copy 相关问题。

不允许 unlogged 分区表。

AFTER 触发器的角色语义变了。 现在以「事件入队时活动的角色」执行,此前是以触发器执行时的角色执行。对在事务提交前切换角色的场景,影响比较明显。

移除 GRANT/REVOKE 中对 rule 权限的支持,该权限自 8.2 起就已无效。

内存上下文视图调整。 移除列 pg_backend_memory_contexts.parent;pg_backend_memory_contexts.level 与 pg_log_backend_memory_contexts() 改为从 1 开始编号,此前从 0 开始。

全文检索读取配置文件与词典时,改用集群默认 collation provider,而不再总是 libc。 如果集群默认使用非 libc 的 provider(ICU、builtin),且它在 LC_CTYPE 相关字符上的行为与 libc 不同,全文检索和 pg_trgm 的行为可能发生变化。用 pg_upgrade 升级时,应重建所有全文检索与 pg_trgm 相关的索引。

RETURNING 支持 OLD 与 NEW。 覆盖 DEL / INSERT / UPDATE / MERGE。

时区缩写处理顺序变化。 现在优先使用当前会话的时区缩写,再查服务器变量 timezone_abbreviations。

四、18 的新特性

异步 I/O(AIO)子系统:对顺序扫描、bitmap heap scan、vacuum 等场景有提升,官方称某些场景最高可达 3 倍。

skip scan:多列 B-tree 索引在更多情况下能被使用。

uuidv7():生成按时间有序的 UUID。

虚拟生成列(virtual generated column):读取时计算,现在是生成列的默认形式。

OAuth 2.0 认证。

时间范围约束:PRIMARY KEY / UNIQUE / FOREIGN KEY 可作用于范围。

PG_UNICODE_FAST collation 与 casefold。

wire protocol 3.2:自 7.4 以来第一个新协议版本,libpq 仍默认使用 3.0。

升级到 18 之前,先把校验和这一项确认掉,否则 pg_upgrade 会在最前面就停下来。

复制全文 生成海报 PostgreSQL pg_upgrade 数据库 升级 initdb

推荐文章

程序员茄子在线接单