发布说明

PostgreSQL 14.21

E.2. 发布版本 14.21 #

发布日期:. 2026-02-12

本次发布包含来自 14.20 的多项修复。 有关 14 主版本新特性的说明,请参见 Section E.23

PostgreSQL 社区将于 2026 年 11 月停止发布 14.X 发布系列的更新。 建议用户尽快升级到较新的发布分支。

E.2.1. 迁移到版本 14.21 #

对于运行 14.X 的用户,不需要执行导出/恢复。

但是,如果是从早于 14.19 的版本升级,请参见 Section E.4

E.2.2. 变更 #

  • 防止 oidvector/int2vector 出现意外的维度 (Tom Lane) §

    这些数据类型预期为不含空值的一维数组,但某些类型转换路径允许违背这些预期。 现已为一些原本依赖这些预期却未加验证的函数补充检查,因为它们可能因此产生错误行为。

    PostgreSQL 项目感谢 Altan Birler 报告此问题。 (CVE-2026-2003)

  • 加固选择性估算器,防止将其附加到接受非预期数据类型的操作符上 (Tom Lane) § § §

    contrib/intarray 包含一个选择性估算函数;由于它未检查输入是否为预期的数据类型, 该函数可被滥用来执行任意代码。第三方扩展也应检查是否存在类似风险, 并采用 intarray 现在使用的技术来增加防护。 由于此类扩展的修复需要时间,我们现在要求具有超级用户权限,才能将非内置的选择性估算器附加到操作符上。

    PostgreSQL 项目感谢 Daniel Firer(zeroday.cloud 成员)报告此问题。 (CVE-2026-2004)

  • 修复 contrib/pgcrypto PGP 解密函数中的缓冲区溢出问题 (Michael Paquier) §

    使用超长会话密钥解密精心构造的消息会导致缓冲区溢出, 严重时甚至可能执行任意代码。

    PostgreSQL 项目感谢 Team Xint Code(zeroday.cloud 成员)报告此问题。 (CVE-2026-2005)

  • 修复多字节字符长度验证不充分的问题 (Thomas Munro,Noah Misch) § § § § § §

    多处漏洞使攻击者只要能够发出精心构造的 SQL,就可能溢出字符串缓冲区, 严重时甚至可以执行任意代码。应用这些修复后,当字符串函数处理数据库中存储的无效文本时, 应用程序可能会看到 invalid byte sequence for encoding 错误。

    PostgreSQL 项目感谢 Paul Gerste 和 Moritz Sanft(zeroday.cloud 成员)报告此问题。 (CVE-2026-2006)

  • 不允许由子查询中的 CTE 引用决定聚合函数的语义层级 (Tom Lane) §

    此变更撤销了两个小版本之前引入的一项更改;现在,如果某个子查询引用的 CTE 所处层级 低于按标准 SQL 规则依据其中的列引用和聚合所判定的聚合语义层级,将抛出错误。 先前的修复方案本身也带来了问题,而且目前尚不清楚应如何处理。由于 SQL 标准本就完全不允许在聚合中包含子查询, 将此类情况视为错误似乎已经足够。

  • 修复当分区目标表的所有子表在 UPDATE 或 DELETE 操作中都被裁剪时的失败问题 (Amit Langote) §

    在这种情况下,执行器可能报告 could not find junk ctid column 错误,即使实际上无需执行任何操作。

  • 允许在部分哈希索引上进行索引扫描,即使索引的谓词蕴含 WHERE 子句的真值 (Tom Lane) §

    通常我们会删除被谓词蕴含的 WHERE 子句,因为测试它没有意义——对于每个索引条目, 该条件必然成立。然而,如果索引是需要在前导索引键上有 WHERE 子句的类型(如哈希索引), 这样做会阻止创建索引扫描计划。在考虑此类索引时,不要删除被蕴含的子句。

  • 不要为非日志 BRIN 索引生成 WAL(Kirill Reshke) §

    一条很少执行到的代码路径错误地为 BRIN 索引生成了 WAL 记录,即使该索引被标记为非日志。 崩溃恢复时将无法重放该记录,并报告文件已存在的错误。

  • 防止截断未读 NOTIFY 消息仍然需要的 CLOG (Joel Jacobson,Heikki Linnakangas) § § §

    此修复防止了当后端进程吸收 NOTIFY 消息较慢时出现的 could not access status of transaction 错误。

  • NOTIFY 消息处理期间发生的错误升级为 FATAL, 即关闭连接(Heikki Linnakangas) §

    以前,如果后端在吸收 NOTIFY 消息时遇到错误, 它会跳过该消息,向客户端报告错误,然后继续运行。但这种行为存在很多问题。 一个主要问题是,客户端没有好的方法来知道通知丢失了, 更无法知道通知的内容是什么。根据应用逻辑的不同, 错过一条通知可能导致应用程序卡在等待状态。此外,剩余的消息在有人发送新的 NOTIFY 之前不会被处理。

    另外,如果连接在接收到 NOTIFY 信号时处于空闲状态, 由于无关的原因,任何 ERROR 都会被升级为 FATAL。因此, 我们选择在所有情况下都这样做,以保持一致性, 并向应用程序提供一个明确的信号,表明它可能错过了一些通知。

  • 修复在锁定元组时跟踪更新链的错误(Jasper Smit) §

    此代码路径忽略了检查更新链中第一个新元组的 xmin, 使得在原始更新者中止且空间被 VACUUM 立即回收并重新使用的情况下, 可能会锁定一个不相关的元组。 这可能导致意外的事务延迟或死锁。 与识别到错误元组相关的错误也已被观察到。

  • 修复就地目录更新相关的问题(Noah Misch) § § §

    为就地更新发送非事务性的无效化消息,因为此类更新在事务回滚后仍然存在。 同时确保在其他会话看到更新之前,该更新已写入 WAL 日志。 这些修复主要防止了关系的冻结 XID 属性变得不一致的情况, 这可能导致过早的 CLOG 截断以及随后的 could not access status of transaction 错误。

  • 修复后端进程在退出时由于尝试在已取消映射的共享内存段中释放锁而可能崩溃的问题 (Rahila Syed) §

  • 防止崩溃后多事务日志被错误截断(Heikki Linnakangas) §

  • 修复 pg_stat_get_backend_activity() 可能返回编码错误的结果的问题 (Chao Li) §

    保存会话活动字符串的共享内存缓冲区末尾可能包含不完整的多字节字符。 读取者应该截断掉任何此类不完整字符,但此函数未能做到这一点。

  • 防止递归的内存上下文日志记录(Fujii Masao) §

    持续不断的请求内存上下文日志记录的信号流可能导致日志记录代码的递归执行, 理论上可能导致栈溢出。

  • 修复重新初始化并行执行上下文时的内存上下文使用问题 (Jakub Wartak,Jeevan Chalke) §

    此错误可能由于附属数据结构的生命周期比并行上下文更短而导致崩溃。 已知仅使用核心 PostgreSQL 无法触发该问题, 但我们收到了扩展中出现问题的报告。

  • 在创建新的多事务 ID 时设置下一个多事务 ID 的偏移量,以消除在边界情况下所需的等待循环 (Andrey Borodin) § §

    之前的逻辑可能会卡在等待一个永远不会发生的更新上。

  • 避免多次重写数据修改 CTE(Bernice Southey, Dean Rasheed) §

    以前,在更新自动可更新视图或带规则的关系时,如果原始查询含有数据修改 CTE, 重写器会由于递归而多次重写这些 CTE。这不仅低效, 而且当 CTE 包含对始终生成列的更新时可能产生虚假错误。

  • 如果 WAL 不存在到检查点记录所指示的重做点,则使恢复失败 (Nitin Jadhav) §

    在开始恢复之前添加一个显式检查,以确保不会造成损害并提供有用的错误消息。 以前,在这种情况下恢复可能会崩溃或损坏数据库。

  • 避免在 ALTER PUBLICATION 期间修改源查询树(Sunil S) §

    此错误的可见效果是,为该查询触发的事件触发器只能看到第一个 publish 选项,即使指定了多个选项。如果此类查询被设置为预备语句,重新执行时也会出现错误行为。

  • 防止新创建或新同步的复制槽被无效化 (Zhijie Hou) §

    与并发检查点的竞争条件可能导致复制槽所需的 WAL 被删除, 使得该槽立即被标记为无效。

  • 修复计算复制槽所需 xmin 时的竞争条件 (Zhijie Hou) §

    这可能导致错误 cannot build an initial slot snapshot as oldest safe xid follows snapshot's xmin

  • 在逻辑复制订阅的初始同步期间,在开始复制数据之前提交 pg_replication_origin 条目的添加 (Zhijie Hou) §

    以前,如果复制步骤失败,新的 pg_replication_origin 条目 会因事务回滚而丢失,从而导致共享内存中的状态不一致。

  • 修复流复制副本服务器重启期间可能出现的 unexpected data beyond EOF 失败问题(Anthonin Bonnefoy) §

  • 修复解析分区范围边界时对列位置的错误跟踪(myzhen) §

    这可能导致在关于将分区边界值转换为列的数据类型的错误消息中引用错误的列名。

  • 修复错误消息中的各种小错误(Man Zeng,Tianchen Zhang) § § §

    例如,关于备份清单中时间线编号不匹配的错误报告在应该显示结束时间线编号的地方 显示了起始时间线编号。

  • 修复在使用 LLVM 17 或更高版本进行 JIT 编译时无法执行函数内联的问题 (Anthonin Bonnefoy) §

  • 调整我们的 JIT 代码以兼容 LLVM 21(Holger Hoffstätte) §

    之前的代码在 aarch64 机器上编译失败。

  • 支持在 GNU/Hurd 上更改进程标题(Michael Banck) §

  • 使 pg_resetwal 在更改 OldestXID 时打印更新后的值 (Heikki Linnakangas) §

    它对可以更改的其他每个变量都已经这样做了。

  • contrib/amcheck 中,为 btree 索引父节点检查使用正确的快照 (Mihail Nikalayeu) §

    之前的代码在检查使用 CREATE INDEX CONCURRENTLY 创建的索引时 会产生虚假错误。

  • 修复 contrib/amcheck 以正确处理 half-dead btree 索引页面 (Heikki Linnakangas) §

    amcheck 期望此类页面有一个父级下行链接,但实际上没有, 导致关于 mismatch between parent key and child high key 的虚假错误报告。

  • 修复 contrib/amcheck 以正确处理不完整的 btree 根页面分裂 (Heikki Linnakangas) §

    amcheck 可能会报告关于 block is not true root 的虚假错误。

  • 修复 contrib/intarray@@ 选择性估算器的边界情况整数溢出问题(Chao Li) §

    这可能导致在涉及最大整数值的情况下产生不准确的选择性估算。

  • 修复 contrib/ltree 中的多字节编码问题 (Jeff Davis) §

    之前的代码可能将不完整的多字节字符传递给 lower(), 可能导致不正确的行为。

  • 将时区数据文件更新到 tzdata 2025c 版本(Tom Lane) §

    唯一的变更是下加利福尼亚 1976 年之前时间戳的历史数据。