受支持版本: 17

E.10. 17.1 发布 #

发布日期:. 2024-11-14

本次发布包含自 17.0 以来的多项修复。 有关 17 主版本中新特性的更多信息,请参见 Section E.11

E.10.1. 迁移到版本 17.1 #

对于运行 17.X 的用户,无需执行转储/恢复。

不过,如果你曾经从一个引用另一分区表的分区表中分离过某个分区,并且之后没有删除该分区,那么你可能需要修复系统目录和/或数据损坏,详见下文第五条变更记录。

此外,在一种不常见的情况下,如果某个数据库的 LC_CTYPE 设置为 C,而 LC_COLLATE 设置为其他 locale,则文本列上的索引应按下文第六条变更记录所述重新建立索引。

E.10.2. 变更 #

  • 确保当 RLS 应用于非顶级表引用时,缓存的执行计划被标记为依赖于调用角色 (Nathan Bossart) §

    如果查询中的 CTE、子查询、子链接、安全调用者视图或强制类型转换投影 引用了具有行级安全策略的表,我们忽略了将结果执行计划标记为可能依赖于 执行它的角色。这可能导致同一会话中后续的查询执行使用错误的执行计划, 然后返回或隐藏本应被隐藏或返回的行。

    PostgreSQL 项目感谢 Wolfgang Walther 报告此问题。 (CVE-2024-10976)

  • 使 libpq 丢弃在 SSL 或 GSS 协议协商期间收到的错误消息 (Jacob Champion) §

    在加密协商完成之前收到的错误消息可能是由中间人注入的, 而不是真正的服务器输出。报告该消息会带来各种安全隐患; 例如,该消息可能伪造查询结果,粗心的用户可能会误以为是正确的输出。 最好的方案似乎是丢弃这类数据,仅依赖 libpq 自身对连接失败的报告。

    PostgreSQL 项目感谢 Jacob Champion 报告此问题。 (CVE-2024-10977)

  • 修复 SET SESSION AUTHORIZATIONSET 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)) +
        CASE WHEN pg_catalog.pg_partition_root(conrelid) = confrelid THEN
                  (SELECT count(*) FROM pg_catalog.pg_partition_tree(confrelid)
                    WHERE level = 1)
             ELSE 0 END);
    

    由于一个或多个 ADD CONSTRAINT 步骤可能会失败,应将查询输出保存到文件中, 然后尝试执行每个步骤。

  • 修复当 LC_COLLATELC_CTYPE 不同时,对 C locale 的测试(Jeff Davis) §

    当使用 libc 作为默认排序规则提供者时,用于测试排序是否使用了 C locale 的代码,误查了 LC_CTYPE 而不是 LC_COLLATE。在这两个设置相同的典型情况下,这不会造成影响;如果两者都不是 C(也不是其别名 POSIX),同样无影响。不过,如果 LC_CTYPEC,而 LC_COLLATE 是其他 locale,就可能产生错误的查询结果,也可能导致字符串索引损坏。使用这类设置的数据库用户应在安装本次更新后对受影响的索引重新建立索引。反过来,如果 LC_COLLATECLC_CTYPE 是其他 locale,则会导致性能下降,但不会产生实际错误。

  • 当查询中键列的排序规则与分区键的排序规则不匹配时, 不使用分区级连接或分组 (Jian He,Webbo Han) § §

    这样的执行计划可能产生不正确的结果。

  • 避免在将 NOT NULL 列上的 IS NULL 测试转换为常量 FALSE 后发生规划器失败(Richard Guo) §

    这个 bug 通常会导致诸如 variable not found in subplan target lists 之类的错误。

  • 避免在内联某个参数包含特定数组相关结构的 SQL 函数时,规划器可能崩溃(Tom Lane、Nathan Bossart) §

  • 修复 MERGE ... WHEN NOT MATCHED BY SOURCE 动作可能产生错误结果或 wrong varnullingrels 规划器错误的问题(Dean Rasheed) § §

  • 修复当 UNION ALL 成员查询的输出需要排序, 且排序列为表达式时,可能出现的 could not find pathkey item to sort 错误 (Andrei Lepikhov,Tom Lane) §

  • 修复 B-tree ScalarArrayOp 索引扫描中的边界情形问题(Peter Geoghegan) §

    当带有这类计划的可滚动游标回退到起点后再向前执行时,可能出现错误结果。

  • 修复 COPY (query) TO ... 中的断言失败或令人困惑的错误消息, 当 queryDO INSTEAD NOTIFY 规则重写时(Tender Wang,Tom Lane) §

  • 修复对 COPYFORCE_NOT_NULLFORCE_NULL 选项的校验(Joel Jacobson) §

    某些不正确的用法现在会像预期那样被拒绝。

  • 修复当 json_objectagg() 调用包含 volatile 函数时的服务器崩溃 (Amit Langote) §

  • 修复并行哈希连接中倾斜数据的检测(Thomas Munro) §

    在对哈希连接的内侧进行重新分区(因为某个分区累积了过多元组)之后, 我们会检查该分区的所有元组是否都进入了同一个子分区, 这表明它们都具有相同的哈希值,进一步重新分区无法改善情况。 此检查在某些情况下出现故障,允许重复进行无效的重新分区, 最终导致资源耗尽错误。

  • 避免在使用 ALTER DATABASE SET 设置需要基于 search_path 查找的服务器参数时崩溃,例如 default_text_search_config(Jeff Davis) §

  • 避免在分区表上创建新索引时重复查找 opclass 和 collation(Tom Lane) §

    之所以成问题,主要是因为其中一些查找会在受限的 search_path 下进行,从而导致当 CREATE INDEX 命令引用 pg_catalog 之外的对象时出现意外失败。

    此修复还阻止了父分区索引上的注释被复制到子索引。

  • 为分区表补上到 CREATE TABLE ... USING 中指定的非内置访问方法的缺失依赖(Michael Paquier) §

    当存在依赖于某访问方法的表时,删除该访问方法本应被阻止,但此前并未如此,因而允许后续出现异常行为。注意,此修复只会防止本次更新之后新建的分区表出现这类问题。

  • 禁止包含非 ASCII 字符的区域设置名称(Thomas Munro) §

    这仅在 Windows 上是一个问题,因为其他平台不使用此类区域设置名称。 它们存在问题是因为完全不清楚此类名称用什么编码表示 (因为区域设置本身定义了要使用的编码)。在最近的 PostgreSQL 版本中,由于对此的混淆, 可能会在 Windows 运行时库中发生中止。

    遇到新错误消息的用户应该使用 Windows Locale Builder 创建一个具有纯 ASCII 名称的 重复区域设置,或者考虑使用符合 BCP 47 的区域设置名称, 如 tr-TR

  • 修复提交可串行化事务时的竞态条件(Heikki Linnakangas) §

    对最近提交的事务的错误处理可能导致断言失败或 could not access status of transaction 错误。

  • 修复 COMMIT PREPARED 中导致产生孤立 2PC 文件的竞态条件 (wuchengwen) §

    并发的 PREPARE TRANSACTION 可能导致 COMMIT PREPARED 不删除已完成事务的磁盘上两阶段状态文件。 虽然没有立即的不良影响,但随后的崩溃恢复可能因 could not access status of transaction 而失败, 需要手动删除孤立文件才能恢复服务。

  • 避免在 VACUUM FULL 期间跳过无效 toast 索引后 发生无效内存访问(Tender Wang) §

    在此代码路径中,跟踪尚待重建索引的列表未被正确更新, 可能导致后续的断言失败或崩溃。

  • 修复就地目录更新可能丢失的问题(Noah Misch) § § § § § § §

    普通行更新会写入行的新版本以保留事务的回滚能力。 然而,某些系统目录更新是有意设计为非事务性的,并通过对行的就地更新来完成。 这些补丁修复了可能导致就地更新效果丢失的竞态条件。 例如,可能会忘记已将 pg_class.relhasindex 设置为 true,从而阻止新索引的更新,进而导致索引损坏。

  • 在恢复结束时重置系统目录缓存(Noah Misch) §

    这可以防止因使用系统目录缓存中的陈旧数据,而导致原地系统目录更新丢失的情况。

  • 避免在持有中断抑制时使用并行查询 (Francesco Degrassi,Noah Misch,Tom Lane) § §

    这种情况在正常情况下不会发生,但可以通过测试场景达到, 例如使用 SQL 语言函数作为 B-tree 支持函数(这对于生产使用来说太慢了)。 如果确实发生,将导致无限期等待。

  • pg_cursors 视图中忽略尚未定义的 Portal (Tom Lane) §

    用户定义的检查该视图的代码可能在新游标正在设置时被调用, 如果发生这种情况,将导致空指针解引用。通过将该视图定义为排除 未完全设置的游标来避免此问题。

  • 避免在解码涉及插入列默认值的事务时出现 unexpected table_index_fetch_tuple call during logical decoding 错误(Takeshi Ideriha,Hou Zhijie) § §

  • 减少逻辑解码的内存消耗(Masahiko Sawada) §

    使用较小的默认块大小来存储逻辑复制期间接收的元组数据。 这减少了内存浪费,据报告在处理长时间运行的事务时内存浪费会很严重, 甚至导致内存不足错误。

  • 修复当 CALL 位于 PL/pgSQL 的 EXCEPTION 块中时,从 CALL 语句参数列表中调用的稳定函数的行为(Tom Lane) §

    与我们之前季度发布中的类似修复一样,这种情况允许此类函数被传递错误的快照, 导致它们看到自外部事务开始以来修改的行的过时值。

  • 以与其他整数值选项相同的方式解析 libpqkeepalives 连接选项(Yuto Sasaki) §

    此处使用的代码拒绝选项值中的尾部空白,与其他情况不同。 这在 ecpg 的使用中被证明是有问题的。

  • 修复 ecpglib 中解析不正确日期时间输入时的越界读取 (Bruce Momjian,Pavel Nekrasov) §

    有可能试图读取常量数组起始位置之前的位置。 不过实际影响似乎很小。

  • 修复 psql 的 describe 命令,使其重新能够与 9.4 之前的服务器协同工作(Tom Lane) §

    由于使用了这些旧版本中不存在的函数,涉及显示 ACL(权限)列的命令在非常旧的 PostgreSQL 服务器上会失败。

  • 避免在 psql\watch 命令中指定小于 1ms 的间隔时挂起 (Andrey Borodin,Michael Paquier) §

    改为将其视为零间隔(执行之间不等待)。

  • 修复无法在 ~/.pgpass 中找到复制密码的问题(Tom Lane) §

    如果未提供 -d--dbname 开关,pg_basebackuppg_receivewal 就无法匹配 ~/.pgpass 中数据库名字段为 replication 的条目,从而导致意外弹出密码提示。

  • 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 的别名而非独立区域, 主要是因为这些区域之间的差异被发现是基于不可靠的数据。

提交更正

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