PostgreSQL 中文参考文档
🌐 英文原版 官方 ↗

E.2. 发布 18.4 #

E.2.1. 迁移到版本 18.4
E.2.2. 变更

发布日期:. 2026-05-14

本发布包含来自 18.3 的多种修复。有关大版本 18 中新特性的信息,参见Section E.6。

E.2.1. 迁移到版本 18.4 #

对于正在运行 18.X 的用户,不需要进行转储/恢复。

但是,如果您要从早于 18.2 的版本升级,参见Section E.4。

E.2.2. 变更 #

  • 防止处理启动包时出现无界递归(Michael Paquier) §

    恶意客户端可以通过无限交替发送被拒绝的 SSL 和 GSS 加密请求,使连接到的后端崩溃。

    PostgreSQL 项目感谢 Calif.io(与 Claude 和 Anthropic Research 合作)报告此问题。(CVE-2026-6479)

  • 修复内存分配计算中的多种整数溢出(Tom Lane, Nathan Bossart, Heikki Linnakangas) § § § § § § § § §

    在计算需要分配多少内存时,有多处代码对整数溢出的可能性不够谨慎。溢出会导致分配一个过小的缓冲区,调用者随后会写到缓冲区末尾之外。这至少会触发服务器崩溃,并且很可能可被利用来执行任意代码。在许多(但绝非全部)情形中,这种危害只存在于 32 位构建中。

    PostgreSQL 项目感谢 Xint Code、Bruce Dang、Sven Klemm 和 Pavel Kohout 报告这些问题。(CVE-2026-6473)

  • 在 pg_createsubscriber 中正确地为订阅名称加引号(Nathan Bossart) §

    给定的订阅名称被不加引号地插入到 SQL 命令中,因此,在订阅名称来自不受信任来源的(或许不太可能的)情形下,攻击者可能借此实现 SQL 注入。

    PostgreSQL 项目感谢 Yu Kunpeng 报告此问题。(CVE-2026-6476)

  • 在逻辑复制源检查中正确地为对象名称加引号(Pavel Kohout) §

    ALTER SUBSCRIPTION ... REFRESH PUBLICATION 会把模式名和关系名不加引号地插入到 SQL 命令中,从而允许在发布者上执行任意 SQL。

    PostgreSQL 项目感谢 Pavel Kohout 报告此问题。(CVE-2026-6638)

  • 拒绝 ts_headline() 中长度超限的选项(Michael Paquier) §

    StartSel、StopSel 和 FragmentDelimiter 字符串的长度不得超过 32Kb,但之前没有对此进行检查。超长的值通常会导致服务器崩溃。

    PostgreSQL 项目感谢 Xint Code 报告此问题。(CVE-2026-6473)

  • 在恢复属性 MCV 统计信息时检测错误的输入(Michael Paquier) §

    统计信息恢复函数在验证最常用值统计信息方面不够谨慎,会接受之后可能使规划器崩溃的值。

    PostgreSQL 项目感谢 Jeroen Gui 报告此问题。(CVE-2026-6575)

  • 在 timeofday() 和 pg_strftime() 中防范恶意的时区名称(Tom Lane) § §

    精心构造的时区设置可以把 % 序列传递给 snprintf(),从而可能导致崩溃或泄露服务器内存。另一个导致类似结果的途径是使 pg_strftime() 所使用的有限大小的输出缓冲区溢出。

    PostgreSQL 项目感谢 Xint Code 报告此问题。(CVE-2026-6474)

  • 在创建多范围类型时,确保用户对为该多范围类型指定的模式拥有 CREATE 权限(Jelte Fennema-Nio) §

    多范围类型可以被放入与其父范围类型不同的模式中,但在这样做时我们忽略了执行所需的权限检查。

    PostgreSQL 项目感谢 Jelte Fennema-Nio 报告此问题。(CVE-2026-6472)

  • 在认证代码中使用计时安全的字符串比较(Michael Paquier) §

    在检查口令、哈希值等时,使用 timingsafe_bcmp() 而不是 memcmp() 或 strcmp()。目前尚不清楚这些函数的数据依赖性在上述任何位置是否真的可被利用,但出于安全考虑,还是将它们替换掉。

    PostgreSQL 项目感谢 Joe Conway 报告此问题。(CVE-2026-6478)

  • 将 PQfn() 标记为不安全,并避免在 libpq 内使用它(Nathan Bossart) §

    对于非整数结果类型,PQfn() 不会被告知输出缓冲区的大小,因此它无法检查服务器返回的数据是否能装得下。恶意服务器因此可能覆写客户端内存。在不更改 API 的情况下这无法修复,所以将该函数标记为已弃用。在 libpq 内部,使用能够执行这一缺失检查的变体版本。

    PostgreSQL 项目感谢 Yu Kunpeng 和 Martin Heistermann 报告此问题。(CVE-2026-6477)

  • 防止 pg_basebackup 和 pg_rewind 中的路径遍历(Michael Paquier) §

    这些应用程序未能验证从其输入读取的输出文件路径,因此恶意来源可以覆写这些应用程序可写的任何文件。通过拒绝绝对路径或包含父目录引用的路径,来限制数据可以写入的位置。

    PostgreSQL 项目感谢腾讯玄武实验室的 XlabAI Team 和 Valery Gubanov 报告此问题。(CVE-2026-6475)

  • 防范 contrib/intarray 的 query_int 类型和 contrib/ltree 的 ltxtquery 类型中的字段溢出(Tom Lane) § §

    对这些查询结构的解析没有检查 16 位字段的溢出,因此可能构建出无效的查询树。这可能在执行查询时使服务器崩溃。

    PostgreSQL 项目感谢 Xint Code 报告此问题。(CVE-2026-6473)

  • 防范 contrib/ltree 的 lquery 类型的值过长(Michael Paquier) §

    包含超过 64K 个条目的值会导致内部溢出,可能造成栈破坏或错误的结果。

    PostgreSQL 项目感谢 Vergissmeinnicht、A1ex 和 Jihe Wang 报告此问题。(CVE-2026-6473)

  • 防止 contrib/spi 中的 SQL 注入和缓冲区溢出(Nathan Bossart) §

    check_foreign_key() 对键值加引号不够谨慎,并且使用固定长度的缓冲区来构造查询。虽然这个模块只是作为示例代码,但它也不应该包含这样危险的错误。

    PostgreSQL 项目感谢 Nikolay Samokhvalov 报告此问题。(CVE-2026-6637)

  • 在假定可排序类型上的相等条件意味着唯一性之前,先检查是否存在非确定性排序规则(Richard Guo) § § § § §

    许多规划器优化都做了这样的假定,例如:如果 x 上有唯一索引,那么至多只有一行表数据能满足 WHERE x = 'abc'。然而,如果索引和 WHERE 子句所附加的排序规则不同,这个结论通常是不安全的。当两个排序规则都是确定性的时候,这样做是安全的,因为该性质本质上要求两个字符串相等就意味着按位相等。但非确定性排序规则并非如此工作,因此如果 WHERE 子句或索引中任何一个具有非确定性排序规则,基于唯一匹配假设所做的优化就可能给出错误的查询结果。

  • 修复在连接消除期间 RestrictInfo 结构中的关系引用未被完全移除的问题(Tom Lane) §

    已经证明这一疏忽会导致规划器失败,例如出现意料之外的 “FULL JOIN 仅支持可合并连接或可哈希连接的连接条件”错误。在其他情形中,它也可能导致无法考虑到有效的计划。

  • 改进规划器将分区键列与子查询输出相匹配的能力(Richard Guo) §

    在将操作数与分区键比较之前,先从中去除不起作用的 PlaceHolderVar。这一改动使分区裁剪能够在某些以前未能识别出无需扫描分区的情形下成功执行。

  • 修复自连接消除,使其能够处理为纯布尔列的连接子句,例如 ON t1.boolcol(Andrei Lepikhov, Tender Wang, Alexander Korotkov) §

    以前,这种情况会导致“没有 relid N 的关系条目”错误。

  • 修复 UPDATE/DELETE ... WHERE CURRENT OF,使其能用于带有虚拟生成列的表(Satyanarayana Narlapuram, Dean Rasheed) §

  • 修复 INSERT ... ON CONFLICT 中 EXCLUDED 列引用对虚拟生成列的展开(Satyanarayana Narlapuram, Dean Rasheed) §

  • 修复规则动作和规则限定条件中对 NEW 生成列的不正确处理(Richard Guo, Dean Rasheed) §

    以前,这样的列引用在 INSERT 情形下会产生 NULL,或者在 UPDATE 情形下等效于 OLD 值。

  • 修复虚假的“不支持虚拟生成列上的索引”错误(Robert Haas) §

    创建表达式索引时,有时会错误地报告此错误。

  • 修复虚假的 “COPY FROM WHERE 条件中不支持生成列”错误(Tom Lane) §

    在 COPY FROM WHERE 条件中使用系统列时,有时会错误地报告此错误。

  • 当 MERGE 在可重复读或可串行化模式下遇到被并发更新的元组时,正确地报告序列化失败(Tender Wang) §

    以前,这种情况的行为与较低隔离级别下的行为相同。

  • 修复在源表具有已删除列的情况下 CREATE TABLE ... LIKE ... INCLUDING STATISTICS 的问题(Julien Tachoires) §

    在这种情况下,扩展统计信息对象可能被不正确地复制,或者该命令可能给出不正确的错误。

  • 允许 ALTER INDEX ... ATTACH PARTITION 在合适的情况下将父索引标记为有效(Sami Imseih) §

    存在一些边缘情况,其中分区索引即使在其所有叶子索引都有效时也可能仍被标记为无效。这一改动提供了一种机制,使用户无需借助手工目录更新就能纠正这种情况。

  • 修复 ALTER TABLE ... SET NOT NULL,使其只在完成目录更改之后才调用对象访问钩子函数(Artur Zakirov) §

  • 修复 ALTER FOREIGN DATA WRAPPER,使其不会丢弃包装器对象对其处理函数的依赖(Jeff Davis) §

  • 修复外键触发器丢失可延迟性的问题(Yasuo Honda) §

    以前,定义为 DEFERRABLE INITIALLY DEFERRED 的外键在被设置为 NOT ENFORCED 状态然后又改回 ENFORCED 之后,会表现得像 NOT DEFERRABLE 一样。

    如果您有存在此问题的外键,(在安装此更新之后)可以将其再次设置为 NOT ENFORCED 然后再改回 ENFORCED 来修复它。

  • 修复 WITHOUT OVERLAPS 以允许使用域(Jian He) §

    UNIQUE/PRIMARY KEY ... WITHOUT OVERLAPS 要求无重叠列是范围或多范围类型,但它也应当允许使用定义在这类类型之上的域。

  • 禁止通过多范围类型使复合类型成为其自身的成员(Heikki Linnakangas) §

    当中间类型是域、数组、复合类型或范围时,此类情形早已被禁止;但当时遗漏了多范围类型。

  • 修复 Datum 映像比较,使其不受符号扩展差异的影响(David Rowley) §

    这修复了一些此前会导致“无法找到记忆化表条目”错误或查询结果不正确的情形。

  • 修复哈希 IN/NOT IN 在非严格相等运算符下的错误逻辑(Chengpeng Yan) §

    旧有的代码可能崩溃或给出错误的结果。所有内建数据类型都拥有严格的相等运算符,因此该问题只可能出现在扩展数据类型上。

  • 在 to_char() 中截断过长的区域设置相关数字符号(Tom Lane) §

    如果某个区域设置指定的货币符号、千位分隔符、小数点符号或正负号超过 8 字节长,则可能发生缓冲区溢出。现实世界中并不存在这样的区域设置,而且让无权限的攻击者在 Postgres 服务器之下安装恶意的区域设置定义也不现实;但为了安全起见,仍会检查过长的符号并在需要时将其截断。

  • 防止在解析 Ispell 词典的词缀文件时发生缓冲区溢出(Tom Lane) § §

    损坏或恶意的词缀文件可能导致服务器崩溃。由于文本搜索配置文件被认为是可信的,因此这不被视为安全问题,但看起来仍然值得修复。

  • 防止窗口聚合的帧开始和结束位置计算中出现整数溢出(Richard Guo) §

    用户指定的极大偏移量(接近 INT64_MAX)可能导致错误或查询结果不正确。

  • 修复 array_agg_array_combine(),使其正确合并数组的空值位图(Dmytro Astapov) §

    这一错误导致并行化的 array_agg(anyarray) 计算有时产生不正确的输出。

  • 当 sync_file_range() 返回错误码 EINTR 时进行重试(DaeMyung Kang) §

  • 修复 pg_stat_reset_single_table_counters() 在共享目录上的错误行为(Chao Li) §

    这类情形会产生一个副作用:重置当前数据库的 stat_reset_timestamp,这并非有意为之。

  • 在并行 apply 工作进程空闲时更新活动统计信息(Zhijie Hou) §

    此前,刚完成的事务所产生的统计信息可能长时间得不到上报,在负载较轻时尤其如此。

  • 修复在集合操作中估算数组长度时出现的“没有 relid 0 的关系条目”失败(Tender Wang) §

  • 修复 pglz_decompress() 收到损坏输入时发生的缓冲区过读问题(Andrew Dunstan) §

    可能会读到超出输入末尾的几个字节,在非常不走运的情况下这可能导致崩溃。

  • 修复增量 JSON 解析器在处理跨越输入缓冲区边界的数字记号时存在的问题(Andrew Dunstan) §

    此前可能会接受格式不正确的数字,从而导致后续出现失败。

  • 防止在恢复增量备份期间造成关系可见性映射的膨胀(Robert Haas) §

    由于对期望文件长度的计算不正确,恢复操作可能向可见性映射追加大量全零块。这不会导致数据损坏,但可能浪费相当多的磁盘空间。

  • 在对文本列进行目录缓存查找时,使用 C 排序规则而不是数据库的默认排序规则(Jeff Davis) §

    这避免了诸如物理复制启动等边缘情形下的失败,在这些情形中没有已确定的数据库,因而无法确定默认排序规则。

  • 防止卡住的 slotsync 工作进程阻塞备用服务器的提升(Nisha Moond, Ajin Cherian) § § §

    徒劳地等待主服务器响应的工作进程会把提升延误一段不合理的时间。

  • 修复空闲 slotsync 工作进程产生过多日志输出的问题(Zhijie Hou) §

  • 确保 tuplestore 数据结构即使在发生错误之后也保持内部一致(Tom Lane) §

    以前的代码对此并不谨慎,这在大多数情况下无妨,但对于支撑 WITH HOLD 游标的 tuplestore 来说却有问题。在 v15 及更早版本中,这会导致易于复现的崩溃;尚不知道后面的分支是否易受影响,但在所有分支中都保持一致性似乎最好。

  • 当条目没有所属进程时,让 pg_aios 系统视图的 pid 列显示 NULL 而不是 0(ChangAo Chen) §

  • 修复 pg_stat_replication 中过早报告 NULL 延迟的问题(Shinya Kato) §

    即使复制活动正在进行,这些延迟列也经常显示为 NULL。

  • 修复并行 btree 索引扫描所用共享内存分配不足的问题(Siddharth Kothari) §

    在边缘情况下,这可能导致服务器崩溃。

  • 避免在使用未记录 WAL 的 GiST 索引时出现罕见的刷写失败(Tomas Vondra) §

    未记录日志的 GiST 索引有时仍可能产生“xlog 刷写请求 n/nnnn 未被满足”错误,原因是选择用于表示插入点的“伪 LSN”并不正确。

  • 修复对奇数大小的段所需的 DSA 页面映射大小的低估(Paul Bunn) §

    这种计算错误会导致越界访问,进而使服务器崩溃。

  • 修复共享内存中最旧 multixact 数组的索引问题(Yura Sokolov) § §

    这一错误可能导致已准备但尚未提交的事务的行锁对其他会话不可见,或者此类事务的结果出现其他可见性问题。在 max_connections 设置非常小的情况下,还可能发生内存踩踏。

  • 修复在安装了过多 EXPLAIN 扩展选项时的数组越界问题(Joel Jacobson) §

  • 修复处理扩展数据类型表达式上的扩展统计信息时可能出现的服务器崩溃(Michael Paquier) §

    如果数据类型的 typanalyze 函数没有计算出任何有用的统计信息,则可能出现空指针解引用。核心内建的 typanalyze 函数都不会这样表现,但扩展可能会。

  • 正确显示在 GROUP BY 中使用的连接别名变量(Tom Lane) §

    在包含诸如 SELECT ... t1 LEFT JOIN t2 USING (x) GROUP BY x 查询的视图中,反解析时可能会不正确地显示 GROUP BY 子句,从而导致转储/恢复失败。仅当 t1.x 与 t2.x 的数据类型不完全相同,且 t1.x 是需要隐式类型转换的一侧时才会发生。

  • 修复基于 ICU 的字符串处理中的轻微内存泄漏(Jeff Davis) §

  • 如果启动进程失败,则在退出 postmaster 之前正确关闭其他子进程(Ayush Tiwari) §

    对这种情形的处理依赖于一个早已过时的假设:启动进程运行期间不存在其他 postmaster 子进程,因此 postmaster 立即退出是可以接受的。孤儿子进程最终会察觉 postmaster 已死亡并自行退出,但更干净的关闭过程才是可取的。

  • 修复检查点的 WAL 重放与 multixact ID 创建之间的竞争条件(Heikki Linnakangas) §

    跟随来自较旧小版本主服务器的 WAL 的备用服务器,可能陷入不断崩溃并重启的循环,并报告“无法访问事务状态”。

  • 防止 walsender 进程在关闭时无限期等待(Anthonin Bonnefoy) § §

    在关闭一个正在发布逻辑复制数据的集簇时,walsender 会等待所有待处理的 WAL 被写出。但它此前没有正确地请求这一点,因此在某些情况下这可能变成无限期等待。

  • 确保对表空闲空间映射的更改在恢复期间被持久化(Alexey Makhmutov) §

    此前,虽然 WAL 重放在重放应当改变空闲空间映射的操作时确实会更新该映射,但在启用了校验和的情况下,映射页所在的缓冲区不会被标记为脏,因此这些更改可能永远不会被写出。在备用服务器上,随着时间推移,这会导致该映射与表的实际内容大相径庭。虽然该映射仅用作提示,但在备用服务器被提升为活动服务器后的一段时间内,这种状况可能造成显著的性能下降,直到大部分映射已通过更新得到修复。

  • 修复某些 ecpg 函数在没有已建立连接的情况下被调用时的崩溃(Shruthi Gowda) §

  • 强化 tar 文件解析逻辑,使其能够应对无法处理的归档(Tom Lane) §

    pg_basebackup 和 pg_verifybackup 中使用的 tar 文件读取代码没有验证输入究竟是不是 tar 文件,更没有验证它是否属于我们能够处理的有效 tar 文件子集。对于输入文件由 PostgreSQL 代码生成的正常场景而言,这不是问题,但如果输入是由其他某个 tar 程序生成的,就可能成为问题。

  • 修复备份解压和 tar 解析代码中的多种缺陷(Andrew Dunstan, Tom Lane, Chao Li) § § §

    pg_basebackup 和 pg_verifybackup 中使用的解压与 tar 文件读取代码错误地处理了 tar 文件填充数据,在边缘情况下可能损坏经 LZ4 压缩的数据,未能检查某些不寻常的错误条件,在压缩/解压错误发生后未能退出(从而导致级联的错误报告),并且存在内存泄漏。

  • 在 pg_dump 中,保留 NOT NULL 约束的 NO INHERIT 属性(Jian He) §

    有些情况遗漏了打印 NO INHERIT 子句。

  • 在 pg_dumpall 中,不要跳过授权者 OID 已悬空的角色 GRANT (Tom Lane) §

    相反,会像 v16 之前那样,通过发出不带任何 GRANTED BY 子句的 GRANT 来处理这类情形。这可以避免在可预见的情形下丢失授权,因为 v16 之前的服务器并不阻止删除授权者角色。仍会继续就缺失的授权者发出警告,但仅当源服务器为 v16 或更高版本时才会如此。

  • 在 pg_upgrade 中,在连接较旧的源服务器时注意使用正确的协议版本(Jacob Champion) §

    在尝试从 2018 年之前的服务器进行升级时,这可能会造成问题。

  • 在 contrib/basic_archive 中,允许归档目录在启动时不存在(Nathan Bossart) §

    此前,如果 basic_archive.archive_directory 的设置没有指向一个已存在的目录,则会被拒绝。这是不合需要的,因为即使目录稍后才出现,归档也会无限期地陷入停滞。

  • 修复 contrib/ltree,使其能够应对大小写折叠改变字符串字节长度的情形(Jeff Davis) § §

    此前,指定不区分大小写匹配的 lquery 模式可能无法匹配它们本应匹配的标签。

  • 修复 contrib/pg_overexplain 的 RANGE_TABLE 选项输出结构错误的问题(Satyanarayana Narlapuram) §

    在 JSON、YAML 和 XML 格式中,有些字段被放错了位置,导致输出在结构上无效。

  • 在 contrib/pg_stat_statements 中,解析 pgss_query_texts.stat 文件期间发生错误时不再泄漏内存(Heikki Linnakangas) §

  • 在 contrib/postgres_fdw 中,避免因过早清理失败的连接而导致崩溃(Etsuro Fujita) §

    如果远程连接的中止清理失败,我们就不能再使用它。但应将连接对象的关闭推迟到事务结束时进行,因为在打开的游标等数据结构中可能仍存在对它的引用。

  • 将时区数据文件更新到 tzdata 2026b 版(Tom Lane) §

    从 2026 年 11 月开始,不列颠哥伦比亚(America/Vancouver)将全年使用 UTC-07(实际上就是永久夏令时)。本版本假定从那时起其 TZ 缩写将为 MST。这一点似乎很可能会改变,但目前尚不清楚将采用什么新缩写。另外对摩尔多瓦做了一项历史修正:自 2022 年以来他们一直遵循欧盟的夏令时转换时间。