E.2. 发行版 16.1#
**发行日期:**2023-11-09
此发行版包含 16.0 中的各种修复。有关主要发行版 16 中的新功能的信息,请参见第 E.3 节。
E.2.1. 迁移到版本 16.1#
对于运行 16.X 的用户,不需要转储/还原。
但是,已发现几个错误,这些错误可能导致某些类型的索引产生错误的搜索结果或不必要地低效。建议在安装此更新后对可能受影响的索引执行REINDEX
。请参阅以下第四至第七个变更日志条目。
E.2.2. 更改#
修复
DISTINCT
"any"
聚合函数中未知类型参数的处理(Tom Lane)此错误导致
text
类型值在运行时被解释为unknown
类型值(即以零结尾的字符串)。这可能导致在text
值之后公开服务器内存。PostgreSQL 项目感谢 Jingzhou Fu 报告此问题。(CVE-2023-5868)
在计算新数组维度时检测整数溢出(Tom Lane)
在将新元素分配给超出当前数组边界的数组下标时,在极端情况下可能会发生未检测到的整数溢出。可能会出现可能被利用来执行任意代码的内存破坏,并且还可能公开服务器内存。
PostgreSQL 项目感谢 Pedro Gallegos 报告此问题。(CVE-2023-5869)
防止
pg_signal_backend
角色向后台工作进程和自动清理进程发出信号(Noah Misch、Jelte Fennema-Nio)文档指出
pg_signal_backend
无法向超级用户拥有的进程发出信号。不过,它能够向这些后台进程发出信号,因为它们通告的角色 OID 为零。将其视为表示超级用户所有权。从核心代码来看,取消这些进程类型之一的安全影响相当小(我们只需启动另一个进程),但扩展可能会添加更易受攻击的后台工作进程。还要确保在这些进程中正确设置
is_superuser
参数。尚未发现此疏忽的具体安全后果,但对于某些扩展而言,它可能很重要。PostgreSQL 项目感谢 Hemanth Sandrana 和 Mahendrakar Srinivasarao 报告此问题。(CVE-2023-5870)
修复 GiST 索引构建中递归页面拆分期间的行为不当(Heikki Linnakangas)
修复页面下链位置跟踪不正确的情况,并引入一些逻辑来允许从这种情况中恢复,而不是默默地做错事。此错误可能导致后续索引搜索的答案不正确。安装此更新后,建议重新索引所有 GiST 索引。
防止对
interval
列的 btree 索引条目进行重复数据删除(Noah Misch)有些
interval
值可区分但比较相等,例如24:00:00
和1 day
。这打破了 btree 重复数据删除所做的假设,因此interval
列需要从重复数据删除中排除。此疏忽会导致仅索引扫描的结果不正确。此外,在更新 amcheck 后,几乎所有此类索引都会报告错误。用户应重新索引interval
列上的任何 btree 索引。在 BRIN
datetime_minmax_multi_ops
索引中更合理地处理date
值(Tomas Vondra)日期的距离计算是向后的,导致无法正确决定合并哪些条目。该索引仍会产生正确的结果,但效率远低于应有的水平。建议重新索引
date
列上的 BRINminmax_multi
索引。在 BRIN
datetime_minmax_multi_ops
索引中更合理地处理较大的timestamp
和timestamptz
值(Tomas Vondra)错误地将无穷大视为与其他值距离为零,而不是距离较大,导致无法正确决定合并哪些条目。此外,有限但非常大的值(接近可表示时间戳范围的端点)可能导致内部溢出,从而再次导致错误的决策。该索引仍会产生正确的结果,但效率远低于应有的水平。如果列包含或包含无穷大或大有限值,建议重新索引
timestamp
和timestamptz
列上的 BRINminmax_multi
索引。避免在 BRIN
interval_minmax_multi_ops
索引中计算溢出,其中包含极端间隔值(Tomas Vondra)尝试将大型间隔值插入到此类索引时,此错误可能导致意外故障。
修复具有多个分区键的哈希分区表的 partition 步骤生成和运行时分区剪枝(David Rowley)
涉及分区键之一上的
IS NULL
条件的一些情况可能导致崩溃。修复在
MERGE
期间对并发更新行的不一致重新检查(Dean Rasheed)在
READ COMMITTED
模式中,发现其目标行刚被并发事务更新的更新将重新检查查询的WHERE
条件在更新的行上。MERGE
无法确保在此重新检查期间使用其他联接表的正确行,可能导致关于MERGE
是否应再次更新新更新的行的不正确决策。即使父表被约束排除,也能正确识别继承的
UPDATE
/DELETE
/MERGE
中的目标表(Amit Langote,Tom Lane)如果最初命名的表被约束排除,但并非其所有继承后代都被排除,则第一个未被排除的后代被识别为主要目标表。这将导致触发与该表关联的语句级触发器,而不是最初命名的表(如应发生的那样)。在 v16 中,同样的疏忽也可能导致 “RTE 中的无效 perminfoindex 0,relid 为 NNNN” 错误。
修复 btree 标记/还原处理 ScalarArrayOpExpr 子句中的边缘情况(Peter Geoghegan)
在将索引扫描还原到先前标记的位置时,如果扫描已精确推进到 ScalarArrayOpExpr(即
indexcol = ANY(ARRAY[])
)子句的匹配项末尾,则代码可能会错过必需的设置步骤。这可能导致丢失应获取的一些行。修复 Memoize 执行中的查询内内存泄漏(Orlov Aleksej,David Rowley)
修复当返回集函数重复返回零行时的查询内内存泄漏(Tom Lane)
如果将
cursor_to_xmlschema()
应用于不返回数据的 Portal,则不会崩溃(Boyu Yang)修复在连续的
pg_logical_slot_get_changes()
调用中不正确地共享源筛选条件(Hou Zhijie)此函数的一次调用设置的源条件将被未指定源参数的后续调用重新使用。这不是本意。
如果将
pgrowlocks()
应用于分区表,则抛出预期的错误(David Rowley)以前,会引发一个不切题的抱怨 “仅支持堆 AM”。
在各种 SQL 函数中更干净地处理无效索引(Noah Misch)
如果将
pgstatindex()
、pgstatginindex()
、pgstathashindex()
或pgstattuple()
应用于无效索引,则报告错误。如果将brin_desummarize_range()
、brin_summarize_new_values()
、brin_summarize_range()
或gin_clean_pending_list()
应用于无效索引,则除了报告调试级别消息之外,什么都不做。以前,这些函数会尝试处理索引,并且可能会以奇怪的方式失败,具体取决于失败的CREATE INDEX
遗留了什么。避免对
to_tsvector()
的长输入进行过早的内存分配失败(Tom Lane)修复
tsvectorrecv()
中构建的tsvector
的过度分配(Denis Erokhin)如果传入的向量包含位置数据,则二进制接收函数会在已完成的
tsvector
中留下浪费的空间(大约等于位置数据的大小)。在极端情况下,这会导致在发出时低于长度限制的向量出现 “超过最大总词素长度” 失败。在任何情况下,都可能导致磁盘上浪费空间。改进对损坏的 PGLZ 压缩数据的检查(Flavien Guedez)
修复
ALTER SUBSCRIPTION
,以便实际应用run_as_owner
选项中的命令更改(Hou Zhijie)修复分区表中的批量表插入(Andres Freund)
在分区之间不正确地共享插入状态可能会导致
COPY FROM
期间出现故障,通常表现为 “无法在文件 XXXX 中读取块 NNNN:仅读取 8192 字节中的 0 字节” 错误。在
COPY FROM
中,避免计算命令不需要的列默认值(Laurenz Albe)如果默认值实际上对列无效,或者如果默认值表达式在当前执行上下文中失败,则可以避免可能的错误。例如,在还原转储时有时会出现此类极端情况。以前的版本在这种情况下不会失败,因此防止 v16 这样做。
在
COPY FROM
中,在需要不支持的编码转换时干净地失败(Tom Lane)最近的重构意外地删除了对此的预期错误检查,因此它以 “函数 0 的缓存查找失败” 结束,而不是有用的错误消息。
如果由
EXPLAIN
标记为显示的参数具有 NULL 引导时间值,则避免在EXPLAIN
中崩溃(Xing Guo、Aleksander Alekseev、Tom Lane)没有内置参数符合此描述,但扩展可以定义此类参数。
确保在删除
ON COMMIT DROP
临时表时拥有快照(Tom Lane)如果临时表的任何目录条目具有足够宽的字段以至于需要吐司(例如非常复杂的
CHECK
条件),这将防止可能的错误行为。避免
system()
刚派生的子进程对关闭信号的错误响应(Nathan Bossart)此修复避免了竞争条件,其中由
system()
派生的子进程尚未执行预期的子程序,可能会接收并处理针对父服务器进程的信号。这将导致执行重复的清理操作,这不会顺利结束。应对前端程序中
pg_control
的撕裂读取(Thomas Munro)在某些文件系统上,当服务器同时写入
pg_control
时,读取pg_control
可能不是原子操作。这可以通过错误的 CRC 检测到。在报告错误之前,重试几次以查看文件是否有效。避免在相关 SQL 函数中撕裂读取
pg_control
(Thomas Munro)在读取
pg_control
之前获取适当的锁,以确保我们获得该文件的统一视图。修复在计划具有
ORDER BY
或DISTINCT
选项的聚合函数时发生的 “找不到要排序的路径键项目” 错误(David Rowley)在计算后端活动字符串数组大小时避免整数溢出(Jakub Wartak)
在 64 位机器上,我们将允许
track_activity_query_size
的值足够大,以至于在乘以允许的连接数时导致 32 位溢出。然而,实际分配每个后端本地数组的代码对此并不在意,并且错误地分配了数组。修复在继承表上对
ANALYZE
短暂显示不一致的进度统计信息(Heikki Linnakangas)当我们更新 current-relation 字段时,应该将块级计数器重置为零。
修复后台写入器以报告其对统计计数器进行的任何 WAL 写入(Nazir Bilal Yavuz)
修复
pgstat_report_wal()
中关于强制刷新行为的混淆(Ryoga Yoshida,Michael Paquier)这可能导致关闭时忘记有关 WAL I/O 的一些统计信息。
修复临时表扩展的统计信息跟踪(Karina Litskevich,Andres Freund)
当它们应该被视为临时表写入时,这些被视为普通表写入。
当启用
track_io_timing
时,将关系扩展操作所花费的时间计入写入时间(Nazir Bilal Yavuz)跟踪缓存的
CALL
语句的依赖关系,并在需要时重新规划它们(Tom Lane)DDL 命令(例如替换已内联到
CALL
参数中的函数)可能需要重新规划 PL/pgSQL 缓存的CALL
。这并未发生,导致错误行为或奇怪的错误,例如 “cache lookup failed”。避免 OpenSSL 连接设置错误后可能发生的 pfree-a-NULL-pointer 崩溃(Sergey Shinderuk)
从外部查询级别检查
RECORD
类型 Vars 时正确跟踪嵌套深度(Richard Guo)此疏忽可能导致断言失败、核心转储或 “bogus varno” 错误。
跟踪 ScalarArrayOpExpr 计划节点的哈希函数和否定函数依赖关系(David Rowley)
在大多数情况下,此疏忽是无害的,因为这些函数在节点的原始运算符仍然存在时不太可能消失。
修复
RECORD
类型缓存管理中的错误处理错误(Thomas Munro)在错误点发生的内存不足错误可能会留下不一致的状态,从而导致无限循环。
在读取 WAL 时将内存不足故障视为致命故障(Michael Paquier)
以前,这将被视为虚假数据条件,从而得出我们已达到 WAL 结尾的结论,这是不正确的,并且可能导致 WAL 重放不一致。
修复由于尝试基于虚假 WAL 记录长度字段分配内存而导致的可能的恢复故障(Thomas Munro、Michael Paquier)
修复当
min_dynamic_shared_memory
设置为高于零时,在 Windows 上发生的 “could not duplicate handle” 错误(Thomas Munro)修复
GenericXLogFinish
中的操作顺序(Jeff Davis)此代码违反了崩溃安全所需条件,即在将已更改的缓冲区标记为脏之前写入 WAL。没有核心代码使用此函数,但扩展使用(例如,
contrib/bloom
使用)。删除 PL/Python 异常处理中的不正确断言(Alexander Lakhin)
修复 pg_dump 以转储订阅的新
run_as_owner
选项(Philip Warner)由于此疏忽,订阅将始终使用设置为
false
的run_as_owner
恢复,这与 v16 之前的版本中的行为不同。修复 pg_restore,以便选择性恢复将包括所选表的表级别和列级别的 ACL(Euler Taveira、Tom Lane)
以前,如果同时存在这两种类型,则只会恢复表级别的 ACL。
向 pg_upgrade 添加逻辑,以检查是否使用了
abstime
、reltime
和tinterval
数据类型(Álvaro Herrera)这些过时的数据类型已在 PostgreSQL 版本 12 中删除,因此在声明可以升级之前,请检查它们是否不存在于较旧的数据库中。
避免在 Windows 上的 pgbench 中出现错误的 “客户端连接过多” 错误(Noah Misch)
修复 vacuumdb 对多个
-N
开关的处理(Nathan Bossart、Kuwamura Masaki)多个
-N
开关应排除多个架构中的表,但实际上由于生成查询的构造错误,没有排除任何内容。修复 vacuumdb,使其在仅分析模式下遵守其
--buffer-usage-limit
选项(Ryoga Yoshida、David Rowley)在
contrib/amcheck
中,不要将中断的页面删除报告为损坏(Noah Misch)此修复程序可防止错误地报告 “最左目标页面的第一个子页面不是其级别的最左页面”、“块 NNNN 不是最左页面” 或 “索引 XXXX 中的左链接/右链接对不一致”。如果 amcheck 在未完成的 btree 索引页面删除后和
VACUUM
清理之前运行,则会出现这些错误。修复
contrib/btree_gin
索引在interval
列上的故障,当执行使用<
或<=
运算符的索引扫描时(Dean Rasheed)此类索引扫描未能返回所有应返回的条目。
添加对 LLVM 16 和 17 的支持(Thomas Munro、Dmitry Dolgov)
在最近的 macOS 上禁止各种构建时警告(Tom Lane)
Xcode 15(随 macOS Sonoma 发布)以一种导致在构建 PostgreSQL 时出现许多重复库警告的方式更改了链接器的行为。这些警告是无害的,但它们很烦人,因此避免两次引用相同的库。此外,不再使用
-multiply_defined suppress
链接器开关,该开关显然长期以来一直是无操作的,现在已受到主动抱怨。在构建
contrib/unaccent
的规则文件时,如果未给出--with-python
且未设置变量PYTHON
,则回退到使用python
(Japin Li)从默认时区缩写列表中移除
PHOT
(菲尼克斯群岛时间)(Tom Lane)此缩写出现在默认列表中,可能会导致最近的 Debian 和 Ubuntu 版本出现故障,因为它们不再默认安装基础 tzdb 条目。由于这是一个虚构的缩写,代表一个总人口约为二十几人的时区,因此似乎不太可能有人会错过它。如果有人确实需要,他们可以通过自定义缩写文件将其放回去。