发布日期: 2024-11-14
此版本包含 17.0 的各种修复。有关 17 主要版本的新功能的信息,请参阅第 E.3 节。
对于运行 17.X 的用户,不需要进行转储/恢复。
但是,如果您曾经从外键引用另一个分区表的分区表中分离出一个分区,并且没有删除前一个分区,那么您可能需要修复目录和/或数据损坏,如下面第五个变更日志条目中所详述。
此外,在数据库的 LC_CTYPE
设置为 C
而其 LC_COLLATE
设置为其他语言环境的不常见情况下,文本列上的索引应重新建立索引,如下面第六个变更日志条目中所述。
当 RLS 应用于非顶层表引用时,确保缓存计划标记为依赖于调用角色 (Nathan Bossart) §
如果查询中的 CTE、子查询、子链接、安全调用者视图或强制投影引用了具有行级安全策略的表,我们忽略了将生成的计划标记为可能依赖于执行它的角色。这可能导致同一会话中的后续查询执行使用错误的计划,然后返回或隐藏本应隐藏或返回的行。
PostgreSQL 项目感谢 Wolfgang Walther 报告此问题。(CVE-2024-10976)
使 libpq 丢弃在 SSL 或 GSS 协议协商期间收到的错误消息 (Jacob Champion) §
在加密协商完成之前收到的错误消息可能由中间人注入,而不是真正的服务器输出。报告它会打开各种安全隐患的大门;例如,该消息可能会欺骗一个不小心将查询结果误认为正确输出的用户。最好的答案似乎是丢弃此类数据,而只依赖 libpq 自身对连接失败的报告。
PostgreSQL 项目感谢 Jacob Champion 报告此问题。(CVE-2024-10977)
修复 SET SESSION AUTHORIZATION
和 SET ROLE
之间意外的交互 (Tom Lane) § §
SQL 标准规定 SET SESSION AUTHORIZATION
具有执行 SET ROLE NONE
的副作用。我们对该标准的实现存在缺陷,导致两个设置之间的交互比预期的要多。值得注意的是,回滚已执行 SET SESSION AUTHORIZATION
的事务会将 ROLE
还原为 NONE
,即使这不是之前的状态,因此有效的用户 ID 现在可能与事务之前的不同。在函数 SET
子句中临时设置 session_authorization
具有类似的效果。一个相关的错误是,如果并行工作进程检查 current_setting('role')
,它会看到 none
,即使它应该看到其他内容。
PostgreSQL 项目感谢 Tom Lane 报告此问题。(CVE-2024-10978)
防止受信任的 PL/Perl 代码更改环境变量 (Andrew Dunstan, Noah Misch) § § §
操纵进程环境变量(如 PATH
)的能力会给攻击者提供执行任意代码的机会。因此,““受信任””PL 不得提供执行此操作的能力。为了修复 plperl
,请将 %ENV
替换为拒绝任何修改尝试并发出警告的绑定哈希。不受信任的 plperlu
保留更改环境的能力。
PostgreSQL 项目感谢 Coby Abrams 报告此问题。(CVE-2024-10979)
修复在附加或分离表分区时外键约束的目录状态更新 (Jehan-Guillaume de Rorthais, Tender Wang, Álvaro Herrera) § §
如果被引用表是分区的,那么对于独立的引用表与作为分区的引用表,需要不同的目录条目。ATTACH/DETACH PARTITION
命令未能正确执行此转换。特别是,在 DETACH
之后,现在独立的表将缺少外键强制触发器,这可能导致该表稍后包含不符合外键约束的行。随后的重新 ATTACH
也可能会失败,并出现令人惊讶的错误。
修复此问题的方法是在现在独立的表上对每个错误的约束执行 ALTER TABLE DROP CONSTRAINT
,然后重新添加该约束。如果重新添加约束失败,则表示已渗入一些错误数据。您需要手动重新建立引用表和被引用表之间的一致性,然后重新添加约束。
此查询可用于识别损坏的约束并构建重新创建它们所需的命令
SELECT conrelid::pg_catalog.regclass AS "constrained table", conname AS constraint, confrelid::pg_catalog.regclass AS "references", pg_catalog.format('ALTER TABLE %s DROP CONSTRAINT %I;', conrelid::pg_catalog.regclass, conname) AS "drop", pg_catalog.format('ALTER TABLE %s ADD CONSTRAINT %I %s;', conrelid::pg_catalog.regclass, conname, pg_catalog.pg_get_constraintdef(oid)) AS "add" FROM pg_catalog.pg_constraint c WHERE contype = 'f' AND conparentid = 0 AND (SELECT count(*) FROM pg_catalog.pg_constraint c2 WHERE c2.conparentid = c.oid) <> (SELECT count(*) FROM pg_catalog.pg_inherits i WHERE (i.inhparent = c.conrelid OR i.inhparent = c.confrelid) AND EXISTS (SELECT 1 FROM pg_catalog.pg_partitioned_table WHERE partrelid = i.inhparent));
由于可能有一个或多个 ADD CONSTRAINT
步骤会失败,您应该将查询的输出保存在文件中,然后尝试执行每个步骤。
当 LC_COLLATE
与 LC_CTYPE
不同时,修复对 C
语言环境的测试 (Jeff Davis) §
当使用 libc
作为默认排序规则提供程序时,检查是否为排序规则使用 C
语言环境的测试意外检查了 LC_CTYPE
,而不是 LC_COLLATE
。在这些设置相同或两者都不是 C
(也不是它的别名 POSIX
)的典型情况下,这不会产生任何影响。但是,如果 LC_CTYPE
为 C
,而 LC_COLLATE
为其他语言环境,则可能会出现错误的查询答案,并且可能会损坏字符串上的索引。安装此更新后,具有此类设置的数据库的用户应重新建立受影响索引的索引。 LC_COLLATE
为 C
而 LC_CTYPE
为其他语言环境的情况会导致性能下降,但不会产生实际错误。
如果查询的键列的排序规则与分区键的排序规则不匹配,则不要使用按分区连接或分组 (Jian He, Webbo Han) § §
此类计划可能会产生不正确的结果。
避免在将 NOT NULL
列上的 IS NULL
测试转换为常量 FALSE
后出现规划器失败 (Richard Guo) §
此错误通常会导致诸如““在子计划目标列表中找不到变量””之类的错误。
避免在内联其参数包含某些与数组相关的构造的 SQL 函数时可能发生规划器崩溃 (Tom Lane, Nathan Bossart) §
修复 MERGE ... WHEN NOT MATCHED BY SOURCE
操作可能出现的错误答案或““错误的 varnullingrels””规划器错误 (Dean Rasheed) § §
修复当需要对 UNION ALL
成员查询的输出进行排序,并且排序列是一个表达式时,可能出现的““找不到排序的路径键项””错误 (Andrei Lepikhov, Tom Lane) §
修复 B 树 ScalarArrayOp 索引扫描中的边缘情况 (Peter Geoghegan) §
当将具有此类计划的可滚动游标备份到其起点,然后再向前运行时,可能会出现错误的答案。
修复当 query
被 DO INSTEAD NOTIFY
规则重写时,COPY (
的断言失败或令人困惑的错误消息 (Tender Wang, Tom Lane) §query
) TO ...
修复 COPY
的 FORCE_NOT_NULL
和 FORCE_NULL
选项的验证 (Joel Jacobson) §
现在会拒绝一些不正确的使用方式,这是应该的。
修复当 json_objectagg()
调用包含易失性函数时服务器崩溃的问题 (Amit Langote) §
修复并行哈希连接期间倾斜数据的检测 (Thomas Munro) §
在重新分区哈希连接的内部部分之后,因为一个分区累积了太多的元组,我们会检查是否所有分区的元组都进入了同一个子分区,这表明它们都具有相同的哈希值,并且进一步重新分区无法改善情况。此检查在某些情况下发生故障,允许重复进行徒劳的重新分区,最终导致资源耗尽错误。
避免在 ALTER DATABASE SET
用于设置需要基于搜索路径查找的服务器参数(如 default_text_search_config
)时发生崩溃 (Jeff Davis) §
避免在分区表上创建新索引时重复查找 opclasses 和排序规则 (Tom Lane) §
这主要是因为一些查找会使用受限的 search_path
进行,如果 CREATE INDEX
命令引用的对象位于 pg_catalog
之外,就会导致意外的失败。
此修复还防止将父分区索引上的注释复制到子索引。
添加从分区表到 CREATE TABLE ... USING
中指定的非内置访问方法的缺失依赖(Michael Paquier)§
当存在依赖于访问方法的表时,应该阻止删除该访问方法,但实际上并没有阻止,从而导致后续的异常行为。请注意,此修复仅防止在此更新之后创建的分区表出现问题。
禁止使用包含非 ASCII 字符的区域设置名称 (Thomas Munro) §
这仅在 Windows 上是一个问题,因为其他地方不使用此类区域设置名称。它们之所以有问题,是因为此类名称的编码方式非常不明确(因为区域设置本身定义了要使用的编码)。在最近的 PostgreSQL 版本中,由于对此的混淆,可能会在 Windows 运行时库中发生中止。
任何遇到新错误消息的人都应该使用 Windows 区域设置生成器创建具有仅 ASCII 名称的新重复区域设置,或者考虑使用符合 BCP 47 标准的区域设置名称,例如 tr-TR
。
修复提交可序列化事务中的竞争条件(Heikki Linnakangas)§
错误处理最近提交的事务可能导致断言失败或 “无法访问事务状态” 错误。
修复 COMMIT PREPARED
中导致孤立 2PC 文件的竞争条件 (wuchengwen) §
并发的 PREPARE TRANSACTION
可能导致 COMMIT PREPARED
不删除已完成事务的磁盘两阶段状态文件。虽然没有立即产生不良影响,但随后的崩溃和恢复可能会失败,并显示 “无法访问事务状态”,需要手动删除孤立的文件才能恢复服务。
在 VACUUM FULL
期间跳过无效的 TOAST 索引后,避免无效的内存访问 (Tender Wang) §
在此代码路径中,跟踪尚未重建的索引的列表没有正确更新,可能会在稍后出现断言失败或崩溃。
修复 “就地”目录更新可能丢失的几种方式 (Noah Misch) § § § § § § §
正常的行更新会写入该行的新版本,以保留事务的回滚能力。但是,某些系统目录更新是有意非事务性的,并通过就地更新行来完成。这些补丁修复了可能导致就地更新效果丢失的竞争条件。例如,可能会忘记将 pg_class
.relhasindex
设置为 true,从而阻止更新新索引,进而导致索引损坏。
在恢复结束时重置目录缓存 (Noah Misch) §
这可以防止由于使用目录缓存中的过时数据而导致就地目录更新丢失的情况。
避免在禁用中断时使用并行查询 (Francesco Degrassi, Noah Misch, Tom Lane) § §
这种情况通常不会发生,但在测试场景中可能会出现,例如使用 SQL 语言函数作为 B 树支持(这对于生产使用来说太慢了)。如果真的发生,会导致无限期等待。
忽略 pg_cursors
视图中尚未定义的 Portal (Tom Lane) §
在设置新游标时,可能会调用检查此视图的用户定义代码,如果发生这种情况,将会导致空指针解引用。通过定义视图以排除未完全设置的游标来避免此问题。
避免在解码涉及插入列默认值的事务时出现 “在逻辑解码期间意外调用 table_index_fetch_tuple” 错误 (Takeshi Ideriha, Hou Zhijie) § §
减少逻辑解码的内存消耗 (Masahiko Sawada) §
使用较小的默认块大小来存储逻辑复制期间接收的元组数据。这可以减少内存浪费,据报告,在处理长时间运行的事务时,内存浪费非常严重,甚至会导致内存不足失败。
修复从 CALL
语句的参数列表中调用的稳定函数的行为,当 CALL
位于 PL/pgSQL EXCEPTION
块中时 (Tom Lane) §
与我们之前季度版本中的类似修复一样,这种情况允许将错误的快照传递给此类函数,导致它们看到自外部事务开始以来修改的行的过时值。
以与其他整数值选项相同的方式解析 libpq 的 keepalives
连接选项 (Yuto Sasaki) §
此处使用的编码拒绝选项值中的尾随空格,这与其他情况不同。事实证明,例如,这在 ecpg 的使用中是有问题的。
在 ecpglib 中,修复解析不正确的日期时间输入时发生的越界读取 (Bruce Momjian, Pavel Nekrasov) §
可能会尝试读取常量数组开始之前的地址。但实际后果似乎微乎其微。
修复 psql 的 describe 命令,使其再次与 9.4 之前的服务器一起工作 (Tom Lane) §
由于使用了那些版本中不存在的函数,因此涉及显示 ACL(权限)列的命令在非常旧的 PostgreSQL 服务器上失败。
避免在 psql 的 \watch
命令中指定小于 1 毫秒的时间间隔时挂起 (Andrey Borodin, Michael Paquier) §
相反,将其视为与零时间间隔相同(执行之间没有等待)。
修复在 ~/.pgpass
中找不到复制密码的问题 (Tom Lane) §
如果未提供 -d
或 --dbname
开关,则 pg_basebackup 和 pg_receivewal 无法匹配数据库名称字段中包含 replication
的 ~/.pgpass
中的条目。这导致意外的密码提示。
在 pg_combinebackup 中,如果增量备份文件存在于应包含完整备份的目录中,则抛出错误 (Robert Haas) §
在 pg_combinebackup 中,不要构造包含双斜杠的文件名 (Robert Haas) §
这没有造成功能性问题,但是重复的斜杠在错误消息中可见,这可能会造成混淆。
避免在 vacuumdb 和并行 reindexdb 中尝试重新索引临时表和索引 (VaibhaveS, Michael Paquier, Fujii Masao, Nathan Bossart) § § §
重新索引其他会话的临时表不起作用,但是某些代码路径中缺少跳过它们的检查,从而导致不必要的失败。
修复 ARM64 平台上不正确的 LLVM 生成的代码 (Thomas Munro, Anthonin Bonnefoy) §
在 ARM 平台上使用 JIT 编译时,生成的代码可能不支持超过 32 位的重定位距离,从而允许生成的代码的错误放置导致大型内存系统上的服务器崩溃。
修复了一些假设进程启动时间(表示为 time_t
)将适合 long
值的位置 (Max Johnson, Nathan Bossart) §
在 long
为 32 位的平台上(尤其是 Windows),此代码会在 2038 年之后失败。大多数失败似乎只是表面上的,但值得注意的是,pg_ctl start
会挂起。
将时区数据文件更新到 tzdata 版本 2024b (Tom Lane) § §
此 tzdata 版本将旧的 System-V 兼容区域名称更改为复制相应的地理区域;例如,PST8PDT
现在是 America/Los_Angeles
的别名。主要可见的结果是,对于引入标准化时区之前的时间戳,该区域被认为代表指定位置的当地平均太阳时间。例如,在 PST8PDT
中,timestamptz
输入(例如 1801-01-01 00:00
)之前会被渲染为 1801-01-01 00:00:00-08
,但现在它被渲染为 1801-01-01 00:00:00-07:52:58
。
此外,还有针对墨西哥、蒙古和葡萄牙的历史修正。值得注意的是,Asia/Choibalsan
现在是 Asia/Ulaanbaatar
的别名,而不是一个单独的区域,主要是因为发现这些区域之间的差异是基于不可靠的数据。
如果您在文档中看到任何不正确、与您使用特定功能的体验不符或需要进一步澄清的内容,请使用此表单报告文档问题。