PostgreSQL 每周新闻 - 2021 年 5 月 16 日

由 PWN 发布于 2021-05-17
PWN

PostgreSQL 每周新闻 - 2021 年 5 月 16 日

安全版本 13.3、12.7、11.12、10.17 和 9.6.22 已发布。请尽快升级。9.6 系列将于 2021 年 11 月 11 日停止获得修复。请现在计划主要版本升级。https://postgresql.ac.cn/about/news/postgresql-133-127-1112-1017-and-9622-released-2210/

本周人物:https://postgresql.life/post/laurenz_albe/

5 月份的 PostgreSQL 工作

https://archives.postgresql.org/pgsql-jobs/2021-05/

PostgreSQL 新闻

Planet PostgreSQL:https://planet.postgresql.org/

本周的 PostgreSQL 每周新闻由 David Fetter 为您带来

请在太平洋标准时间(PST8PDT)周日下午 3:00 前将新闻和公告提交至 david@fetter.org。

应用的补丁

Tom Lane 推送了

  • 改进 pg_config_manual.h 中关于 USE_VALGRIND 的注释。这些注释给人一种印象,即 USE_VALGRIND 对于 valgrind 测试来说并非真正必要。但这错了,正如我今天惨痛地了解到的一样。讨论:https://postgr.es/m/512778.1620588546@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/8dc3d68cbe676deb5e74d1b1b565f57fffaf107e

  • 防止数组下标计算中的整数溢出。尽管我们(大部分情况下)小心地确保数组的维度不会大到导致整数溢出,但通常没有检查下限值。这允许出现 lower_bound + dimension 整数溢出的情况。到目前为止,就数组读取而言,这似乎是无害的,只是下标名义上超过 INT_MAX 的数组元素无法访问。然而,它会混淆各种数组赋值逻辑,导致潜在的内存踩踏。通过添加检查来修复此问题,确保数组的下限不会大到导致 lower_bound + dimension 溢出。(注意:这会导致不允许最后一个下标位置恰好为 INT_MAX 的情况。原则上,我们或许可以允许这种情况,但有很多代码会计算 lower_bound + dimension,需要进行调整。允许这样做似乎不值得麻烦/风险。)在某种程度上独立于此,array_set_element() 在检查固定长度数组的下标时,对可能的溢出很粗心,从而创建了另一条导致内存踩踏的途径。也修复了这个问题。安全:CVE-2021-32027 https://git.postgresql.org/pg/commitdiff/f02b9085ad2f6fefd9c5cdf85579cb9f0ff0f0ea

  • 修复 ON CONFLICT ... UPDATE tlists 中对 resjunk 列的错误处理。在 ON CONFLICT ... UPDATE 列表中拥有任何 resjunk 列是不寻常的,但当存在 MULTIEXPR_SUBLINK 子计划时,可能会发生这种情况。如果发生这种情况,ON CONFLICT UPDATE 代码路径最终会存储包含额外 resjunk 列值的元组。从短期来看,这相当无害,但如果向表中添加新列,则这些值将变得可访问,如果它们与新列的数据类型不匹配,则可能导致故障。这通过缺少健全性检查的汇合而逃脱了注意,包括:* 没有交叉检查传递给 heap_insert 或 heap_update 的元组是否与表行类型匹配。虽然很难以合理的成本完全检查它,但我们可以很容易地添加断言,确保没有太多列。* execExprInterp.c 中的输出列赋值情况缺少对输出列号的任何健全性检查,考虑到输入列号上有很多断言检查,这似乎是一个疏忽。也在此处添加断言。* 我们未能将 nodeModifyTable 的 ExecCheckPlanOutput() 应用于 ON CONFLICT UPDATE tlist。这不会捕获此特定错误,因为该函数被授权忽略 resjunk 列;但现在我们已经看到了这个错误,这看起来确实是一个不好的疏忽。在 HEAD 中,解决此问题的正确方法是使 ON CONFLICT UPDATE tlists 的处理方式与现在常规 UPDATE tlists 的处理方式相同,即不添加“SET x = x”条目,并使用 ExecBuildUpdateProjection 来评估 tlist 并将其与未设置列的旧值组合。这给 ExecBuildUpdateProjection 增加了一些复杂性,但允许从规划器中删除相当数量的现在已失效的代码。在后分支中,最便捷的解决方案似乎是(a)为 ON CONFLICT UPDATE 投影使用与目标表实际匹配的输出槽,然后(b)创建一个 ExecBuildProjectionInfo 的变体,该变体可以被告知不存储 resjunk 列产生的值,因此它不会尝试存储到输出槽的不存在的列中。(我们不能完全忽略 resjunk 列;必须对其进行评估,以便 MULTIEXPR_SUBLINK 工作。)这适用于 v10。在 9.6 中,投影的工作方式大相径庭,我们无法以便宜的方式给它们这样的选项。此补丁的 9.6 版本通过在必要时插入 JunkFilter 来消除 resjunk 列。此外,当尝试在分区表上执行 ON CONFLICT UPDATE 时,v11 及更高版本会遇到相反的问题。通过进一步的疏忽,adjust_partition_tlist() 在重新排序 ON CONFLICT UPDATE tlist 以匹配分区时丢弃了 resjunk 列。这意外地防止了存储虚假元组的问题,但代价是 MULTIEXPR_SUBLINK 情况不起作用,通常在必须更新多行时会崩溃。通过在该例程中保留 resjunk 列来修复。 (我未能抵挡住在这里添加更多断言和进行一些小的代码美化的诱惑。)根据 Andres Freund 的报告。向所有受支持的分支进行反向移植。安全:CVE-2021-32028 https://git.postgresql.org/pg/commitdiff/049e1e2edb06854d7cd9460c22516efaa165fbf8

  • 用 C 代码替换 opr_sanity 测试的 binary_coercible() 函数。 opr_sanity 的 binary_coercible() 函数一直旨在匹配解析器对二进制强制转换的概念,但它也一直是对解析器真实规则(如 IsBinaryCoercible() 中所体现的)的相当糟糕的近似。到目前为止,这并没有让我们陷入困境,但可以预见的是,它最终会这样做。现在还出现,在 clobber-cache-always 测试中,在 plpgsql 中实现此检查的性能非常糟糕。(也许我们可以对此做些什么,但我怀疑这只是意味着 plpgsql 正在充分利用目录缓存。)因此,让我们用直接调用 IsBinaryCoercible() 的 C 垫片替换 binary_coercible(),消除语义风险和性能问题。大多数 regress.c 的 C 函数都在 create_function_1 中声明,但我们不能简单地将其移动到 opr_sanity/type_sanity 之前,因为这些测试会抱怨生成的 shell 类型。我选择将其拆分为 create_function_0 和 create_function_1。由于 create_function_0 现在作为并行组的一部分运行,而 create_function_1 不运行,因此将后者减少为仅创建 opr_sanity 和 type_sanity 会抱怨的函数。为了为第二个并行测试组中的 create_function_0 腾出空间,将 tstypes 移动到第三个并行组。在传递过程中,清理 parallel_schedule 和 serial_schedule 之间的一些排序偏差。讨论:https://postgr.es/m/292305.1620503097@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/6303a5730914dfe6ef2709b28b225553315c573c

  • 删除单独的串行测试列表 serial_schedule。维护两个回归测试脚本列表已被证明是非常容易出错的。我们可以通过使用“--max_connections=1”运行 parallel_schedule 来实现 serial_schedule 的效果;因此,这样做并删除 serial_schedule。这会导致进度输出中的外观差异,但似乎不值得重组 pg_regress 以避免这种情况。讨论:https://postgr.es/m/899209.1620759506@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/1df3555acc78dedc3ca25eb5e83649b3da1f298f

  • 修复 vcregress.pl 中对 --max-connections 的旧式拼写错误。我复制了现有的“--max_connections”拼写,但这完全是错误的 :-(。显然,在此脚本中设置 $ENV{MAX_CONNECTIONS} 从未真正起作用。鉴于缺少投诉,可能不值得反向移植修复程序。每个构建场。讨论:https://postgr.es/m/899209.1620759506@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/0b85fa93e4575183aa5a71ebe3c6bae8d97704ed

  • 在 CLOBBER_CACHE_ALWAYS 下减少 privileges.sql 测试的运行时。权限回归测试中的几个查询会导致规划器将 plpgsql 函数“leak()”应用于 atest12.b 的每个直方图元素。由于提交 0c882e52a 将该直方图的大小增加到 10000 个条目,因此该测试会调用该函数超过 100000 次,这在 clobber-cache-always 模式下会花费绝对不合理的时间。但是,没有真正的原因要求它必须是 plpgsql 函数:就此测试的目的而言,所有重要的是它没有被标记为防泄漏。因此,我们可以用 int4lt 的直接调用替换 plpgsql 实现,它具有相同的行为并且速度快几个数量级。预计这将使 CCA 动物的构建场周期时间缩短几个小时。它在正常构建中也有一些积极的影响,尽管这可能淹没在噪声中。反向移植到 v13,其中 0c882e52a 出现。讨论:https://postgr.es/m/575884.1620626638@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/e135743ef07ea59088d09c459f41ee2eaabe95c3

  • 针对 v14 的初始 pgindent 和 pgperltidy 运行。还有“make reformat-dat-files”。唯一值得注意的变化是 pgindent 搞乱了 launcher.c 的 struct LogicalRepWorkerId 的格式,这让我注意到该结构不再使用了,所以我直接将其删除。https://git.postgresql.org/pg/commitdiff/def5b065ff22a16a80084587613599fe15627213

  • 对目录数据执行预发布内务处理。按照 RELEASE_CHANGES 指定的预 beta 任务,运行 renumber_oids.pl 以向下移动高编号的 OID。作为参考,该命令是 ./renumber_oids.pl --first-mapped-oid 8000 --target-oid 6150 https://git.postgresql.org/pg/commitdiff/14472442861ca95cc9158518acdedf740c4bff55

  • 文档:更新 bki.sgml 中关于 OID 范围的语句。提交 ab596105b 忽略了使文档与代码匹配。https://git.postgresql.org/pg/commitdiff/1f9b0e6938054515b8c9df545437c3d347eed683

  • 在 system_constraints.sql/system_functions.sql 中对命令进行双倍间距。以前,后端在读取 system_constraints.sql 时报告的任何错误都会报告整个文件,而不仅仅是它正在处理的特定命令。(问我怎么知道。)同样,system_functions.sql 中有一些块会作为一个命令读取,如果其中发生任何故障,这将很烦人。system_constraints.sql 的问题是提交 dfb75e478 中的一个疏忽。我没有尝试追踪 system_functions.sql 中格式不佳的起始位置,但这肯定与该文件开头的建议相反。https://git.postgresql.org/pg/commitdiff/7dde98728a2ef6d48ef397ee783dd130fdb34e6b

  • 重构 CHECK_FOR_INTERRUPTS() 以增加灵活性。拆分 CHECK_FOR_INTERRUPTS() 以提供额外的宏 INTERRUPTS_PENDING_CONDITION(),它仅测试是否有中断挂起,而不尝试处理它。这在调用者知道中断被阻塞,并且想知道是否值得解除阻塞的情况下很有用。还添加了 INTERRUPTS_CAN_BE_PROCESSED(),它指示是否可以依赖 CHECK_FOR_INTERRUPTS() 来清除挂起的中断。此提交实际上没有添加任何新宏的使用,但后续的错误修复会这样做。将该补丁向后移植到所有受支持的分支,为该修复提供基础结构。Alvaro Herrera 和 Tom Lane 的讨论:https://postgr.es/m/20210513155351.GA7848@alvherre.pgsql https://git.postgresql.org/pg/commitdiff/e47f93f981ccb70b4c4c5a0966e5fa0400e11a7e

  • 修复 spgdoinsert() 中的查询取消处理。考虑到有缺陷的操作符类可能会导致无限插入循环,spgdoinsert() 旨在允许其循环被查询取消中断。但是,这实际上从未奏效,因为在第一次迭代之后,我们会持有缓冲区锁,这会导致 InterruptHoldoffCount 为正数,从而阻止中断处理。为了修复此问题,请检查是否有中断挂起,如果有,则退出插入循环,并在释放缓冲区后处理中断。如果确实是查询取消,则此事结束。如果是非取消中断的原因,则利用现有规定重试整个插入。(这并不像看起来那样浪费,因为我们已经创建的任何上层索引元组都应该可以在下一次尝试中使用。)尽管在现有发布分支中没有已知的此类错误实例,但将此向后移植到所有受支持的分支仍然是一个好主意,因为如果发生循环,则行为会非常糟糕---它不仅无法取消,而且会迅速消耗内存到 OOM 失败的地步。无论如何,此代码肯定没有按预期工作。根据 Dilip Kumar 的报告。讨论:https://postgr.es/m/CAFiTN-uxP_soPhVG840tRMQTBmtA_f_Y8N51G7DKYYqDh7XN-A@mail.gmail.com https://git.postgresql.org/pg/commitdiff/eb7a6b9229432dcb791f4bf0c44fe97bab661134

  • 防止 spgdoinsert() 中的无限插入循环。以前,我们只是依靠断言 longValuesOK 的操作符类来最终缩短叶值,使其足以容纳在索引页上。自从引入 INCLUDE 列支持(提交 09c1c6ab4)以来,这种情况失败了,因为 INCLUDE 列本身可能占用超过一页,这意味着无论如何压缩叶数据都无法完成工作。至少对于 spgtextproc.c 来说,这会导致无限循环,因为 spgtextproc.c 不会因为无法再缩短叶数据而抛出错误。为了在不破坏其他情况下有效的情况下进行修复,请添加逻辑到 spgdoinsert(),以验证叶元组大小在每个“选择”步骤后都在减小。某些操作符类可能不会在每个周期都减小大小,并且在任何情况下,元组大小的对齐舍入也可能会掩盖小的增益。因此,允许最多 10 个周期没有额外节省,然后再抛出错误。(也许这个数字需要调整,但现在看来相当慷慨。)只要我们开发了这个逻辑,我们就向后移植它。后向分支不必担心 INCLUDE 列,但这似乎是对操作符类中可能存在的错误的良好防御。我们已经知道这里的无限循环非常令人不愉快,因此进行防御似乎比破坏某些东西的风险更大。(请注意,spgtextproc.c 实际上是唯一已知具有 longValuesOK 支持的操作符类,因此无论如何,对于已知的非核心操作符类,这一切都是没有意义的。)根据 Dilip Kumar 的报告。讨论:https://postgr.es/m/CAFiTN-uxP_soPhVG840tRMQTBmtA_f_Y8N51G7DKYYqDh7XN-A@mail.gmail.com https://git.postgresql.org/pg/commitdiff/c3c35a733c77b298d3cf7e7de2eeb4aea540a631

  • 在释放 BackgroundWorkerSlots 时更加小心地处理屏障。ForgetBackgroundWorker 完全没有任何内存屏障,而 BackgroundWorkerStateChange 有一个屏障,但在屏障之后却莫名其妙地对槽进行了额外的操作。AFAICS,规则必须是屏障紧接在设置或清除 slot->in_use 之前。看来早在 9.6 中首次编写 ForgetBackgroundWorker 时,可能有一些不需要屏障的情况,但我对此不太确信---bgw_notify_pid 的加载在调用者中似乎并不能保证没有内存排序问题。因此,也要修补 9.6。这很可能不会修复 Intel 硬件上的任何可观察到的错误,但具有较弱内存排序规则的机器可能会在此处出现问题。讨论:https://postgr.es/m/4046084.1620244003@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/30d8bad494ad1f604295033e4f4de4b8f258fe74

Michaël Paquier 推送

Thomas Munro 推送

Bruce Momjian 推送

Peter Eisentraut 推送了

David Rowley 推送了

Andrew Dunstan 推送了

Fujii Masao 推送了

Etsuro Fujita 推送了

  • 修复异步能力节点的 EXPLAIN ANALYZE。对于与 postgres_fdw 关联的具有异步能力的 ForeignScan 节点的 EXPLAIN ANALYZE,只需使用从节点回调调用的 ExecProcNode() 的检测即可完成,从而导致以下问题:1)如果要扫描的远程表为空,则即使执行了节点,该命令也错误地认为该节点为“从未执行过”,因为在这种情况下,根本不会从节点回调调用 ExecProcNode()。 2) 该命令无法收集在节点中完成的 ExecProcNode() 以外的事情的计时,例如为节点的远程查询创建游标。为了解决这些问题,为具有异步能力的节点添加检测,并相应地修改 postgres_fdw。这是我在提交 27e1f1456 中的疏忽。同时,更新 execnodes.h 中 AsyncRequest 结构的注释,以及 fdwhandler.sgml 中 ForeignAsyncRequest API 的文档,以匹配 nodeAppend.c 中的 ExecAsyncAppendResponse() 中的代码,并修复 nodeAppend.c 中注释的拼写错误。根据 Andrey Lepikhov 的报告,尽管我没有使用他的补丁。审核者:Andrey Lepikhov 讨论:https://postgr.es/m/2eb662bb-105d-fc20-7412-2f027cc3ca72%40postgrespro.ru https://git.postgresql.org/pg/commitdiff/a363bc6da96b14d27e1cae1bae97242eb6ade5e6

  • 防止直接外表修改的异步执行。提交 27e1f1456 和 86dc90056 是独立讨论的,当执行启用了异步执行的继承外键 UPDATE/DELETE 查询时会导致崩溃,其中 ModifyTable 节点的直接/间接子节点的 Append 节点的子节点被重写为通过 postgresPlanDirectModify() 直接修改外表;因为在这种情况下,直接修改是异步执行的,而异步执行目前不支持此操作。通过禁用该函数中直接修改的异步执行来解决此问题。作者:Etsuro Fujita 审核者:Amit Langote 讨论:https://postgr.es/m/CAPmGK158e9sJOfuWxfn%2B0ynrspXQU3JhNjSCbaoeSzMvnga%2Bbw%40mail.gmail.com https://git.postgresql.org/pg/commitdiff/a784859f4480ceaa05a00ca35311071ca33483d1

