受支持版本:当前 (17)

E.1. 版本 17.1 #

发布日期: 2024-11-14

此版本包含从 17.0 版本的一系列修复。有关主要版本 17 中的新功能的信息,请参阅 章节 E.2

E.1.1. 迁移到版本 17.1 #

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

但是,如果您曾经从拥有到其他分区表的外键引用的分区表中分离了一个分区,并且没有删除前一个分区,那么您可能需要修复已损坏的目录和/或数据,如下面第五个变更日志条目中所述。

同样,在不常见的案例中,如果数据库的 LC_CTYPE 设置是 C,而其 LC_COLLATE 设置是其他区域设置,则应重新建立文本列的索引,如下面第六个变更日志条目中所述。

E.1.2. 更改 #

  • 当 RLS 适用于非顶级表引用时,确保缓存计划被标记为依赖于调用角色(内森·博萨特)§

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

    感谢PostgreSQL项目感谢沃尔夫冈·瓦瑟报告此问题。(CVE-2024-10976)

  • 使 libpq 丢弃在 SSL 或 GSS 协议协商过程中收到的错误消息(雅各布·冠军)§

    在加密协商完成之前收到的错误消息可能并非真实的服务器输出,而是由中间人注入的。报告此消息会带来各种安全隐患;例如,消息可能会欺骗查询结果,导致粗心的用户将其误认为正确的输出。最好的答案似乎是丢弃此类数据,仅依靠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));
    

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

  • LC_COLLATE 不同于 LC_CTYPE 时,修复 C 区域设置的测试(Jeff Davis) §

    当使用 libc 作为默认校对提供程序时,检查 C 区域设置是否用于校对的测试错误地检查了 LC_CTYPE,而不是 LC_COLLATE。这在这些设置相同时,或两者都不是 C(或其别名 POSIX)时,没有影响。但是,如果 LC_CTYPECLC_COLLATE 是其他区域设置,则可能导致查询答案错误,并且字符串的索引可能会损坏。使用此类设置的数据库的用户应在安装此更新后对受影响的索引重新编制索引。当 LC_COLLATECLC_CTYPE 为其他区域设置时,相反的情况会导致性能下降,但不会出现实际错误。

  • 如果查询中主键列的校对与分区键的校对不匹配,请不要使用分区联接或分组(Jian He,Webbo Han) § §

    此类计划可能会产生不正确的结果。

  • 在将 NOT NULL 列上的 IS NULL 测试转换为常量 FALSE 后,避免计划程序失败(Richard Guo) §

    此错误通常会导致错误,例如 子计划目标列表中找不到变量

  • 避免在内联 SQL 函数(其参数包含某些与数组相关的构造)时发生可能的计划程序崩溃(Tom Lane、Nathan Bossart) §

  • 修复可能出现错误答案或 错误的 varnullingrels 的计划程序错误,用于 MERGE ... WHEN NOT MATCHED BY SOURCE 操作(Dean Rasheed) § §

  • 修复可能的 找不到要排序的 pathkey 项目 错误,当 UNION ALL 成员查询的输出需要排序,且排序列是表达式时(Andrei Lepikhov、Tom Lane) §

  • 修复 B 树 ScalarArrayOp 索引扫描中的边缘案例(Peter Geoghegan) §

    当此类的计划可滚动的游标备份到其启动点并再次运行向前时,可能会出现错误的答案。

  • 解决 COPY (查询) TO ... 时出现的断言失败或产生误导的错误消息,当 查询DO INSTEAD NOTIFY 规则(Tender Wang、Tom Lane)重写时 §

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

    一些不正确的用法现在将被正确地拒绝。

  • 修复服务器崩溃问题,当 json_objectagg() 调用包含不稳定函数时(Amit Langote) §

  • 修复并行哈希联接期间偏斜数据的检测(Thomas Munro) §

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

  • 避免在使用 ALTER DATABASE SET 来设置需要基于搜索路径的查找的服务器参数(例如 default_text_search_config)时出现崩溃(Jeff Davis) §

  • 避免在对分区表创建新索引时重复查找操作类和排序规则(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) §

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

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

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

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

    在该代码路径中,跟踪尚未重建的索引的列表没有得到适当更新,从而在下文中存在断言失败或崩溃风险。

  • 修复可能导致“就地”编录更新丢失的问题 (诺亚·米施) § § § § § § §

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

  • 在恢复结束时重置编录缓存 (诺亚·米施) §

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

  • 避免在保留中断时使用并行查询 (弗朗西斯科·德格拉西、诺亚·米施、汤姆·莱恩) § §

    此情况通常不会出现,但可以通过测试场景达到此目的,例如使用 SQL 语言函数作为 B 树支持(这对于实际使用来说过于缓慢)。如果确实发生了此情况,将会导致无限期等待。

  • 忽略 pg_cursors 视图中尚未定义的门户 (汤姆·莱恩) §

    在设置新游标时可能会调用检查此视图的用户定义代码,如果是这种情况,则会导致空指针取消引用。通过定义视图以排除设置不完全的游标来避免这个问题。

  • 避免在解码涉及插入列默认值的交易时出现“在逻辑解码期间出现“意外的表索引获取元组调用”错误 (竹芝出莉、侯志杰) § §

  • 减少逻辑解码的内存消耗 (正彦泽田) §

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

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

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

  • 以与其他整数值选项相同的方式解析 libpqkeepalives 连接选项(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_basebackuppg_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)的平台上,该编码会在 Y2038 后失败。大多数故障仅仅是表面上的,但特别要注意,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 的别名,而不再是单独的区域,主要是因为发现这些区域之间的差异是基于不可信数据。

提交修正

如果您在文档中看到任何内容不正确、与您使用具体功能的体验不符,或者需要进一步说明,请使用此表格報告文档问题。