发布日期:. 2025-08-14
本次发布包含自 17.5 以来的多项修复。 有关 17 主版本中新特性的更多信息,请参见 Section E.10。
对于运行 17.X 的用户,无需执行转储/恢复。
不过,如果你有任何 BRIN numeric_minmax_multi_ops 索引,建议在更新后对其重建索引。见下文第四条变更记录。
此外,如果你是从早于 17.5 的版本升级,请参见 Section E.5。
加强规划器估算函数中的安全检查(Dean Rasheed) §
针对 CVE-2017-7484 的修复以及后续修复,本意是防止泄漏函数被应用到调用用户无权读取的列统计数据上。现已发现该保护存在两个缺口。其中一个缺口出现在分区和继承层级中,表上的 RLS 策略本应限制对统计数据的访问,但实际上没有做到。
另一个缺口出现在查询经由视图访问表的场景中:视图所有者有权读取底层表,但调用用户对该视图并无权限。由于视图所有者的权限满足了安全检查,泄漏函数会在我们检查调用用户对该视图的权限之前,就被应用到该底层表的统计信息上。现已通过将视图上的安全检查提前到规划开始阶段来修复这一问题。这可能会使权限失败比以前更早发生。
PostgreSQL 项目感谢 Dean Rasheed 报告此问题。 (CVE-2025-8713)
防止利用 pg_dump 脚本攻击执行恢复的用户(Nathan Bossart) §
由于转储/恢复操作通常涉及以超级用户身份执行 SQL 命令,因此目标数据库安装必须信任源服务器。然而,这并不意味着执行 psql 来完成恢复的操作系统用户也必须信任源服务器。这里的风险在于,若攻击者已取得源服务器上的超级用户级控制权,就可能诱使它输出会被解释为 psql 元命令的文本。这将使攻击者能够获得执行恢复的用户账户的 shell 级访问权限,而与目标数据库本身的访问权限无关。
为了给出这种情况不会发生的明确保证,我们扩展了 psql,新增 \restrict 命令以阻止进一步执行元命令,并让 pg_dump 在接收任何来自源服务器的数据之前先发出该命令。
PostgreSQL 项目感谢 Martin Rakhmanov、Matthieu Denais 和 RyotaK 报告此问题。 (CVE-2025-8714)
将 pg_dump 输出中注释所含名称里的换行转换为空格(Noah Misch) §
含有换行的对象名称会带来向输出脚本中注入任意 SQL 命令的能力。(若没有前一项修复,也可以借此注入 psql 元命令。)CVE-2012-0868 当年修复过这一类问题,但后续工作又重新引入了若干情形。
PostgreSQL 项目感谢 Noah Misch 报告此问题。 (CVE-2025-8715)
修复 BRIN numeric_minmax_multi_ops 支持函数中的距离计算错误(Peter Eisentraut, Tom Lane) §
在 64 位平台上,结果有时会出错;在 32 位平台上,则可能大错特错。之所以没有产生明显故障,是因为这段逻辑仅用于决定如何把值合并进范围;最坏情况下,索引只会变得低效并发生膨胀。尽管如此,仍建议对所有使用 numeric_minmax_multi_ops 操作符类的 BRIN 索引执行重建索引。
避免可接受的 XML 输入大小上限发生回退(Michael Paquier, Erik Wienhold) § §
我们为 libxml2 早期 2.13.x 版本中的一个缺陷所做的变通处理,使用了一条会拒绝超过 10MB 文本块的代码路径,而之前的实现并不会这样做。考虑到这些早期版本现在在实际环境中大概已经绝迹,因此恢复到此前的实现方式。
修复 MERGE 在并发更新下的问题(Dean Rasheed) §
如果 CTE 内部的 MERGE 尝试对带有 BEFORE ROW 触发器的表执行更新或删除,而并发的 UPDATE 或 DELETE 又修改了目标行,那么 MERGE 命令将会失败(在更新动作情况下会崩溃,而在删除动作情况下则可能执行错误的动作)。
修复向普通继承父表执行 MERGE 的问题(Dean Rasheed) §
向这类目标表插入数据时,可能因为未能正确处理 WITH CHECK OPTION 和 RETURNING 动作而崩溃,或产生错误的查询结果。
允许带语句级触发器的表成为分区或继承子表(Etsuro Fujita) §
我们不允许分区或继承子表拥有带过渡表的行级触发器,因为对整个继承树执行操作时,需要为每个此类子表维护独立的过渡表。但语句级触发器不存在这个问题,因为只会触发父表上的语句级触发器。然而,用于检查现有表能否成为分区或继承子表的代码,却把这两类触发器一并拒绝了。
禁止从外部子表收集过渡元组(Etsuro Fujita) §
我们不支持在外部表上使用带过渡表的触发器。然而,分区或继承子表本身是外部表的情况此前被忽略了。若父表拥有这类触发器,就会从该外部子表中收集到错误的过渡元组。现在改为抛出错误,说明该场景不受支持。
允许重置带保留前缀的未知自定义参数(Nathan Bossart) §
先前,如果某个参数设置是通过 ALTER DATABASE/ROLE/SYSTEM 存储的,那么当该参数未知但带有保留前缀时,就无法移除该存储设置。若某扩展曾经有一个参数,但在升级中删除了该参数,就可能出现这种情况。
修复 ALTER SUBSCRIPTION ... DROP PUBLICATION 期间潜在的死锁(Ajin Cherian) §
确保服务器进程在删除复制源时,以一致的顺序获取系统目录锁。
缩短创建名称冲突索引时的竞争窗口(Tom Lane) §
在为索引选择自动生成的名称时,除了完全有效的 pg_class 行之外,也要避免与尚未提交的 pg_class 行发生冲突。这样可以避免在并发 CREATE INDEX 尚处于填充索引过程中,或虽已完成但其事务尚未提交时,意外选中同一个名称。虽然仍然存在一个出问题的窗口,但其长度仅限于验证新索引参数并插入其 pg_class 行所需的时间。
防止在单条命令对多个表执行 VACUUM 的某些情况下使用错误的选项(Nathan Bossart, Michael Paquier) §
一个表的 TRUNCATE 和 INDEX_CLEANUP 选项可能会被错误地应用到其他表上。
确保在 vacuum 没有索引的表时,表的自由空间映射能及时更新(Masahiko Sawada) §
先前的一项优化会导致这类表有时跳过 FSM vacuum。
修复 SIMILAR TO 正则表达式中字符类的处理问题(Laurenz Albe) § §
将 SIMILAR TO 模式匹配表达式转换为 POSIX 风格正则表达式的代码,没有考虑到方括号可以嵌套。例如,在 [[:alpha:]%_] 这样的模式中,代码把 % 和 _ 字符当成了元字符,但它们本应是字面量。
在反解析查询时,始终为 FETCH FIRST 子句中的表达式加上括号(Heikki Linnakangas) § §expression ROWS WITH TIES
这可以避免某些情况下反解析结果在语法上无效。
限制检查点进程的 fsync 请求队列大小(Alexander Korotkov, Xuneng Zhou) § §
当 shared_buffers 设置非常大时,检查点进程可能尝试为 fsync 请求分配超过 1GB 的空间,从而导致失败并陷入无限循环。现已限制队列大小以防止这种情况。
避免逻辑解码读取部分写入的 WAL 记录时发生无限等待(Vignesh C) §
如果服务器在写入一个跨越多个页面的 WAL 记录的第一部分后崩溃,那么后续对该 WAL 流的逻辑解码就会等待下一页 WAL 上的数据到达。若服务器此时处于空闲状态,这种情况可能永远不会发生。
修复 MultiXactOffsetSLRU 和 MultiXactMemberSLRU 的 LWLock 名称拼写不一致问题(Bertrand Drouvot) §
这导致 pg_wait_events 和 pg_stat_activity 中显示的等待事件名称不同,可能破坏连接这两个视图的监控查询。
修复 ACL 字符串中角色名引用方式不一致的问题(Tom Lane) §
先前的引用规则依赖区域设置,这在跨安装环境传递 aclitem 值时可能带来可移植性问题。(pg_dump 不会这样做,但其他工具可能会。)为保证一致性,现在在 aclitem 输出中始终引用非 ASCII 字符;但为了保持向后兼容,在 aclitem 输入时仍绝不要求必须引用它们。
拒绝在关系选项和外部数据选项名称中使用等号(=)(Tom Lane) §
这类选项名称看不出有什么明确用途,而且允许它们会在存储表示中引入歧义。
修复可能不正确地解压 LZ4 压缩归档数据的问题(Mikhail Gribkov) §
这个错误似乎只会在不太容易压缩的输入数据上表现出来,这或许可以解释它为何一直未被发现。
避免 btree 索引扫描在罕见场景下把错误的索引条目标记为 dead(Peter Geoghegan) §
避免在逻辑复制期间重新分发来自其他事务的缓存失效消息(Vignesh C) §
我们上一轮次版本发布中包含了一项修复,确保复制接收进程会响应跨进程缓存失效消息,从而避免它们在执行复制更新时使用过期的系统目录数据。然而,该修复无意中也让这些进程再次重新分发这些消息,导致失效消息数量呈指数级增长,并且常常以内存分配失败告终。现已通过不重新分发收到的消息来修复该问题。
当复制槽同步配置错误时,避免服务器意外关闭(Fujii Masao) §
如果 sync_replication_slots 被设为 true,而 wal_level 又低于 logical,postmaster 进程就会报告错误并随之停止。理想行为只是禁用复制槽同步,因此现在降低该错误消息的级别,以避免 postmaster 被关闭。
避免在检查点期间过早移除旧 WAL(Vitaly Davydov) §
如果在检查点进行期间推进了某个复制槽的 restart point,那么已不再需要的 WAL 段可能会被过早移除,从而在数据库随后立即崩溃时导致恢复失败。现已通过额外保留一个检查点周期来修复此问题。
绝不要向后移动复制槽的 confirmed-flush 位置(Shveta Malik) §
在某些情况下,复制客户端可能会确认一个超过其持久化存储位置的 LSN,然后在重启后又发送一个更旧的 LSN。只要客户端对这两个位置之间的 WAL 没有任何必须执行的操作,我们就认为这并不是缺陷。不过,为避免数据重复,我们不应重新发送那段 WAL,因此要确保对给定槽始终采用最新的 confirmed LSN。
防止在启动新的逻辑复制工作进程前出现过长延迟(Tom Lane) §
在某些情况下,逻辑复制启动器在启动新工作进程之前,休眠时间可能会远远超过所配置的 wal_retrieve_retry_interval。
修复逻辑复制 INSERT ... ON CONFLICT 时的 use-after-free 问题(Ethan Mertz, Michael Paquier) §
这可能导致进度报告不正确,运气极差时还可能导致 WAL sender 进程崩溃。
允许中断在备库服务器上等待事务结束的操作(Kevin K Biju) §
在备库服务器上创建复制槽时,可能需要等待主库上的某些活动事务结束,并在备库上完成回放。由于这可能是无限期等待,因此理应允许取消该操作,但原先循环中没有检查查询取消。
不要让级联逻辑 WAL sender 尝试发送超出其备库服务器已回放范围的数据(Alexey Makhmutov) §
这可以避免此类 WAL sender 在备库服务器关闭时卡住,等待本不会发生的回放工作,因为服务器的启动进程此时已经关闭。
修复 autovacuum 中每个关系的内存泄漏(Tom Lane) §
修复 XMLSERIALIZE(... INDENT) 中贯穿会话生命周期的内存泄漏(Dmitry Kovalenko, Tom Lane) § §
修复使用 “bump” 分配器分配大块内存时,在内存耗尽后可能发生崩溃的问题(Tom Lane) §
修复某些位置可能在没有任何快照的情况下尝试提取系统目录 toast 字段的问题(Nathan Bossart) §
这可能导致断言失败,或出现 “cannot fetch toast data without an active snapshot” 错误。
移除“到 PortalRunMulti() 结束时必须已经确定命令标签”这一错误断言(Álvaro Herrera) §
这一断言会在空预备语句之类的边缘场景中失败。
修复 XMLTABLE 解析中的断言失败(Richard Guo) §
恢复并行执行 PL/pgSQL 表达式的能力(Dipesh Dhameliya) §
PL/pgSQL 对 “表达式” 的定义非常宽泛,涵盖任何返回单列且最多一行的 SQL SELECT 查询。因此,存在一些场景,例如聚合函数求值,这类查询包含相当多的工作量,使用并行工作进程执行会很有价值。此前这是可行的,但之前的一项缺陷修复无意间将其禁用了。
修复 PL/Python 错误报告中的边缘场景资源泄漏(Tom Lane) § §
在报告 Python 错误时发生内存耗尽失败,可能导致无法减少 Python 对象的引用计数,从而造成贯穿整个会话生命周期的内存泄漏。
修复当服务器地址使用 hostaddr 指定时 libpq 的 PQcancelCreate() 函数(Sergei Kornilov) §
如果实际使用生成出的 cancel 对象,libpq 就会崩溃。
修复 libpq 的 PQport() 函数,使其除非传入的连接为 NULL,否则绝不返回 NULL(Daniele Varrazzo) §
这是文档规定的行为,但最近的 libpq 版本会在用户未提供端口指定的某些情况下返回 NULL。现已恢复为历史行为,即在这些情况下返回空字符串。(而在 v18 及以后版本中,将改为返回编译时内置的默认端口号,通常为 "5432"。)
避免当 GSSAPI 认证需要大于 16kB 的数据包时发生失败(Jacob Champion, Tom Lane) §
属于许多 AD 组的 Active Directory 用户需要更大的认证数据包。这个限制表现为连接失败,并伴随难以理解的错误消息,典型如 “GSSAPI context establishment error: The routine must be called again to complete its function: Unknown error”。
修复 SSL 和 GSSAPI 数据传输中依赖时序的失败问题(Tom Lane) §
在非阻塞模式下使用 SSL 或 GSSAPI 加密时,libpq 有时会因 “SSL error: bad length” 或 “GSSAPI caller failed to retransmit all data needing to be retried” 而失败。
避免 ecpg 应用在查找连接期间发生空指针解引用(Aleksander Alekseev) §
只有当应用同时存在带名称和不带名称的连接时,才可能出现这种情况。
改进 psql 对 COPY 和 \copy 选项的 Tab 补全(Atsushi Torikoshi) §
原先对 COPY FROM 和 COPY TO 提供的是同样的补全项,尽管有些选项仅对其中一种情况有效。现在区分这些场景,以提供更准确的建议。
避免 pgbench 在收到多个 pipeline sync 消息时发生断言失败(Fujii Masao) §
修复使用 pg_createsubscriber 初始化订阅时事务被重复回放的问题(Shlok Kyal) §
在订阅者恢复期间处理的最后一个事务,有可能会在正常复制开始后再次被发送。
确保 pg_dump 转储域类型上非空约束的注释(Jian He, Álvaro Herrera) §
确保 pg_dump 按有效顺序转储域约束上的注释(Jian He) §
在某些情况下,注释命令可能会出现在约束创建之前。
确保 pg_dump 对所有类型的数据库对象采用稳定的排序顺序(Noah Misch, Andreas Karlsson) § § §
pg_dump 在按依赖关系重排之前,会先按对象的逻辑名称排序。此前,这一排序没有把规则、约束等某些对象类型的完整唯一键考虑进去,因此逻辑上相同的数据库也可能产生不同的排序结果。这使得通过比较 pg_dump 输出 diff 来比较数据库变得困难,因此改进了这部分逻辑,以确保在所有情况下都能得到稳定的排序顺序。
修复 pg_dump 过滤文件中对象类型解析错误的问题(Fujii Masao) §
现在将关键字视为一直延伸到下一个空白字符,而不是像以前那样在第一个非字母数字字符处停止。对于有效关键字,这没有区别;但它能让某些错误情况被正确识别。例如,table-data 现在会被拒绝,而以前会被误解为 table。
pg_restore 无法从 PostgreSQL v12 之前的 pg_dump 版本生成的目录格式转储中恢复大对象(BLOB)(Pavel Stehule) §
在 pg_upgrade 中,检查不一致的继承非空约束(Ali Akbar) § § §
18 之前的 PostgreSQL 版本允许删除继承列上的非空约束。然而,这会导致产生无法恢复的模式,从而使 pg_upgrade 失败。现在会在 pg_upgrade 的预检阶段检测此类情况,以便用户在开始升级前先行修复。
在 pg_upgrade 期间,不再要求目标安装将 max_slot_wal_keep_size 设置为其默认值(Dilip Kumar) §
如果在 initdb 期间启用了 track_commit_timestamp,避免发生断言失败(Hayato Kuroda, Andy Fan) §
修复 pg_waldump,使其显示 PREPARE TRANSACTION WAL 记录中被删除统计信息的相关内容(Daniil Davydov) §
避免在 contrib/dblink 建立连接期间可能泄漏已打开的连接(Tom Lane) §
在罕见情况下,如果我们在将新连接对象插入 dblink 的哈希表时遇到内存耗尽,那么该已打开的连接就会一直泄漏到会话结束,并在远程服务器上留下一个空闲会话。
使 contrib/pg_prewarm 能够处理非常大的 shared_buffers 设置(Daria Shanina) §
如果 shared_buffers 大于约 5000 万个缓冲区(400GB),autoprewarm 就会因内存分配错误而失败。
防止 contrib/pg_prewarm 中出现断言失败(Masahiro Ikeda) §
将 pg_prewarm() 应用于缺少存储的关系(如视图)时会导致断言失败,尽管在非断言构建中并无实际副作用。现已增加错误检查以拒绝这种情况。
在 contrib/pg_stat_statements 中,避免在规范化查询使用的参数编号集合中留下空洞(Sami Imseih) §
修复 contrib/postgres_fdw 的 DirectModify 方法中的内存泄漏(Tom Lane) §
如果查询在 DirectModify 方法两次调用之间失败,那么保存远程修改命令结果的 PGresult 就会在该会话剩余时间内泄漏;当存在 RETURNING 数据需要处理时,就可能发生这种情况。
确保 configure 的 --with-includes 和 --with-libraries 选项中列出的目录会在系统提供的目录之前被搜索(Tom Lane) §
使用这些选项的一个常见原因,是让用户自行构建的某个库版本覆盖系统提供的版本。然而,由于 makefile 发出的命令中开关顺序安排不当,这在某些环境中未能生效。
修复 configure 对 __cpuid() 和 __cpuidex() 的检查(Lukas Fittl, Michael Paquier) §
configure 未能检测到这些 Windows 特有函数,导致它们不会被使用。由于无法验证硬件指令是否可用,CRC 计算因此比必要情况更慢。这个错误的实际影响有限,因为 Windows 的生产构建通常不会使用 Autoconf 工具链。
修复在 Solaris 系平台上使用 --with-pam 选项时的构建失败(Tom Lane) §
Solaris 在 PAM 认证 API 上与其他 Unix 平台并不一致。这表现为一个 “inconsistent pointer” 编译器警告,而我们此前一直未处理它。但从 GCC 14 起,这默认已变为错误而非警告,因此需要修复。
使我们的代码可移植到 GNU Hurd(Michael Banck, Christoph Berg, Samuel Thibault) § §
修复关于 IOV_MAX 和 O_RDONLY 的假设,因为这些假设在 Hurd 上并不成立。
使我们对 memset_s() 的使用严格符合 C11 标准(Tom Lane) §
这可以避免某些平台上的编译失败。
消除使用 Meson 配合 MSVC 构建时的兼容性警告(Peter Eisentraut) §
防止 JSONB 比较代码中出现使用未初始化值的编译器警告(Tom Lane) §
避免在使用 libxml2 2.14 及更高版本构建时出现弃用警告(Michael Paquier) §
避免在 C++ 下编译 pg_locale.h 时出现问题(John Naylor) §
为了能被用 C++ 编写的扩展包含,PostgreSQL 头文件通常需要包裹在 extern "C" { ... } 中。由于 pg_locale.h 使用了 libicu 头文件,这一点此前无法成立;但我们可以通过屏蔽这些头文件中仅限 C++ 的声明来绕过该问题。希望使用 libicu 的 C++ API 的 C++ 扩展,可以在包含 pg_locale.h 之前先包含 libicu 头文件。
如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。