Álvaro Herrera 推送了

Amit Kapila 推送了

Alexander Korotkov 推送了

Peter Geoghegan 推送了

待处理的补丁

Amit Langote 提交了另一个补丁修订版,允许在跨分区更新期间进行批量插入。

Nitin Jadhav 提交了一个补丁,用于匹配 src/backend/utils/activity/backend_status.c 中注释中的实际文件路径。

Bharath Rupireddy 提交了一个补丁,使 PostgreSQL FDW 缓存连接函数测试更有意义。

Thomas Munro 提交了一个补丁,用于清除 HASH_REMOVE 释放的内存,并避免在释放本地锁后访问它们。

Andres Freund 提交了一个补丁,用于在 walreceiver 中将部分页面置零。

Peter Smith 提交了一个补丁,以确保 GetSubscriptionRelations 只声明 1 个扫描键。

Vigneshwaran C 提交了另外三个补丁修订版,以在逻辑复制消息描述中包含实际使用的数据类型。

Tang 提交了另外三个补丁修订版,使 psql 中 DELETE FORM 和 INSERT INTO 的 Tab 补全保持一致。

Vigneshwaran C 提交了另外三个补丁修订版,以使错误消息更具信息性,说明实际错误。

Kyotaro HORIGUCHI 提交了另外两个补丁修订版,以基于 recoveryTargetTLI 正确设置 expectedTLEs。

