发布说明

PostgreSQL 15.3

E.15. 发布版本 15.3 #

发布日期:. 2023-05-11

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

E.15.1. 迁移到版本 15.3 #

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

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

E.15.2. 变更 #

  • 防止 CREATE SCHEMA 绕过 search_path 的变更(Alexander Lakhin) § §

    CREATE SCHEMA 命令内部,即使被调用的函数或脚本尝试设置安全的 search_path,当前 search_path 中的对象以及新创建模式中的对象仍然可见。 这可能允许任何有权创建模式的用户劫持安全定义者函数或扩展脚本的权限。

    PostgreSQL 项目感谢 Alexander Lakhin 报告此问题。 (CVE-2023-2454)

  • 修复在内联集合返回函数后正确执行行级安全策略的问题(Stephen Frost,Tom Lane) §

    如果集合返回的 SQL 语言函数引用了具有行级安全策略的表,并且可以被内联到调用查询中, 那么在某些涉及以不同角色重用缓存计划的情况下,这些 RLS 策略不会被正确执行。 这可能允许用户查看或修改本应不可见的行。

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

  • 修复使用 STRATEGY WAL_LOG 选项执行 CREATE DATABASE 后模板(源)数据库可能损坏的问题 (Nathan Bossart,Ryo Matsumura) §

    不正确的缓冲区处理带来了风险:之后对模板的 pg_class 目录的任何修改都可能丢失。

  • 修复使用 STRATEGY WAL_LOG 选项执行 CREATE DATABASE 时的内存泄漏和不必要的磁盘读取 (Andres Freund) §

  • 避免在 CREATE SCHEMA 中省略新模式名称时崩溃(Michael Paquier) §

    SQL 标准允许编写 CREATE SCHEMA AUTHORIZATION owner_name,其中模式名称默认为 owner_name。然而某些代码路径期望模式名称存在,因此会失败。

  • 修复 MERGE 命令的各种规划器故障(Tom Lane) § §

    规划可能会失败,并报告诸如 variable not found in subplan target listPlaceHolderVar found where not expected 之类的错误。

  • 修复 MERGE 在某些边界情况下报告的行数(Dean Rasheed) § §

    命令标签中报告的行数计入了实际上由于 BEFORE ROW 触发器返回 NULL 而未被修改的行。这与普通 UPDATEDELETE 中的行为不一致,因此将其改为不计算此类行。此外,避免在 MERGE 将行移到分区表的不同分区时重复计数。

  • 修复 MERGE 在并发更新时的问题 (Dean Rasheed,Álvaro Herrera) § §

    如果 MERGE 要更新或删除的行刚刚被并发事务更新,某些情况下会出现异常行为。 这可能导致崩溃、执行了错误的合并操作,或者完全不执行任何操作。

  • 增加对 MERGE 命令反编译的支持(Álvaro Herrera) §

    这在添加 MERGE 时被遗漏了,但它是在新式 SQL 函数中支持 MERGE 所必需的。

  • 修复分区表中外键触发器的启用/禁用问题(Tom Lane) §

    ALTER TABLE ... ENABLE/DISABLE TRIGGER 在应用于分区表的外键约束触发器时会失败, 因为它试图按名称定位分区的克隆触发器,而它们的名称并不相同。改为按父触发器 OID 定位。

  • 禁止修改存储在索引中的复合类型(Tom Lane) §

    ALTER TYPE 不允许对存储在任何表列中的复合类型进行非二进制兼容的修改。 (也许将来某天会允许,但目前还没有实现;重写多个表所涉及的锁定问题令人望而却步。) 我们忽略了索引可能包含不在其表中出现的复合类型的可能性。

  • 禁止将系统列作为外键的元素(Tom Lane) §

    自从 OID 被移除作为系统列以来,这样做没有合理的使用场景,并且各种代码不再支持它。 与其试图修复所有情况,不如直接禁止。

  • 确保从启用了 RLS 的父表执行 COPY TO 时不会复制子表中的任何行 (Antonin Houska) §

    文档明确指出 COPY TO 仅从指定的表复制行, 而不包括它可能拥有的任何继承子表。然而,如果该表启用了行级安全,这一点就不再成立。

  • 避免在向 array_position()array_positions() 传递空数组时可能发生的崩溃(Tom Lane) §

  • 修复 to_char() 中可能的越界读取(Tom Lane) §

    在运气不好的情况下,这可能导致服务器崩溃。

  • 避免 translate() 函数中的缓冲区越界读取(Daniil Anisimov) §

    使用删除功能时,该函数可能会读取输入字符串之后的字节,造成轻微的崩溃风险。

  • 调整全文搜索相关的字符分类逻辑,以正确检测当前区域设置是否为 C(Jeff Davis) §

    当数据库的默认排序规则使用 ICU 时,此代码会出现混乱。

  • 避免在 interval 类型输入为空时可能发生的崩溃(Tom Lane) §

  • 重新允许 ISO-8601 时间间隔字段中的指数表示法(Tom Lane) §

    P0.1e10D 这样的时间间隔输入并未被 ISO-8601 正式认可, 但在版本 15 之前我们长期接受它,因此重新允许它。

  • 修复 JSON 字符串字面量中解析错误的错误光标设置(Tom Lane) §

    在 JSON 值中的字符串字面量内检测到语法错误的大多数情况下, 错误光标未能正确设置。这至少会导致无用的错误消息(指向字符串之前的标记, 而非实际的问题位置),在 v14 及更高版本中甚至可能导致崩溃。

  • 修复 vacuum_defer_cleanup_age 大于当前 64 位 xid 时导致的数据损坏(Andres Freund) §

    在 v14 及更高版本中,使用非默认的 vacuum_defer_cleanup_age 设置时,可能计算出一个非常大的清理范围 xid,导致 vacuum 删除仍然存活的行。 v12 和 v13 存在同一问题的较轻形式,仅影响 GiST 索引,可能导致索引页被过早回收。

  • 修复解析器未能检测到某些不当嵌套聚合的情况(Tom Lane) §

    这一疏忽可能导致本应被拒绝为无效的查询在执行器中失败。

  • 修复解析序列 SEQUENCE NAME 选项时的数据结构损坏(David Rowley) §

    如果事件触发器捕获了损坏的解析树,这可能会导致问题。

  • 在将 initplan 从一个节点移至另一个节点时,正确更新计划节点的并行安全性标记(Tom Lane) §

    这一规划器疏忽可能导致运行时出现 subplan was not initialized 错误。

  • 避免在扩展统计代码中使用 PlaceHolderVar 时的失败(Tom Lane) §

    使用依赖类型的扩展统计可能会因 PlaceHolderVar found where not expected 而失败。

  • 修复对应用于子查询的 qual 子句能否在子查询内转换为窗口聚合 运行条件的不正确测试(David Rowley) §

    此类子句中的 SubPlan 会导致断言失败或不正确的结果,其他一些不常见的情况也会如此。

  • 当窗口聚合调用包含子 SELECT 时,禁用逆转换优化(David Rowley) §

    此优化要求聚合的参数表达式具有可重复的结果,而子 SELECT 可能不满足这一条件。

  • 修复嵌套 ARRAY[] 构造执行中的疏忽(Alexander Lakhin,Tom Lane) §

    正确检测结果数组所需总空间的溢出,避免因输出分配过小而可能导致的崩溃。 同时确保结果数组中任何尾部填充空间被清零;虽然留下垃圾数据在大多数情况下无害, 但可能导致后续出现奇怪的行为。

  • 防止在更新"复合类型之上的域的数组"类型列的字段时崩溃(Dmitry Dolgov) §

  • 修复布尔列分区裁剪逻辑(David Rowley) §

    使用 boolcol IS NOT TRUE 条件进行裁剪时处理不正确, 导致可能不返回 boolcol 为 NULL 的行。此外,不太常见的对 NOT boolcol 进行分区的情况也处理不正确。

  • 修复并行哈希连接中每批次清理时的竞态条件(Thomas Munro,Melanie Plageman) §

    在时机不巧且 parallel_leader_participation = off(非默认值)的情况下,可能发生崩溃。

  • 在 EvalPlanQual 检查后重新计算 GENERATED 列(Tom Lane) §

    READ COMMITTED 隔离模式下,行更新的效果可能需要重新应用于 比查询最初找到的更新版本的行。如果是这样,我们需要重新计算所有 GENERATED 列,因为它们可能依赖于被并发更新改变的列。

  • 修复 Memoize 计划执行中的内存泄漏(David Rowley) §

  • 修复对包含在分区树中的外部表使用批量插入时的缓冲区引用计数泄漏(Alexander Pyhalov) §

  • 恢复对亚毫秒级 vacuum_cost_delay 设置的支持(Thomas Munro) §

  • 当表具有为零的逐关系 vacuum_cost_delay 设置时, 不要平衡 vacuum 代价延迟(Masahiko Sawada) §

    当 autovacuum 处理具有逐关系 vacuum_cost_delay 设置的表时,延迟平衡应该被禁用,但这仅对正值有效,对零值无效。

  • 修复在视图末尾添加列后的边界情况崩溃(Tom Lane) §

  • 修复分区更新中 MULTIEXPR_SUBLINK 子计划的罕见失败(Andres Freund,Tom Lane) §

    在分区目标表上使用 INSERT ... ON CONFLICT DO UPDATE SET (c1, ...) = (SELECT ...) 语法时,如果任何子表与父表不同 (例如,物理列顺序不同),可能导致失败。 这通常表现为执行器中的一致性检查失败;但也可能发生崩溃或不正确的数据更新。

  • 修复在具有 DO ALSO INSERT ... SELECT 规则的视图上执行多行 INSERT ... VALUES 查询时对 DEFAULT 标记的处理(Dean Rasheed) §

    这类情况通常会因 unrecognized node type 错误或断言失败而失败。

  • 支持在规则操作的子查询中引用 OLDNEW (Dean Rasheed,Tom Lane) §

    这些引用实际上是横向引用,但如果子查询没有显式标记为 LATERAL,服务器可能会崩溃。在必要时改为隐式添加该标记。

  • 在反编译包含 WITH 中的 INSERT/UPDATE/DELETE 的规则或 SQL 函数体时,注意为目标表打印正确的别名(Tom Lane) §

  • 修复 SERIALIZABLE READ ONLY 优化中的缺陷(Thomas Munro) § §

    已标记为 doomed 的事务会干扰 SERIALIZABLE READ ONLY 事务的安全快照优化。在某些情况下该优化被不必要地跳过。 在其他情况下会发生断言失败(但在非断言构建中没有问题)。

  • 避免在 pgoutput 逻辑解码插件中泄漏缓存回调槽(Shi Yu) §

    在单个会话中多次启动和关闭该插件最终会导致 out of relcache_callback_list slots 错误。

  • 避免对索引操作符类选项的自定义验证器进行不必要的调用(Alexander Korotkov) §

    此更改修复了某些情况下抛出意外错误的问题。

  • 避免在扫描具有多个扫描键的多列 BRIN 索引时做无用功(Tomas Vondra) §

    现有代码在判断某个范围是否匹配时实际上只考虑最后一个扫描键, 因此通常扫描了比所需更多的索引内容。

  • 修复 BRIN inet_minmax_multi_ops 操作符类中的网络掩码处理(Tomas Vondra) §

    此错误在启用断言的构建中触发断言失败,但在生产构建中基本无害。

  • 修复 GiST 索引缓冲构建期间的悬空指针解引用(Alexander Lakhin) §

    此错误在生产构建中通常是无害的,因为获取的值并不关键;但原则上可能导致服务器崩溃。

  • 在逻辑复制更新或删除操作期间忽略已删除的列和生成列(Onder Kalaci,Shi Yu) § §

    使用 REPLICA IDENTITY FULL 选项的复制在表包含此类列时会失败。

  • 更正提交时间戳 SLRU 缓冲区 I/O 等待事件的名称(Alexander Lakhin) §

    根据文档,此等待事件名为 CommitTsBuffer,但代码中为 CommitTSBuffer。将代码修改为与文档一致,因为这样与相关等待事件的命名更一致。

  • 重新激活等待事件 SLRUFlushSync 的报告(Thomas Munro) §

    此类等待的报告在代码重构时被意外移除。

  • 避免在计算应保留多少 WAL 段时可能发生的下溢(Kyotaro Horiguchi) §

    这可能导致无法准确遵守 wal_keep_size 设置。

  • 在备库模式下禁用启动进度报告的开销(Bharath Rupireddy) §

    在备库模式下,我们实际上不报告恢复进度,但却仍在做跟踪工作。

  • 支持 RSA-PSS 证书与 SCRAM-SHA-256 通道绑定(Jacob Champion,Heikki Linnakangas) §

    此功能需要使用 OpenSSL 1.1.1 或更高版本构建。服务器和 libpq 都受到影响。

  • 避免 Windows 上进程 ID 跟踪的竞态条件(Thomas Munro) § § §

    操作系统可能在 postmaster 观察到子进程已消失之前就回收了该 PID。 这可能导致跟踪到多个具有相同 PID 的子进程,从而引起混乱。

  • 修复 list_copy_head() 在空 List 上的正确工作(David Rowley) §

    目前没有已知的 PostgreSQL 核心代码会触发此情况, 但扩展可能依赖于它的正确工作。

  • SPI_result_code_string() 添加缺失的情况(Dean Rasheed) §

  • 修复 AllocSetRealloc() 中错误的 Valgrind 标记(Karina Litskevich) §

    在不常见的大型(>8kB)palloc 块大小缩小的情况下,启用 Valgrind 的构建会错误标记从块中释放的内存的已定义状态, 可能在 Valgrind 测试期间导致不正确的结果。

  • 修复对启用了行级安全的分区表执行 MERGE 时的断言失败(Dean Rasheed) §

  • 避免在解码事务性逻辑复制消息时的断言失败(Tomas Vondra) §

  • 避免在处理正则表达式转义时的区域设置敏感性(Jeff Davis) §

    反斜杠后跟非 ASCII 字符有时可能导致断言失败,具体取决于当前的区域设置。

  • 避免在 log_newpage_range() 中当指定范围内最后几页为空时尝试写入空 WAL 记录(Matthias van de Meent) §

    目前尚不完全清楚在已发布的分支中是否可以触发此情况, 但如果可以,则可能发生断言失败。

  • 修复 plpgsql DO 块中使用类型转换表达式时的会话级内存泄漏 (Ajit Awekar,Tom Lane) §

  • 在将 Perl 列表结构转换为多维 SQL 数组时,加强数组维度检查(Tom Lane) §

    当子列表的嵌套不一致导致数据不表示矩形值数组时, plperl 可能会出现异常行为。这类情况现在会产生错误, 但以前可能导致崩溃或输出垃圾数据。

  • 在将 Python 列表结构转换为多维 SQL 数组时,加强数组维度检查(Tom Lane) § §

    在处理空子列表或子列表嵌套不一致导致数据不表示矩形值数组时, plpython 可能会出现异常行为。前者应产生空的输出数组, 后者应产生错误。但某些情况下会导致崩溃,其他情况下则产生意外的输出。

  • 修复 plpython 中异常栈的展开(Xing Guo) §

    某些罕见的失败情况可能在未清理 PG_TRY 异常栈的情况下返回, 如果在下一个栈层被展开之前引发另一个错误,则有崩溃风险。

  • 修复 libpqPQconnectPoll() 中不一致的 GSS 加密错误处理 (Michael Paquier) §

    gssencmode 设置为 require 时, GSS 初始化失败后连接未被标记为已死。使其像 TLS 加密的等效情况一样立即失败。

  • 修复使用 -C ORACLE 选项构建的 ecpg 程序中可能的数据损坏 (Kyotaro Horiguchi) §

    ecpg_get_data()varcharsize 设置为零时被调用,它可能会将终止零字符写入前一个字段的最后一个字节, 截断该字段中的数据。

  • 修复 pg_dump,使在枚举类型列上哈希分区的分区表能够成功恢复 (Tom Lane) §

    由于枚举值的哈希码取决于分配给枚举的 OID,它们在导出和恢复后通常不同, 这意味着行经常需要进入与原来不同的分区。用户可以通过指定 --load-via-partition-root 选项来解决此问题;但由于不使用该选项成功的可能性很小, 因此让 pg_dump 对这类表自动应用该选项。

    此外,修复 pg_restore 在使用 --load-via-partition-root 模式时不再尝试在恢复前 TRUNCATE 目标表。这避免了死锁和数据丢失的风险。

  • 在 Windows 上正确检测不可定位的文件 (Juan José Santamaría Flecha,Michael Paquier,Daniel Watzinger) § §

    此错误导致 pg_dump 写入管道或 pg_restore 从管道读取时出现异常行为。

  • pgbenchprepared 模式下,在启动管道之前准备管道中的所有命令(Álvaro Herrera) §

    这避免了 pgbench 脚本尝试在管道内启动可序列化事务时的失败。

  • contrib/amcheck 的堆检查代码中,正确处理 xmin 或 xmax 为零的元组 (Robert Haas) § §

  • contrib/amcheck 中,合理处理看起来在纪元零之前的 xid (Andres Freund) §

    在损坏的情况下,我们可能会看到一个回卷的 32 位 xid,它看起来在第一个 xid 纪元之前。 将这样的值提升为 64 位形式会产生一个远在未来的值,导致错误的报告。 在这种情况下返回 FirstNormalFullTransactionId,以便事情能合理地工作。

  • contrib/basebackup_to_shell 中,正确检测打开管道失败 (Robert Haas) §

  • contrib/hstore_plpython 中,避免在要转换的 Python 值不是映射时崩溃 (Dmitry Dolgov,Tom Lane) §

    这应该报错,但 Python 3 更改了一些 API 的方式导致检查出现异常,从而允许崩溃发生。

  • 要求 ltree 列上 GiST 索引的 siglen 选项(如果指定)为 4 的倍数 (Alexander Korotkov) §

    其他值会导致对索引内容的未对齐访问,这在 Intel 兼容硬件上无害, 但在其他一些架构上可能导致崩溃。

  • contrib/pageinspect 中,为 gist_page_items() 函数添加对不正确输入的防护(Dmitry Koval) §

  • 修复 contrib/pg_trgm 在无法满足的正则表达式上的异常行为(Tom Lane) §

    $foo 这样的正则表达式是合法的但无法满足; 正则表达式编译器识别出这一点并生成空的 NFA 图。 尝试将这样的图优化为 pg_trgm GIN 或 GiST 索引条件时会导致访问工作数组末尾之后的内容, 可能导致崩溃。

  • 修复 contrib/postgres_fdwapplication_name 参数中转义序列的处理 (Kyotaro Horiguchi,Michael Paquier) §

    扩展这些转义序列的代码在后台进程中执行时可能会失败, 例如在自动分析外部表时。

  • contrib/pg_walinspect 中,限制 pg_get_wal_records_info() 的内存使用(Bharath Rupireddy) §

  • 在使用 GNU 兼容的 strip 剥离静态库时使用 --strip-unneeded 选项(Tom Lane) §

    此前,make install-strip 在这种情况下使用 -x 选项。此更改避免了 llvm-strip 的异常行为,并且生成的输出也略小。

  • 停止推荐自动下载 DTD 文件来构建文档,并且实际上禁用它 (Aleksander Alekseev,Peter Eisentraut,Tom Lane) §

    如果没有在本地安装 DocBook DTD 文件,似乎已经无法构建 SGML 文档。 此前 xsltproc 可以从 sourceforge.net 即时下载这些文件; 但 sourceforge.net 现在仅允许 HTTPS 访问,而没有常见版本的 xsltproc 支持该协议。因此,删除我们文档中建议这是可行或有用的内容, 并在构建方案中添加 xsltproc--nonet 选项。

  • 在 PGXS 构建中运行 TAP 测试时,为临时 portlock 目录使用更合理的位置(Peter Eisentraut) §

    将其放在构建目录下的 tmp_check 中。使用之前的代码, PGXS 构建会尝试将其放在安装目录中,而该目录不一定是可写的。

  • 将时区数据文件更新到 tzdata 2023c 版本, 包含埃及、格陵兰、摩洛哥和巴勒斯坦的夏令时法规变更。(Tom Lane) §

    在使用莫斯科时间时,Europe/Kirov 和 Europe/Volgograd 现在使用缩写 MSK/MSD 而不是数字缩写,以与其他使用莫斯科时间的时区保持一致。 此外,America/Yellowknife 不再与 America/Edmonton 不同; 这影响该地区一些 1948 年之前的时间戳。