受支持版本: 17

E.3. 发布版本 17.7 #

发布日期:. 2025-11-13

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

E.3.1. 迁移到版本 17.7 #

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

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

E.3.2. 变更 #

  • 检查 CREATE STATISTICS 在目标模式上的 CREATE 权限(Jelte Fennema-Nio) §

    这一遗漏使得表所有者可以在任何模式中创建统计对象,可能导致意外的命名冲突。

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

  • 避免 libpq 中分配大小计算出现整数溢出(Jacob Champion) §

    libpq 中有若干处在计算所需内存分配大小时不够谨慎。足够大的输入可能导致整数溢出,进而使缓冲区分配过小,随后发生越界写入。

    PostgreSQL 项目感谢 Positive Technologies 的 Aleksey Solovev 报告此问题。 (CVE-2025-12818)

  • 防止当 JSON_VALUE 等 SQL/JSON 函数的 DEFAULT 子句包含 COLLATE 表达式时出现 unrecognized node type 错误(Jian He) § §

  • 正确地将 JSON_OBJECT() 等 JSON 构造表达式视为非 strict(Tender Wang、Richard Guo) §

    在某些情况下,这些表达式即使有一个或多个 NULL 输入也能产生非 NULL 结果,因此它们并非 strict。规划器错误地将它们归类为 strict,从而可能进行不正确的查询转换。

  • 进一步修复 SIMILAR TO 正则表达式中字符类的处理(Laurenz Albe) §

    先前把 SIMILAR TO 模式匹配表达式翻译为 POSIX 风格正则表达式的修复,又破坏了一个先前可正常工作的边角场景:如果在左方括号后紧接着就是转义字符,而转义序列后又紧跟右方括号(例如 [\w]),那么该右方括号就不再被视为字符类的结束标记。

  • 修复参数中包含子选择且该子选择通过 FROM 引用了聚合函数外部 CTE 时,对聚合函数的解析问题(Tom Lane) §

    在确定聚合的语义级别时,这种 CTE 引用必须像外层级列引用一样处理;但此前并未将其计算在内,从而导致晦涩的规划器或执行器错误。

  • 修复在估算 SubPlan 代价时边角场景下出现 no relation entry for relid 错误的问题(Richard Guo) §

  • 避免规划器展开分区表时极不可能发生的 use-after-free(Bernd Reiß) §

    只有在最后一个存活分区被并发删除时,才存在这一风险。

  • 移除 btree 索引清理中的错误断言(Peter Geoghegan) §

  • 修复 GIN 索引扫描在存在多个扫描条件时可能出现的无限循环(Tom Lane) §

    GIN 可以处理那些能够排除不匹配条目、但对查找相关条目没有帮助的扫描条件,例如 tsquery 子句 !term。但这类条件不能位于扫描条件数组的首位。代码未能在所有情况下确保这一点,结果就是,一个同时含有这类条件和普通条件的查询,是否能正常工作取决于查询中给出这些条件的顺序。

  • 确保 GIN 索引扫描可以被取消(Tom Lane) §

    某些代码路径可能在很长时间内都不检查中断。

  • 确保 BRIN 自动摘要对需要快照的索引表达式提供快照(Álvaro Herrera) § §

    以前,自动摘要在这类索引上会失败,并留下占位索引元组,导致索引随时间膨胀。

  • 修复当表包含接近 232 页时 BRIN 索引扫描中的整数溢出风险(Sunil S) §

    这一疏漏可能导致无限循环或扫描不需要的表页。

  • 修复 JIT 生成的元组解构代码对存储值进行零扩展的错误(David Rowley) §

    在不使用 JIT 时,对应代码执行的是符号扩展而不是零扩展,从而导致小整数数据类型的 Datum 表示不同。这种不一致在大多数情况下被掩盖了,但已知在使用 Memoize 计划节点时会导致 could not find memoization table entry 错误,也可能还有其他症状。

  • 修复为触发器缓存结果关系信息的逻辑错误(David Rowley、Amit Langote) §

    在分区的列集合与其父分区表的列集合在物理上不完全一致的情况下,这一疏漏可能导致崩溃。

  • 为 TID Scan 和 TID Range Scan 计划节点补充缺失的 EvalPlanQual 重新检查(Sophie Alpert、David Rowley) § §

    这一遗漏可能导致在并发更新场景下没有重新检查 ctid 上的条件,从而使更新行为取决于所选择的计划类型。

  • 修复 EvalPlanQual 对未为 EPQ 准备替代本地连接计划的 foreign 或 custom join 的处理(Masahiko Sawada、Etsuro Fujita) §

    在这种情况下,本应正常调用 foreign 或 custom 访问方法,但实际上并没有,通常会导致崩溃。

  • 避免在 DETACH CONCURRENTLY 期间复制哈希分区约束(Haiyang Li) §

    ALTER TABLE DETACH PARTITION CONCURRENTLY 原本会给已分离出的分区再添加一份分区约束副本。这样做并不合适,一部分原因是非并发的 DETACH 根本不会这么做,但更主要的原因在于,对哈希分区而言,该约束表达式中包含了对父表 OID 的引用。这会在 dump/restore 时出问题,或者在 DETACH 之后父表被删除时出问题。从 v19 开始,我们将完全不再创建这类约束副本。而在已发布分支中,为尽量降低意外后果的风险,只在哈希分区场景下跳过添加此类约束副本。

  • 禁止在分区键中使用生成列(Jian He、Ashutosh Bapat) §

    这原本就不被允许,但检查漏掉了某些情况,例如列引用隐含在整行引用中的情况。

  • 禁止在 COPY ... FROM ... WHERE 子句中使用生成列(Peter Eisentraut、Jian He) §

    以前,尝试引用这类列会导致错误行为或晦涩的错误消息,因为在执行 WHERE 过滤时,生成列尚未计算出来。

  • 避免并行 vacuum 中潜在的 use-after-free(Kevin Oommen Anish) §

    该缺陷在标准构建中似乎没有实际后果,但理论上仍存在风险。

  • 修复 pg_temp 中统计对象的可见性检查(Noah Misch) §

    位于临时模式中的统计对象若不带模式限定名就无法命名,但 pg_statistics_obj_is_visible() 漏掉了这一点,因此无论如何都可能返回 true。进而,像 pg_describe_object() 这样的函数可能无法按预期给对象名称加上模式限定。

  • 修复 pg_event_trigger_dropped_objects() 对临时状态的报告问题(Antoine Violin, Tom Lane) § §

    如果被删除的列默认值、触发器或 RLS 策略属于临时表,则应将其以 is_temporary 为 true 的形式报告出来。

  • 修复哈希子计划中的内存泄漏(Haiyang Li) §

    对元组进行哈希时,哈希函数消耗的任何内存都会构成贯穿整个查询生命周期的内存泄漏。被哈希的值如果需要执行 detoast,就是一种可能发生这种情况的场景。

  • 避免启动进程中的 SMgrRelation 对象泄漏(Jingtang Zhang) §

    在长时间运行的备库服务器上,保存这些对象的哈希表可能会显著膨胀,因为原先没有释放不再需要条目的机制。

  • 修复回放数据库创建 WAL 期间的小型内存泄漏(Nathan Bossart) §

  • 修复内存耗尽失败后共享统计信息表损坏的问题(Mikhail Kot) §

    先前,如果在创建新的哈希表条目过程中途发生内存耗尽失败,就会遗留一个损坏的条目,之后可能导致其他会话报错。

  • 修复 MERGE 中的并发更新问题(Yugo Nagata) §

    执行 MERGE UPDATE 动作时,如果目标行发生了多次并发更新,锁定并重试代码有时会错误识别目标元组的最新版本,从而产生错误结果。

  • MERGEINSERT ... ON CONFLICT DO UPDATE 补充缺失的 replica identity 检查(Zhijie Hou) § § §

    如果 MERGE 可能需要执行更新或删除动作,且目标表发布了更新或删除,则必须定义 REPLICA IDENTITY。若不作此要求,复制可能会在静默状态下被破坏。同样地,带有 UPDATE 选项的 INSERT,如果目标表发布了插入或更新,也必须要求定义 REPLICA IDENTITY

  • 当发布者与订阅者位于同一服务器上时,避免在 DROP SUBSCRIPTION 期间发生死锁(Dilip Kumar) §

  • 修复 pg_stat_replication 视图中复制延迟报告不正确的问题(Fujii Masao) §

    如果某个备库的回放 LSN 停止推进,write_lagflush_lag 列最终也会停止更新。

  • 避免针对无效 primary_slot_name 设置重复记录日志消息(Fujii Masao) §

  • synchronized_standby_slots 引用了不存在的复制槽时,避免发生故障(Shlok Kyal) §

  • 在将复制槽状态写入磁盘失败后,移除未完成的槽状态文件(Michael Paquier) §

    先前,磁盘空间耗尽之类的失败会遗留一个临时 state.tmp 文件。这会造成问题,因为它会阻塞之后所有写入该状态的尝试,必须人工清理。

  • 修复逻辑复制并行 apply 工作进程对锁超时信号处理不当的问题(Hayato Kuroda) §

    同一个信号编号同时用于工作进程关闭和锁超时,导致了混淆。

  • 从流复制 WAL 源切换到归档 WAL 源时,避免 WAL 接收器被意外关闭(Xuneng Zhou) §

    在时间线切换期间,备库的 WAL 接收器本应保持存活并等待新的 WAL 流起点。此前它却会反复关闭并立即重启,这可能会让状态监控代码产生混淆。

  • 避免常规表与临时表文件号偶然冲突而导致逻辑复制失败(Vignesh C) §

    这个低概率问题表现为诸如 unexpected duplicate for tablespace X, relfilenode Y 之类的瞬时错误。contrib/autoprewarm 也受此影响。该修复的一个副作用是,SQL 函数 pg_filenode_relation() 现在会忽略临时表。

  • 修复 pgoutput 逻辑解码插件维护的关系同步缓存中的 use-after-free 问题(Vignesh C, Masahiko Sawada) §

    逻辑解码期间发生错误时,可能导致同一会话后续的逻辑解码尝试崩溃。只有通过 SQL 函数调用 pgoutput 时才会触发这种情况。

  • 避免逻辑复制槽被不必要地标记为无效(Bertrand Drouvot) §

  • 避免在单用户模式下尝试释放复制槽时触发断言失败(Hayato Kuroda) §

  • 修复检查用户是否具有 Windows 管理员权限失败时消息打印不正确的问题(Bryan Green) §

    这段代码原本会崩溃,至少也会打印出乱码。不过目前尚未有此类案例报告,说明这些系统调用发生失败的情况极为罕见。

  • 在 macOS 和 BSD 平台上,若与预先存在的信号量集合冲突,避免启动失败(Tom Lane) §

    如果预先存在的信号量集合所含信号量少于我们请求的数量,这些平台返回的是 EINVAL 而不是代码原先预期的 EEXIST,从而导致数据库启动失败。

  • 使用某些 libsanitizer 选项测试 PostgreSQL 时,避免发生崩溃(Emmanuel Sibi, Jacob Champion) §

  • 修复 64 位 Windows 上调试构建中的误报内存上下文检查警告(David Rowley) §

  • 在 PL/pgSQL 赋值语句中正确处理 GROUP BY DISTINCT(Tom Lane) §

    解析器在该上下文中未能记录 DISTINCT 选项,因此该命令会被当作普通的 GROUP BY 来执行。

  • 避免在 PL/Python 内处理 SQL 错误时发生内存泄漏(Tom Lane) §

    这修复了我们在先前次版本发布中引入的一个贯穿整个会话生命周期的内存泄漏。

  • 修复 libpq 对高位已置位字符的跟踪输出问题(Ran Benita) §

    在将 char 视为有符号类型的平台上,输出中会带有难看的 \xffffff 修饰。

  • 修复 libpq 在 Windows 上其 GSSAPI 逻辑中对套接字相关错误的处理(Ning Wu, Tom Lane) §

    使用 GSSAPI 对传输数据进行加解密的代码未能正确识别连接套接字上的错误状态,因为 Windows 对此类错误的报告方式与其他平台不同。这导致在 Windows 上无法建立此类连接。

  • 修复继承表列上非继承而来的非空约束的转储问题(Dilip Kumar) §

    从早于 v18 的服务器转储时,pg_dump 未能保留这类约束。

  • pg_dump 中,转储订阅和事件触发器上的安全标签(Jian He, Fujii Masao) §

    先前遗漏了这些类型对象上的标签。

  • 修复 pg_dump 对默认 ACL 和外键约束的排序问题(Kirill Reshke, Álvaro Herrera) § § §

    确保这些数据库对象类型的排序保持一致,正如其他对象类型早已做到的那样。

  • pg_dump 中,为单独转储的域约束上的注释标注正确的依赖关系(Noah Misch) §

    该错误可能导致并行 pg_restore 在约束本身尚未恢复之前就尝试创建注释。

  • pg_restore 中,跳过未被恢复的发布和订阅上的注释及安全标签(Jian He, Fujii Masao) § §

    当指定 --no-publications--no-subscriptions 时,不要为这些对象输出 COMMENTSECURITY LABEL 命令。

  • 修复 pg_dumppg_restore 中数据压缩逻辑里的多处错误(Daniel Gustafsson, Tom Lane) § § §

    多处位置缺少错误检查或实现不正确,此外还存在会在大端硬件上显现的可移植性问题。此前未发现这些问题,是因为这段代码仅用于读取目录格式转储中的压缩 TOC 文件,而 pg_dump 本身不会生成这样的转储;只有在事后手工压缩 TOC 文件时才会触发这种情况,虽然这是受支持的做法,但非常少见。

  • 修复 pgbench,使其在启动 COPY 操作时能够干净地报错退出(Anthonin Bonnefoy) §

    pgbench 本就无意支持这种情况,但此前它会陷入无限循环。

  • 修复 pgbench 对多个错误的报告问题(Yugo Nagata) §

    如果连续两次 PQgetResult 调用都失败,pgbench 可能会报告错误的错误消息。

  • pgbench 中,修复有关管线模式错误的错误断言(Yugo Nagata) §

  • 修复 pg_combinebackup 中每个文件的内存泄漏(Tom Lane) §

  • 确保 contrib/pg_buffercache 函数可以被取消(Satyanarayana Narlapuram, Yuhang Qiu) §

    某些代码路径可能会在长时间运行时不检查中断。

  • 修复 contrib/pg_prewarm 对索引的权限检查(Ayush Vatsa, Nathan Bossart) § §

    pg_prewarm() 要求对待预热关系具有 SELECT 权限。然而,由于索引自身没有 SQL 权限,这会导致非超级用户无法预热索引。因此,改为检查索引所属表上的 SELECT 权限。

  • 提高 contrib/pgstattuple 处理空或无效索引页时的健壮性(Nitin Motiani) §

    将全零页面计为可用空间,并忽略那些经页面特殊空间大小检查后判定为无效的页面。btree 索引的代码本就把全零页面计为空闲,但 hash 和 gist 的代码会直接报错,这已被证明远不如前者友好。同样地,现在让这三种情况都统一为忽略损坏页面,而不是抛出错误。

  • 强化读写屏障宏以满足 Clang 的要求(Thomas Munro) §

    我们原以为 __atomic_thread_fence() 足以阻止 C 编译器对其前后的内存访问重新排序,但看来 Clang 并非如此处理,因此它至少会在 RISC-V、MIPS 和 LoongArch 机器上生成错误代码。现已加入显式的编译器屏障以修复此问题。

  • 修复使用 LLVM 21 及更高版本时的构建问题(Holger Hoffstätte) §

  • 使用 meson 构建时,对 numeric.cchecksum.c 应用与 makefile 构建相同的特殊优化标志(Nathan Bossart, Jeff Davis) § §

    对这两个文件都使用 -ftree-vectorize,并为 checksum.c 额外使用 -funroll-loops,以与 makefile 长期以来的做法保持一致。

  • 修复 PGXS 构建基础设施,使其支持为扩展构建 NLS po 文件(Ryo Matsumura) §

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。