Etsuro Fujita 提交了另一个补丁修订版,以修复异步可感知节点的 EXPLAIN ANALYZE。

Hou Zhijie 提交了另一个补丁修订版,以检查 fmgr_info 中的 UDF 并行安全性,修复测试用例中 UDF 的并行安全性标签,检查 fmgr_info 中的内置函数并行安全性,并修复测试用例中的内置并行安全性标签。

Honza Horak 提交了一个补丁,以修复 Python 3.10 的子事务测试。

Masahiko Sawada 提交了另一个补丁修订版,引入外事务的事务管理器,并使用该管理器来处理涉及它们的两阶段提交。

Masahiro Ikeda 提交了另外两个补丁修订版,以提高 wal 统计信息的报告性能。

Hou Zhijie 提交了另外两个补丁修订版,使用户可以声明表允许并行数据修改,为 insert 启用并行选择,实现一个实用函数 pg_get_parallel_safety(regclass),该函数返回 (objid, classid, parallel_safety) 的记录,这些记录表示确定指定表并行安全性的对象的并行安全性,并更新回归测试以包含相同内容。

Pavel Stěhule 提交了另外两个补丁修订版,以实现模式变量。

Pavel Stěhule 提交了另一个补丁修订版,使 pg_dump 可以从文件中读取表名。

