发布说明

PostgreSQL 16.4

E.10. 发布版本 16.4 #

发布日期:. 2024-08-08

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

E.10.1. 迁移到版本 16.4 #

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

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

E.10.2. 变更 #

  • 防止在 pg_dump 期间执行未授权的代码 (Masahiko Sawada) §

    能够创建和删除非临时对象的攻击者可以注入 SQL 代码, 该代码会被并发的 pg_dump 会话以运行 pg_dump 的角色权限(通常是超级用户)执行。 攻击方法是将序列或类似对象替换为会执行恶意代码的视图或外部表。 为防止此问题,引入了新的服务器参数 restrict_nonsystem_relation_kind, 可以禁用非内置视图的展开以及对外部表的访问, 并让 pg_dump 在可用时设置该参数。 请注意,只有当 pg_dump 和它所导出的服务器 都足够新以包含此修复时,才能防止该攻击。

    PostgreSQL 项目感谢 Noah Misch 报告此问题。 (CVE-2024-7348)

  • 避免合并右反连接计划产生不正确的结果 (Richard Guo) §

    如果已知内部关系具有唯一的连接键,当外部关系中存在重复的连接键时, 合并可能会出现异常行为。

  • 防止 VACUUM 中的无限循环 (Melanie Plageman) §

    在一个具有旧事务的断开连接的备库重新连接到主库后, 主库上的 VACUUM 可能会对哪些元组可以被删除产生混淆, 从而导致无限循环。

  • 修复将表作为分区挂接后的失败问题,如果该表之前有继承子表 (Álvaro Herrera) §

  • 修复 ALTER TABLE DETACH PARTITION 在涉及 不一致的基于索引的约束时的问题 (Álvaro Herrera,Tender Wang) § §

    当分区表有一个不与约束关联的索引,但其分区有一个等效的且与约束关联的索引时, 分离该分区会出现异常行为,导致前分区的约束具有不正确的 coninhcount 值。 这会在后续对该约束进行任何操作时造成问题。

  • 修复 ALTER TABLE DETACH PARTITION CONCURRENTLY 期间的分区修剪设置 (Álvaro Herrera) § §

    执行器假定在对分区表的查询规划和执行之间不会有分区被分离。 自从引入 DETACH PARTITIONCONCURRENTLY 选项后, 这一假设不再成立,使得在使用该选项时查询执行可能会出现短暂的失败。

  • 在删除最后一个子分区后,正确更新分区表的 pg_class.reltuples 字段为零(Noah Misch) §

    对这样的分区表进行第一次 ANALYZE 时必须同时更新 relhassubclass,而这导致 reltuples 的更新被丢失。

  • 修复过程的多态输出参数的处理 (Tom Lane) § §

    SQL CALL 语句未能为此类参数解析正确的数据类型, 导致诸如 cannot display a value of type anyelement 之类的错误, 甚至直接崩溃。(但 PL/pgSQL 中的 CALL 可以正确工作。)

  • 修复从 CALL 语句的参数列表中调用稳定函数时的行为 (Tom Lane) §

    如果 CALL 位于原子上下文中 (例如存在外部事务块),此类函数会被传递错误的快照, 导致它们看到自外部事务开始以来已修改的行的过期值。

  • 修复 timetimetz 类型的 ISO-8601 扩展时间格式的输入 (Tom Lane) §

    重新允许诸如 T12:34:56 之类的情况。

  • 检测 money 计算中的整数溢出 (Joseph Koshakow) §

    money 类型的所有算术函数之前都没有检查溢出, 因此在溢出情况下会静默地给出错误的结果。

  • 修复 round(numeric)trunc(numeric) 中对精度参数的过度截断 (Dean Rasheed) §

    这些函数将精度参数截断到 +/-2000,但存在需要更大值的有效用例; 在这些情况下函数返回了不正确的结果。 改为截断到 numeric 类型的实际允许范围。

  • 修复 pg_size_pretty() 应用于最小 bigint 值时的结果 (Joseph Koshakow) §

  • 防止 pg_sequence_last_value() 在备库上的 非日志序列以及其他会话的临时序列上失败 (Nathan Bossart) §

    在这些情况下使其返回 NULL 而不是抛出错误。

  • 修复 websearch_to_tsquery() 中被忽略的操作符的解析 (Tom Lane) §

    根据手册,websearch_to_tsquery() 的输入中的标点符号 除了破折号和引号的特殊情况外都会被忽略。然而,紧接在 or 之前出现的括号和其他一些字符可能导致 or 被视为数据词,而非预期的 OR 操作符。

  • 检测计算新数组维度时的另一个整数溢出情况 (Joseph Koshakow) §

    拒绝将数组维度 [-2147483648:2147483647] 应用于空数组。这与 CVE-2023-5869 密切相关,但似乎是无害的, 因为数组最终仍然是空的。

  • 修复 strnxfrm() 的不可移植用法(Jeff Davis) §

    非确定性排序规则的某些代码路径可能会因诸如 pg_strnxfrm() returned unexpected result 之类的错误而失败。

  • 检测在对目录缓存条目的字段进行解压缩时该条目变为过期的另一种情况 (Noah Misch) §

    在我们展开目录元组中的行外字段时发生的就地更新可能会被遗漏, 导致目录缓存条目缺少就地更改但不被标记为过期。 这仅在 pg_database 目录中可能发生, 因此影响范围有限,但可能出现异常行为。

  • 正确检查 INSERT ... DEFAULT 目标视图列的可更新性 (Tom Lane) §

    如果这样的列是不可更新的,我们应该给出相应的错误报告。 但该检查被遗漏了,之后的代码会报告一个无用的错误,如 attribute number N not found in view targetlist

  • 避免对不正确的递归查询报告无用的内部错误 (Tom Lane) §

    重新安排错误检查的顺序,以便当 WITH RECURSIVE 查询 在 UNION 的第二个分支中没有自引用, 但在其他地方(如 ORDER BY)有自引用时, 抛出一个有针对性的错误。

  • ALTER TABLE SET LOGGED|UNLOGGED 期间锁定拥有的序列(Noah Misch) §

    这些命令会随表一起更改表所拥有的序列的持久性,但它们在执行时 未能获取序列上的锁。这可能导致并发 nextval() 调用的结果丢失。

  • 当排队的 AFTER 触发器不再存在时不抛出错误 (Tom Lane) §

    事务可能会执行一个操作将延迟的 AFTER 触发器 排队等待后续执行,然后在触发器执行之前将其删除。 之前这会导致诸如 could not find trigger NNNN 之类的奇怪错误。 如果触发器在应该执行的时间点已不存在,静默地不做任何操作似乎更好。

  • 修复在删除表时未能移除 pg_init_privs 中 列级权限条目的问题(Tom Lane) §

    如果扩展对其创建的表授予了某些列级权限,在删除该扩展后 相关的目录条目会被保留。这在表的 OID 被另一个关系重新使用之前是无害的, 届时它可能会干扰 pg_dump 对该关系的导出。

  • 修复当目标索引具有表达式或谓词时 ON CONFLICT 仲裁索引的选择(Tom Lane) §

    如果使用 ON CONFLICT 的查询通过可更新视图访问目标表, 可能会失败并报告 there is no unique or exclusion constraint matching the ON CONFLICT specification,即使存在匹配的索引。

  • 拒绝使用 ALTER TABLE 修改另一个会话的临时表 (Tom Lane) §

    权限检查通常会阻止此类情况发生,但可以通过修改一个其子表 是另一个会话的临时表的父表来达到此情况。 如果我们发现这样的子表属于另一个会话,则抛出错误。

  • 修复 CREATE TABLE LIKE STATISTICS 中 对表达式上扩展统计信息的处理(Tom Lane) §

    CREATE 命令未能将统计表达式中的列引用 调整为新表可能不同的列编号。这会产生无效的统计对象, 在后续操作中造成问题。需要重新编号列的典型场景是源表包含一些已删除的列。

  • 修复从 MIN()MAX() 聚合生成的子查询未能重新计算的问题(Tom Lane) §

    在某些情况下,在外部查询的某一行计算出的聚合结果可能会被后续行 错误地重用。目前仅在外部查询使用以哈希聚合实现的 DISTINCT 时观察到此问题,但可能存在其他情况。

  • 重新禁止位置参数中包含下划线(Erik Wienhold) §

    从 v16 开始我们允许整数字面量包含下划线。 此更改导致诸如 $1_234 之类的输入被当作单个标记处理, 但它不能正确工作。恢复到原始定义似乎更好, 即参数符号仅为 $ 后跟数字。

  • 避免在 JIT 内联的后端函数抛出错误时崩溃 (Tom Lane) §

    错误状态可以包含指向持有 JIT 编译代码的动态加载模块的指针 (用于错误位置字符串)。在某些代码路径中,模块可能在错误报告被处理之前 被卸载,导致访问位置字符串时出现 SIGSEGV。

  • 应对 libxml2 2.13.x 版本中的行为变更 (Erik Wienhold,Tom Lane) §

    值得注意的是,我们现在会抑制来自 libxml2chunk is not well balanced 错误,除非这是唯一报告的错误。 这是为了使 2.13.x 和更早版本的 libxml2 之间的错误报告保持一致。在早期版本中,该消息几乎总是冗余的或完全不正确的, 因此 2.13.x 大幅减少了报告该消息的情况。

  • 修复启动热备服务器时预备事务的子事务处理 (Heikki Linnakangas) §

    当备库在关机检查点 WAL 记录处开始回放时, 在主库上已预备但尚未提交的事务会被正确地理解为仍在进行中。 但预备事务的子事务(由保存点或 PL/pgSQL 异常块创建)未被考虑,会被当作已中止的事务处理。 如果预备事务随后被提交,就会导致不一致。

  • 防止逻辑复制槽的不正确初始化 (Masahiko Sawada) §

    在某些情况下,复制槽在 WAL 流中的起始点可能被设置为事务内部的某个点, 导致断言失败或不正确的解码结果。

  • 避免在复制槽创建和删除期间出现 can only drop stats once 错误 (Floris Van Nee) §

  • 修复逻辑复制 WAL 发送器中的资源泄漏(Hou Zhijie) §

    当发布对分区表的更改时,如果分区的行类型与分区表的行类型物理上不同, walsender 进程会泄漏内存。

  • 避免在处理通知或共享失效中断后的内存泄漏 (Tom Lane) §

    这些事件的处理函数可能将当前内存上下文切换到 TopMemoryContext, 导致在错误设置被替换之前分配的任何数据出现会话级别的泄漏。 至少在传入查询的编码转换和附加到 Bind 消息的参数方面存在可观察到的泄漏。

  • 防止用于统计信息的共享内存块的引用计数泄漏 (Anthonin Bonnefoy) §

    新的后端进程在附加到统计共享内存时会增加其引用计数, 但在退出时未能减少该计数。 在创建 232 个会话后,引用计数会溢出为零, 导致所有后续后端进程启动失败。

  • 防止在截断多事务 SLRU 日志时出现死锁和断言失败 (Heikki Linnakangas) §

    尝试删除 SLRU 段的进程可能与检查点进程发生死锁。

  • 避免在 Windows 套接字上可能遗漏输入结束事件 (Thomas Munro) §

    Windows 在连接的远端断开连接后只报告一次 FD_CLOSE 事件。 如果时机不巧,我们可能会错过该报告,从而无限期等待 (或至少等到超时),期待更多输入。

  • 修复 JSON 解析错误报告中针对不完整字节序列的缓冲区越界读取 (Jacob Champion) §

    当最后的字节构成不完整的多字节字符时,可能会在输入缓冲区末尾 越界读取几个字节。虽然通常无害,但原则上这可能导致崩溃。

  • 禁用 OpenSSL 创建有状态的 TLS 会话票证 (Daniel Gustafsson) § § §

    这避免了认为收到会话票证就意味着支持 TLS 会话恢复的客户端可能出现的故障。

  • 在重新规划 PL/pgSQL 简单 表达式时,检查其是否仍然是简单的(Tom Lane) §

    某些相当人工的情况,如删除一个被引用的函数并将其重新创建为聚合函数, 可能导致诸如 unexpected plan node type 之类的意外失败。

  • 修复 PL/pgSQL 对包含下划线的整数范围的处理 (Erik Wienhold) §

    从 v16 开始我们允许整数字面量包含下划线, 但 PL/pgSQL 未能处理诸如 FOR i IN 1_001..1_003 之类的示例。

  • 修复返回 RECORD 类型的递归 PL/Python 函数(Tom Lane) §

    如果递归到同一函数的新调用并传递了不同的列定义列表(AS 子句), 将会失败,因为内部调用会覆盖外部调用所期望的返回行类型。

  • 防止在递归触发器调用期间损坏 PL/PythonTD 字典(Tom Lane) §

    如果一个 PL/Python 语言的触发器导致另一个 触发器被调用,为内部触发器创建的 TD 字典 会覆盖外部触发器的 TD 字典。

  • 修复 PL/Tcl 在返回元组的函数结果中 存在无效列表语法时的报告(Erik Wienhold,Tom Lane) §

    这种情况可能导致崩溃,或发出实际上引用的是之前 Tcl 错误的 误导性上下文信息。

  • 避免在 libpq 中使用非线程安全的 strerror()(Peter Eisentraut) §

    在多线程应用程序中,OpenSSL 返回的某些错误消息可能会变得混乱。

  • 避免在二进制升级期间 pg_dump 中的内存泄漏 (Daniel Gustafsson) §

  • 确保 pg_restore -l 正确报告依赖的 TOC 条目(Tom Lane) §

    如果 -l 与选择性恢复选项(如 -n-N)一起指定, 依赖的 TOC 条目(如注释)会从列表中被省略, 即使实际恢复会选择它们。

  • 允许 contrib/pg_stat_statements 区分 出现在 SQL 语言函数中的工具语句 (Anthonin Bonnefoy) §

    SQL 语言函数执行器未能传递为工具 (非 SELECT/INSERT/UPDATE/DELETE/MERGE) 语句计算的查询 ID。

  • 避免 contrib/postgres_fdw 中出现 cursor can only scan forward 错误 (Etsuro Fujita) §

    如果远程服务器是 v15 或更高版本,并且外部表映射到非平凡的远程视图, 可能会出现此错误。

  • contrib/postgres_fdw 中,不向远程服务器 发送 FETCH FIRST WITH TIES 子句 (Japin Li) §

    远程服务器可能不支持此子句,或可能对其解释与本地不同, 因此不要冒险尝试远程执行。

  • 避免与系统提供的 <regex.h> 头文件冲突 (Thomas Munro) §

    这修复了 macOS 15 及更高版本上的编译失败问题。

  • 修复 Memoize 代价估算中的无害断言失败 (David Rowley) §

  • 修复对 SP-GiST 索引执行 REINDEX CONCURRENTLY 时的无害断言失败(Tom Lane) §