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

E.4. 发布 18.2 #

E.4.1. 迁移到版本 18.2
E.4.2. 变更

发布日期:. 2026-02-12

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

E.4.1. 迁移到版本 18.2 #

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

但是,如果在 ltree 列上有任何索引,则可能需要在更新之后重建它们。参见下面的第六条变更日志条目。

E.4.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 的攻击者可以溢出字符串缓冲区,其后果的严重程度等同于任意代码执行。在这些修复之后,当字符串函数处理已存入数据库的无效文本时,应用程序可能会看到“编码中的无效字节序列”错误。

    PostgreSQL 项目感谢 Paul Gerste 和 Moritz Sanft(作为 zeroday.cloud 的一部分)报告了这一问题。(CVE-2026-2006)

  • 强化 contrib/pg_trgm,以应对字符串小写化行为的变化(Heikki Linnakangas) § §

    修复因在某些区域设置下将字符串小写化可能产生比原文更多字符(而非字节)而导致的潜在缓冲区溢出。这一行为是版本 18 中新出现的,这个缺陷也是如此。

    PostgreSQL 项目感谢 Heikki Linnakangas 报告了这一问题。(CVE-2026-2007)

  • 修复 contrib/ltree 中大小写不敏感匹配不一致的问题(Jeff Davis) § §

    ltree 中与索引相关的例程所使用的大小写折叠实现与主运算符不同。只有当默认排序规则提供程序为 libc 且编码为单字节时,两者的行为才是等价的。

    为修复此问题,将代码改为使用数据库的默认排序规则进行大小写折叠。除非数据库使用 libc 作为排序规则提供程序且其编码为单字节,否则此更改将要求对 ltree 列上的索引(无论使用何种索引访问方法)重新建立索引。如果不这样做,对此类索引的搜索将无法找到相关条目。

  • 当使用 ALTER TABLE ... ADD CONSTRAINT 添加具有显式名称的非空约束时,如果该列已被标记为 NOT NULL,则要求所提供的名称与现有约束的名称一致(Álvaro Herrera、Srinath Reddy Sadipiralla) §

  • 不允许子选择中的 CTE 引用决定聚集函数的语义级别(Tom Lane) §

    此更改撤销了两个小版本之前所做的一项更改,现在改为抛出错误:如果子选择所引用的 CTE,其语义级别低于标准 SQL 规则根据其中包含的列引用和聚集为该聚集所指派的语义级别,就会报错。事实证明,之前尝试的修复自身会带来问题,而且目前尚不清楚应当用什么方案来替代。由于 SQL 标准完全禁止在聚集内使用子选择,因此把这类情况当作错误来处理似乎已经足够。

  • 修复 CTE 查询中 MERGE 的触发器过渡表捕获问题(Dean Rasheed) §

    当执行一个数据修改 CTE 查询,其中既包含 MERGE,又包含对带有语句级 AFTER 触发器的表的另一个 DML 操作时,传递给触发器的过渡表将不包含受 MERGE 影响的行,而只包含受其他操作影响的行。

  • 修复对属于非关系范围表条目(例如子查询)的行标记(rowmark)进行错误剪枝的问题(Dean Rasheed) §

    如果一个拟议中的行更新需要由 EvalPlanQual 重新检查加以修正(当该行正被并发更新时就可能发生这种情况),则会导致错误的结果。

  • 修复 UPDATE 或 DELETE 的分区目标表的所有子分区都已被剪枝时的失败(Amit Langote) §

    在这种情况下,即使实际上无需执行任何操作,执行器也可能报告“无法找到垃圾 ctid 列”错误。

  • 修复数组下标中的子选择的表达式求值缺陷(Andres Freund) §

  • 修复非确定性排序规则下的文本子串搜索(Laurenz Albe) §

    在使用非确定性排序规则时,未能检测到发生在被搜索字符串最末尾的匹配。

  • 当查询包含重复的窗口函数调用时,避免规划器可能出现的失败(Meng Zhang、David Rowley) §

    对此类调用去重时的混淆可能导致类似 “winref 为 2 的 WindowFunc 被指派给了 winref 为 1 的 WindowAgg” 这样的错误。

  • 修复涉及集合返回函数和分组集时规划器的错误(Richard Guo) §

    在构造 ProjectSet 计划节点时,规划器未能检测到涉及分组表达式的子表达式已经被输入计划计算过。这会导致低效的计划,或者产生诸如“在子计划目标列表中找不到变量”之类的错误。

  • 当子查询的分组子句包含易失函数或集合返回函数时,避免不正确的优化(Richard Guo) §

    规划器会把引用这种分组列的外层查询条件下推,这会由于易失函数被多次求值而导致不正确的行为,或者由于把集合返回函数引入子查询的 WHERE/HAVING 子句而导致错误。

  • 在搜索关于某个表达式的统计信息时穿透 PlaceHolderVar 节点(Richard Guo) §

    此更改使规划器能够找到关于从子查询中上拉的表达式或用于 GROUP BY 的表达式的相关统计信息,避免回退到默认估计值。(可以说,我们应该调整找到的统计信息,以考虑该值为 NULL 的概率增加这一因素,但对于普通 Var 我们也从未做过同等的事情。)虽然这一限制由来已久,但 PostgreSQL 版本 18 中的更改使 PlaceHolderVar 比以前更常见,因此做出此更改,以避免在受影响的情形中出现计划退化。

  • 在将表达式匹配到索引时穿透无操作的 PlaceHolderVar 节点(Richard Guo) §

    由于 PostgreSQL 版本 18 在比以前更多的情况下使用 PlaceHolderVar,一些以前能够使用索引的查询无法再使用索引。增加逻辑以防止这种退化。

  • 修复规划器把 OR 子句转换为 ScalarArrayOp 索引条件时的问题(Tender Wang、Tom Lane) §

    代码未能正确处理 RelabelType 节点,可能生成无效的表达式,或者无法执行有效的转换。

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

    通常我们会丢弃被谓词蕴涵的 WHERE 子句,因为对它进行测试毫无意义,它必然对每个索引条目都成立。然而,如果索引要求在第一个索引键上带有 WHERE 子句(哈希索引正是如此),这可能会阻止创建索引扫描计划。在考虑这类索引时,不要丢弃被蕴涵的子句。

  • 对于非日志的 BRIN 索引不再产生预写式日志(Kirill Reshke) §

    一条很少执行的代码路径会错误地产生与 BRIN 索引相关的预写式日志记录,即使该索引已被标记为非日志。随后,崩溃恢复将无法重放该记录,并报错说文件已经存在。

  • 在并行 GIN 索引构建中使用正确的排序函数(Tomas Vondra) §

    并行代码使用了默认的排序运算符(由列数据类型的 btree opclass 决定),而它应当使用 GIN opclass 所指定的排序函数(如果指定了的话)。如果数据类型没有 btree opclass,这会导致失败;如果 opclass 指定的排序函数与 btree opclass 不一致,则会产生无效的索引。

  • 防止截断仍被未读 NOTIFY 消息所需的 CLOG (Joel Jacobson、Heikki Linnakangas) § § §

    此修复防止了在后端吸收 NOTIFY 消息缓慢时出现“无法访问事务状态”错误。

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

    以前,如果后端在吸收 NOTIFY 消息时发生错误,它会跳过该消息继续前进,把错误报告给客户端,然后继续运行。但这种行为存在很多问题。一个重要的顾虑是,客户端没有办法可靠地知道一条通知已经丢失,当然更无法知道其中包含什么内容。根据应用逻辑的不同,丢失通知可能导致应用程序陷入等待而停滞不前。此外,其余的消息也要等到有人发送新的 NOTIFY 时才会得到处理。

    此外,如果在接收到 NOTIFY 信号时连接正处于空闲状态,出于一些不相关的原因,任何 ERROR 无论如何都会被升级为 FATAL。因此,为了保持一致性,并且向应用程序清晰地表明它可能已经错过了某些通知,我们选择让这种情况在所有场合下都发生。

  • 在计算查询 ID 哈希时考虑分组表达式(Jian He) §

    以前,除了 GROUP BY 表达式以外完全相同的两个查询,会被 contrib/pg_stat_statements 以及其他使用查询 ID 的组件合并在一起。

  • 修复 EXPLAIN ANALYZE MERGE 在存在并发更新时对更新计数的错误统计(Dean Rasheed) §

    这种情况会导致 EXPLAIN 输出中“被跳过”元组的计数不正确,或者在启用断言的构建中触发断言失败。

  • 修复锁定元组时沿更新链回溯的缺陷(Jasper Smit) §

    该代码路径忽略了检查更新链中第一个新元组的 xmin,因此如果原来的更新者中止了事务,并且其空间立即被 VACUUM 回收后又被重新使用,就可能锁定一个不相关的元组。这可能导致意外的事务延迟或死锁。也观察到过因识别到错误元组而产生的错误。

  • 修复对大表增量备份的不正确处理(Robert Haas、Oleg Tkachenko) §

    如果一个超过 1GB 的表(或者一般地说,超过本安装的段大小)在基础备份与增量备份之间被 VACUUM 截断, pg_combinebackup 可能会失败,并报出关于“截断块长度超过段大小”的错误。这会阻止增量备份的恢复。

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

  • 修复异步 I/O 代码中的竞态条件(Andres Freund) §

    异步 I/O 操作的结果代码有可能在其被获取之前就被覆盖。

  • 防止崩溃后对 multixact 日志的不正确截断(Heikki Linnakangas) §

  • 修复 pg_stat_get_backend_activity() 的结果可能编码不正确的问题(Chao Li) §

    保存会话活动字符串的共享内存缓冲区可能以一个不完整的多字节字符结尾。读取者应当截去任何这样的不完整字符,但该函数没有做到这一点。

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

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

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

    此错误可能由于一个附属数据结构的生命周期短于并行上下文而导致崩溃。据我们所知,仅使用核心 PostgreSQL 并不会触及这个问题,但我们已经收到在扩展中出现麻烦的报告。

  • 在创建新的 multixid 时设置下一个 multixid 的偏移量,以消除在极端情况下需要的等待循环(Andrey Borodin) § §

    先前的逻辑可能陷入对一个永远不会发生的更新的等待。

  • 避免对数据修改 CTE 进行多次重写(Bernice Southey、Dean Rasheed) §

    以前,在更新一个可自动更新的视图或带有规则的关系时,如果原始查询包含任何数据修改 CTE,重写器就会由于递归而把这些 CTE 重写多次。这种做法效率低下,并且如果某个 CTE 包含对始终生成列的更新,还可能产生虚假的错误。

  • 允许重试 DSM 注册表条目的初始化(Nathan Bossart) §

    如果一个动态共享内存条目的初始化中途失败,则允许下一次使用该条目的尝试重新进行初始化。以前,该条目会停留在永久失败的状态。

  • 避免在页面已被换出时 NUMA 状态视图的失败(Tomas Vondra) §

  • 在使用较旧版本的 libnuma 查询 NUMA 页面状态时,避免“操作不被允许”错误(Tomas Vondra) §

  • 如果预写式日志并未一直存在回溯到检查点记录所指示的重做点,则让恢复失败(Nitin Jadhav) §

    在开始恢复之前对此增加显式检查,从而避免造成损害并提供有用的错误消息。以前,在这种情况下恢复可能会崩溃或损坏数据库。

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

    此错误的可见影响是,为该查询触发的事件触发器只能看到第一个 publish 选项,即使指定了多个选项也是如此。如果这样的查询被建立为预备语句,重新执行时同样会出现异常行为。

  • 把在 CREATE SUBSCRIPTION ... CONNECTION 中指定的连接选项传递给发布方的 walsender(Fujii Masao) §

    在此修复之前,options 连接选项(如果有)会被忽略,例如这会阻止在 walsender 会话中设置自定义的服务器参数值。原本的设计是让它能够工作,而且在 PostgreSQL 版本 15 中的重构破坏它之前它也确实可以工作,因此这里恢复了以前的行为。

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

    与并发检查点之间的竞态条件可能导致复制槽所需的预写式日志被删除,从而使该槽立即被标记为无效。

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

    这可能导致错误“无法构建初始槽快照,因为最老的安全 xid 晚于快照的 xmin”。

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

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

  • 在并行 worker 应用失败之后,不再推进逻辑复制进度(Zhijie Hou) §

    先前的行为会使订阅者丢失事务。

  • 修复逻辑复制 slotsync 工作进程,使其正确处理 LOCK_TIMEOUT 信号(Zhijie Hou) §

    以前,超时信号实际上被忽略了。

  • 修复流复制备用服务器重启期间可能出现 “EOF 之后存在意外数据”失败的问题(Anthonin Bonnefoy) §

  • 修复 SQL/JSON 路径类型不匹配时的错误报告(Jian He) §

    代码可能产生“类型 0 的缓存查找失败”错误,而不是关于路径表达式类型不正确的预期报错。

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

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

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

    例如,关于备份清单中时间线编号不匹配的错误报告,本应显示结束时间线编号,却显示了开始时间线编号。

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

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

    先前的代码在 aarch64 机器上无法编译。

  • 修复 aarch64 特定的代码,使其能够使用旧的(RHEL7 时代)系统头文件进行构建(Tom Lane) § §

  • 修复对 io_uring_queue_init_mem() 不正确的 configure 探测(Masahiko Sawada) §

    此错误导致在基于 autotools 的构建中无法优化异步 I/O 缓冲区分配,不过使用 meson 构建时代码可以正常工作。这一疏漏的主要影响是后端进程的退出比必要的更慢。

  • 新增服务器参数file_extend_method以控制 posix_fallocate() 的使用(Thomas Munro) §

    PostgreSQL 版本 16 及更高版本会使用 posix_fallocate()(如果平台提供该函数)来扩展关系文件。然而,有报告称它与某些文件系统的交互不佳:使用 posix_fallocate() 会禁用 BTRFS 压缩,而且在较旧的 Linux 内核版本上,XFS 可能产生虚假的 ENOSPC 错误。为了提供一种变通办法,引入了这个新的服务器参数。把 file_extend_method 设置为 write_zeros 将使服务器回到通过写入零块来扩展文件的旧方法。

  • 在 Windows 上遵循 open() 的 O_CLOEXEC 标志(Bryan Green、Thomas Munro) § § §

    让该标志像在 POSIX 平台上那样工作,从而我们不会把文件句柄泄漏到诸如 COPY TO/FROM PROGRAM 之类的子进程中。虽然这种泄漏没有造成过太多问题,但它看起来并不是我们想要的行为。

  • 修复用 meson 构建的 Solaris 可执行文件无法解析服务器命令行上的长选项的问题(Tom Lane) §

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

  • 修复 psql 对 VACUUM 选项值的 Tab 补全(Yugo Nagata) §

  • 在 psql 命令提示符中,当没有服务器连接时,不显示 %P(流水线状态)的值(Chao Li) §

    这使得 %P 的行为与其他值取决于当前连接的提示符转义序列一致。

  • 修复 pg_dump 收集序列值的逻辑(Nathan Bossart) § §

    如果序列在转储的同时被并发删除,那么即使该序列并不在要转储的数据库对象之列,pg_dump 也会失败。此外,如果调用用户缺少读取序列值的权限,pg_dump 会发出不正确的值,而不是按预期那样失败。

  • 修复 pg_dump 对 oauth_validator_libraries 值的加引号可能不正确的问题(ChangAo Chen) §

    如果需要转储该设置的值,pg_dump 会应用错误的加引号规则。

  • 避免 pg_dump 在二进制升级模式下的断言失败(Vignesh C) §

    对象排序代码未能处理订阅-关系对象,从而触发了断言,不过在生产构建中并没有严重的负面影响。

  • 修复 pgbench 在流水线模式下存在多个 \syncpipeline 命令时的错误处理(Yugo Nagata) §

    如果在查询错误之后又遇到多个 \syncpipeline 命令, pgbench 会报告“无法退出流水线模式”,或者在启用断言的构建中出现断言失败。

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

    对于它能够更改的其他所有变量,它本来就会这样做。

  • 让 pg_resetwal 允许把下一个 multixact xid 设置为 0,或者把下一个 multixact 偏移量设置为 UINT32_MAX (Maxim Orlov) §

    这些都是有效的值,因此拒绝它们是不正确的。在最坏的情况下,如果恰好在 multixact 回卷的时刻尝试 pg_upgrade,升级将会失败。

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

    先前的代码在检查用 CREATE INDEX CONCURRENTLY 创建的索引时会导致虚假错误。

  • 修复 contrib/amcheck,使其正确处理处于“半死”(half-dead)状态的 btree 索引页面(Heikki Linnakangas) §

    amcheck 期望这样的页面拥有一个父级下行链接,但实际上它并没有,这会导致关于“父键与子页高键不匹配”的虚假错误报告。

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

    amcheck 可能报告关于“块不是真正的根”的虚假错误。

  • 修复 contrib/pg_buffercache 中过度分配内存的问题(David Geier) §

    该代码为 NUMA 页面状态分配的内存是所需数量的两倍。

  • 修复 contrib/intarray 中用于 @@ 的选择性估计器在极端情况下的整数溢出(Chao Li) §

    这可能导致在涉及最大整数值的情形下产生较差的选择性估计。

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

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

  • 当 IN 列表同时包含常量和非常量表达式时,避免 contrib/pg_stat_statements 崩溃(Sami Imseih) §

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

    唯一的改动涉及下加利福尼亚(Baja California)地区 1976 年之前时间戳的历史数据。