Pavel Stěhule 提交了另一个补丁修订版,使可以为 psql 中的 \watch 指定单独的分页器。

Zeng Wenjing 提交了另一个补丁修订版,以实现全局临时表。

Tom Lane 提交了另一个补丁修订版,以用固定范围检查替换 pg_depend PIN 条目。

Atsushi Torikoshi 提交了一个补丁,添加了一个 pg_log_current_plan(pid) 函数,该函数允许人们获取当前正在执行的查询的计划。

Mark Dilger 提交了另一个补丁修订版,将 GUC 变量的设置委托给一些新创建的 ROLE。

Michail Nikolaev 提交了另外两个补丁修订版,以在备用机上添加对索引 LP_DEAD 提示位的完全支持。

Amul Sul 提交了另外两个补丁修订版,以实现 ALTER DATABASE READ {ONLY | WRITE}。

Vigneshwaran C 和 Bharath Rupireddy 交换了补丁,以澄清 ALTER SUBSCRIPTION ... DROP PUBLICATION 的消息和文档。

Ranier Vilela 提交了一个补丁,修复了 src/backend/commands/tablecmds.c 中显式的 NULL 指针解引用。

Michaël Paquier 提交了一个补丁,添加了一个 vacuum_cleanup_index_scale_factor GUC。

Vigneshwaran C 提交了两个补丁修订版,旨在通过检查 pg_replication_slot 中的活动列而不是 pg_stat_replication 来修复一个表现为消息文本失败的错误,pg_replication_slot 测试更可靠。

Bharath Rupireddy 提交了一个补丁,重新措辞了并行 VACUUM 的错误消息和文档。

Nathan Bossart 提交了一个补丁,允许在 pg_hba.conf 中指定直接角色成员关系。

Peter Smith 和 Ajin Cherian 交换了补丁,以支持两阶段事务的逻辑解码。

Peter Geoghegan 提交了一个补丁,以考虑在 vacuumlazy.c 中首次扫描期间触发故障保护。

Amit Langote 提交了一个补丁,以修复 pgoutput tupeconv 映射泄漏。

Kyotaro HORIGUCHI 提交了一个补丁,以使有关花括号的错误与其名称相匹配。

Vigneshwaran C 提交了三个补丁修订版,为 psql 的 ALTER SUBSCRIPTION SET options streaming 和 binary 添加 Tab 补全。

Ranier Vilela 提交了两个补丁修订版,以修复 src/timezone/zic 中可能发生的内存损坏。

Michaël Paquier 提交了另一个补丁修订版,将 pg_upgrade 的测试重写为 TAP 测试。

Nitin Jadhav 和 Justin Pryzby 交换了补丁,以从 create_list_bounds 中删除额外的内存分配,将 PartitionListValue 和 create_hash_bounds PartitionHashBound 分配为一个块,批量分配数据数组以避免 palloc 开销,并在 create_range_bounds 中 pfree() 中间结果。

Tom Lane 提交了两个补丁修订版,旨在修复一个错误,该错误表现为 prion 在 pg_toast_2619 中对 toast 值 14334 报错:缺少块号 0。

Tatsuo Ishii 提交了两个补丁修订版,以修复 README.barrier 中的拼写错误。

Nitin Jadhav 提交了一个补丁,以支持 to_char() 中的 tzh_tzm 模式。