PostgreSQL 每周新闻 - 2021 年 4 月 18 日

由 PWN 发布于 2021-04-19
PWN

PostgreSQL 每周新闻 - 2021 年 4 月 18 日

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

PostgreSQL 产品新闻

pgmetrics 1.11,一个用于 PostgreSQL 指标的命令行工具,已发布。https://pgmetrics.io/

hypopg 1.2.0,一个实现假设索引的扩展,已发布。https://github.com/HypoPG/hypopg/releases

四月份的 PostgreSQL 工作

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

PostgreSQL 新闻

PostgreSQL 星球:https://planet.postgresql.org/

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

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

已应用的补丁

Tom Lane 推送

  • 消除一些 Coverity 警告并提高代码一致性。Coverity 抱怨诸如 intresult = tm->tm_sec * 1000000 + fsec 之类的表达式中可能存在溢出;理由是乘法运算会在扩展到 int64 结果之前以 32 位算术进行。我认为这些都是误报,因为 tm_sec 的可能范围有限;但尽管如此,当附近行使用 64 位常量编写相同的计算时,这样拼写似乎很愚蠢。 ... 或者更准确地说,使用 LL 常量,这不是项目风格。让所有这些都使用 INT64CONST(),就像我们在其他地方所做的那样。这都是来自 a2da77cdb 的新代码,因此无需反向移植。https://git.postgresql.org/pg/commitdiff/6277435a8a89c59f716c111200c072d1454b8ff2

  • 修复强制转换 COLLATE 表达式结果的旧错误。parse_coerce.c 中有一些技巧可以将请求的强制转换下推到可能出现的任何 CollateExpr 之下。但是,即使请求的数据类型是不可排序的,我们也会这样做,从而导致无效的表达式树,其中 CollateExpr 应用于不可排序的类型。修复方法只是完全删除 CollateExpr,理由是它是无用的。这个错误已经有十年历史了,可以追溯到最初添加 COLLATE 支持的时候。缺乏现场投诉表明,没有很多用户可见的后果。我们注意到这个问题是因为如果无效结构作为视图的输出列出现,它会在 DefineVirtualRelation 中触发断言;但是,在非断言版本中,您不会看到崩溃,只会看到(略微不正确的)关于将排序规则应用于不可排序类型的抱怨。我发现通过将不正确的结构放在视图的更下方,我可以创建一个视图定义,该定义将导致转储/重新加载失败,如添加的回归测试用例所示。但是 CollateExpr 在运行时不会执行任何操作,因此这可能不会导致任何真正令人兴奋的后果。根据 Yulin Pei 的报告。反向移植到所有受支持的分支。讨论:https://postgr.es/m/HK0PR01MB22744393C474D503E16C8509F4709@HK0PR01MB2274.apcprd01.prod.exchangelabs.com https://git.postgresql.org/pg/commitdiff/c402b02b9fb53aee2a26876de90a8f95f9a9be92

  • 删除不再相关的测试用例。collate.icu.utf8.sql 正在练习记录枚举比较表达式的排序规则依赖性,但是这样的表达式从一开始就不应该有任何排序规则依赖性。在我修复 c402b02b9 中的问题后,测试开始失败。我们不再需要测试该场景,因此只需删除现在无用的测试步骤。(此测试用例在 HEAD 中是新的,因此无需反向移植。)讨论:https://postgr.es/m/3044030.1618261159@sss.pgh.pa.us 讨论:https://postgr.es/m/HK0PR01MB22744393C474D503E16C8509F4709@HK0PR01MB2274.apcprd01.prod.exchangelabs.com https://git.postgresql.org/pg/commitdiff/cf0020080a3de20287217621da57bfd840e9a693

  • 避免在 heap_update 期间发生不太可能的 PANIC。heap_update 需要清除旧元组页面(如果不同,也包括新页面)上的任何现有的“全部可见”标志。根据编码规则,要做到这一点,它必须在不持有独占缓冲区锁的情况下获取适当可见性映射页面的引脚;这会创建一个竞争条件,因为当我们在不持有缓冲区锁时,其他人可以设置该标志。该代码应该通过在获取缓冲区锁后重新检查标志并在设置标志时重试来处理该问题。但是,heap_update 本身中的一个代码路径,以及其子例程 RelationGetBufferForTuple 中的一个代码路径,未能执行此操作。最终结果是,在不太可能发生的并发 VACUUM 在我们暂时不持有锁时设置该标志的情况下,会出现非重复的“PANIC: 传递给 visibilitymap_clear 的缓冲区错误”失败。自从最近的 VACUUM 更改添加了可以在仅持有独占缓冲区锁的情况下设置全部可见标志的代码路径以来,这在构建农场中已经见过几次。以前,该标志(通常?)仅在执行 LockBufferForCleanup 后设置,这将坚持缓冲区引脚计数为零,从而防止在 heap_update 中途设置该标志。但是,很明显,这是 heap_update 而不是 VACUUM 的错误。不太清楚的是,这些错误是否对发布的分支构成任何风险。heap_update 当然违反了 API 期望,但是如果没有代码路径可以在没有清理锁的情况下设置全部可见,那么这只是一个潜在的错误。但这并不是 100% 确定,此外,我们应该担心可能会引入此类代码路径的扩展或未来的反向移植修复。我选择反向移植到 v12。在此之前修复 RelationGetBufferForTuple 将需要反向移植旧修复程序的部分内容(特别是 0d1fe9f74),这似乎比修复一个假设问题需要更多的代码改动。讨论:https://postgr.es/m/2247102.1618008027@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/34f581c39e97e2ea237255cf75cccebccc02d477

  • 重新设计 get_cached_rowtype() 完成的缓存。以前,get_cached_rowtype() 缓存了一个指向类型缓存中引用计数元组描述符的指针,依赖 ExprContextCallback 机制在销毁使用 tupdesc 的表达式树时释放 tupdesc 引用计数。当它被设计时,这工作得很好,但是引入 DO 块内的 COMMIT 打破了它。引用计数记录在事务生命周期的资源所有者中,但是 plpgsql 不会在退出 DO 块之前(在第一次提交之前)销毁 DO 块内创建的简单表达式。这会导致在 COMMIT 销毁原始资源所有者时发出有关泄露的 tupdesc 引用计数的警告,然后在销毁表达式时发出关于活动资源所有者不持有匹配引用计数的错误。为了解决这个问题,通过缓存一个指向相关类型缓存条目的指针,从而完全无需关闭回调。这些在后端生命周期内存在,因此我们不必担心指针会过期。(对于注册的 RECORD 类型,我们仍然可以缓存一个指向 tupdesc 的指针,因为我们知道它在后端生命周期内不会更改。)自提交 4b93f5799 以来,此机制已在 plpgsql 和 expandedrecord.c 中使用,并且似乎工作良好。此更改需要修改相关表达式步骤类型使用的 ExprEvalStep 结构,这对于反向移植有点令人担忧。但是,似乎没有充分的理由让扩展熟悉这些特定子结构的详细信息。根据 Rohit Bhogate 的报告。反向移植到 v11,其中在 DO 块内的 COMMIT 成为现实。讨论:https://postgr.es/m/CAAV6ZkQRCVBh8qAY+SZiHnz+U+FqAGBBDaDTjF2yiKa2nJSLKg@mail.gmail.com https://git.postgresql.org/pg/commitdiff/c2db458c1036efae503ce5e451f8369e64c99541

  • 修复 ALTER ROLE/DATABASE SET 的一些不适当的禁用用法。大多数检查数据库状态的 GUC 检查钩子都有特殊的检查,以防止它们在 source == PGC_S_TEST 时为依赖于状态的问题引发硬错误。例如,当尚未创建“foo”配置时,这允许“ALTER DATABASE d SET default_text_search_config = foo”。如果没有这个,我们在转储/重新加载或 pg_upgrade 期间会出现问题,因为 pg_dump 不知道 GUC 值的可能依赖关系,并且无法确保安全的恢复顺序。但是,check_role() 和 check_session_authorization() 没有收到关于此的通知,并且无论如何都会引发硬错误。“ALTER ROLE x SET role = y”的用例并不完全清楚,但是我们现在已经收到了两个关于此破坏升级的独立投诉,因此显然有人在这样做。因此,修复这两个函数,使其行为更像其他具有类似需求的检查钩子。(但是我没有更改他们坚持在事务内部的要求,因为仍然不明显从配置文件中设置任一 GUC 是明智之举。)还要修复 check_temp_buffers,它也有相同形式的疾病,即在没有为 PGC_S_TEST 设置任何例外的情况下进行依赖于状态的检查。对其他 GUC 检查钩子的粗略调查没有发现任何更多此类问题。(PGC_POSTMASTER 和 PGC_SIGHUP GUC 之间存在许多相互依赖关系,这可能是一个坏主意,但它们与当前关注的问题无关,因为它们无法通过 ALTER ROLE/DATABASE 设置。)根据 Charlie Hornsby 和 Nathan Bossart 的报告。反向移植到所有受支持的分支。讨论:https://postgr.es/m/HE1P189MB0523B31598B0C772C908088DB7709@HE1P189MB0523.EURP189.PROD.OUTLOOK.COM 讨论:https://postgr.es/m/20160711223641.1426.86096@wrigleys.postgresql.org https://git.postgresql.org/pg/commitdiff/69d5ca484b69771073380e234e5377b6d6a5ebaf

  • 允许在 ON CONFLICT ... WHERE 子句中使用带表限定符的变量名。之前,你在这里只能使用不带限定符的变量名。虽然这在功能上没有缺陷,因为只能引用目标表,但这与部分索引谓词的规则(此语法据说是模仿的)存在令人惊讶的不一致。修复方法很简单,只需将 addToRelNameSpace = true 传递给 addNSItemToQuery 即可。然而,`transformOnConflictArbiter` 和 `transformOnConflictClause` 为了目标表的命名空间项而混淆处理,这真是非常荒谬的。它不是它们管理的,会导致命名空间项的重复创建,而且 `transformOnConflictClause` 甚至没有完全正确地执行此操作(因为没有清除现有的,该代码导致了目标表的两个命名空间项)。因此,让 `transformInsertStmt` 负责为这两个子句和 RETURNING 设置目标命名空间项一次。此外,安排在运行 `transformOnConflictArbiter` 之前,将 ON CONFLICT ... UPDATE 的“excluded”伪关系添加到范围表。如果有人在仲裁表达式中写入“excluded.col”,这将产生更有用的 HINT。根据 Lukas Eder 提出的 bug #16958。虽然我同意这是一个 bug,但其后果并不严重,所以不进行向后移植。讨论:https://postgr.es/m/16958-963f638020de271c@postgresql.org https://git.postgresql.org/pg/commitdiff/6c0373ab77359c94b279c4e67c91aa623841af65

  • 修复引用过时的 JoinPathExtraData.extra_lateral_rels 的注释。该字段在提交 edca44b15 中被删除,但提交 45be99f8c 似乎重新引入了一些提到它的注释。James Coleman 注意到了这一点,虽然这并不是他提出的新措辞。还要感谢 Justin Pryzby 的软件考古学。讨论:https://postgr.es/m/CAAaqYe8fxZjq3na+XkNx4C78gDqykH-7dbnzygm9Qa9nuDTePg@mail.gmail.com https://git.postgresql.org/pg/commitdiff/e1623b7d86812ee6ab98a42f38b43a192c149988

  • 稳定最近添加的 information_schema 测试查询。如果核心系统或同时运行的测试脚本创建了任何会出现在 information_schema 视图中的函数,这些查询可能会显示意外的条目。将它们限制为仅显示属于此测试模式的函数,就像附近较旧的测试用例一样。根据将一些内置函数转换为 SQL 函数体风格的实验得出。 https://git.postgresql.org/pg/commitdiff/3157cbe974846729d49a1ee081944eee1839bdd8

  • 撤销允许 pg_proc.prosrc 为 NULL 的决定。提交 e717a9a18 更改了长期以来的规则,即 prosrc 不为 NULL,因为当 SQL 语言函数以 SQL 标准风格编写时,我们目前没有任何有用的东西放在那里。但这似乎是一个糟糕的决定,因为它很容易对外部 PL 产生负面影响(例如,使它们容易发生以前不会发生的崩溃)。与测试“prosrc 是否为 null”一样,SQL 函数相关代码可以轻松测试“prosqlbody 是否不为 null”,因此也没有真正的收获。因此,恢复删除 NOT NULL 标记并调整相关逻辑。目前,我们只是为 SQL 标准函数在 prosrc 中放入一个空字符串。也许我们以后会有更好的想法,尽管像 pg_attrdef.adsrc 这样的东西的历史表明,维护节点树的字符串等效物并不容易。这还添加了一个断言,即 queryDesc->sourceText != NULL 到 standard_ExecutorStart。我们已经默默地依赖这一点一段时间了,所以让它不那么沉默。还要修复一些被忽略的文档和测试用例。讨论:https://postgr.es/m/2197698.1617984583@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/1111b2668d89bfcb6f502789158b1233ab4217a6

  • 恢复“在 ExecInitParallelPlan() 中处理 NULL 查询字符串。”。这将恢复提交 b3ee4c503872f3d0a5d6a7cbde48815f555af15b。在前面的提交添加了查询字符串不为 null 的上游检查之后,我们不再需要它了。讨论:https://postgr.es/m/2197698.1617984583@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/83efce7a1ebc5bae79617ddba12a64790141725c

  • 在解析 SQL 标准函数体时提供查询源文本。没有这个,我们会丢失错误光标位置,如修改后的回归测试结果所示。讨论:https://postgr.es/m/2197698.1617984583@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/409723365b2708acd3bdf2e830257504bdefac4b

  • 修复两个 ExplainPropertyFloat 调用中的错误单位。这只是一个潜在的 bug,因为这些调用仅针对非文本输出格式到达,并且目前这些格式都不会打印单位。尽管如此,我们应该在这种情况发生时使其正确。Justin Pryzby 讨论:https://postgr.es/m/20210415163846.GA3315@telsasoft.com https://git.postgresql.org/pg/commitdiff/f90c708a048667befbf6bbe5f48ae9695cb89de4

  • 修复错误的排序规则版本记录逻辑。`recordMultipleDependencies` 的“version”变量的作用域错误,允许版本标签从其应有的排序规则条目泄漏到后续的非排序规则条目。由于输入通常会以 OID 降序排列,这相对难以触发:后续的非排序规则项往往会被固定。但是,使用自定义排序规则可以很容易地展示这一点。此外,不要特殊处理默认排序规则,而是在我们找到排序规则的版本时忽略排序规则的固定状态。这避免了创建无用的 pg_depend 条目,并消除了一个不太面向未来的假设,即 C、POSIX 和 DEFAULT 是唯一固定的排序规则。一个小问题是,由于默认排序规则可能具有或不具有版本,因此回归测试无法假设是否会为其创建依赖项条目。但这似乎没问题,因为它现在与其他排序规则的处理方式相同,并且我们有针对版本化和未版本化排序规则的测试用例。修复了提交 257836a75 中的疏忽。感谢 Julien Rouhaud 的审查。讨论:https://postgr.es/m/3564817.1618420687@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/ef387bed87f2787b1012e68e9a33607a1074c123

  • 将函数定义从 system_views.sql 拆分到一个新文件中。创建 system_functions.sql 来保存以前在 system_views.sql 中的函数定义。函数定义已经占了该文件的四分之一,并且即将变得更多,因此将它们放到自己的家中似乎是合适的。顺便说一下,修复 dfb75e478 中的疏忽:它忽略了为 system_constraints.sql 调用 check_input()。讨论:https://postgr.es/m/3956760.1618529139@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/e80949372564c126c92aa7d64de483e04c0ef95e

  • 将内置 SQL 语言函数转换为 SQL 标准体样式。为所有内置和 information_schema SQL 语言函数采用新的预解析表示形式,除了少数因具有多态参数而目前无法转换的函数。这消除了这些函数周围的搜索路径安全性的残留风险,并且可能通过降低解析成本提供一些小的性能优势。为 SQL 标准体功能提供更多的测试覆盖率似乎也很有用。讨论:https://postgr.es/m/3956760.1618529139@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/767982e36298be4da44a063e36261e9cfdc0bf49

  • 更新虚拟 prosrc 值。哎呀,忘记在 767982e36 的这部分中将 system_views.sql/g 替换为 system_functions.sql 了。我认为,由于这些字符串在 initdb 完成时已经消失了,因此无需额外的 catversion 提升。讨论:https://postgr.es/m/3956760.1618529139@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/8a2df442b652f83b1c189822737091b90f343965

  • 重新考虑排序规则依赖项的提取。目前,`find_expr_references_walker()` 关注叶节点排序规则字段,而忽略实际函数和运算符节点的输入排序规则。从语义角度来看,这似乎完全相反,并且会导致报告与表达式行为无关的排序规则的依赖项。因此,重写为查看函数输入排序规则。这也不是完全完美的;它未能解释 `record_eq` 及其兄弟节点的行为。(之前的代码至少给出了一个近似值,但我认为它很容易被欺骗,从而考虑不相关的复合类型的列。)我们可能会在以后改进这一点,但现在这应该能满足不喜欢 ef387bed8 的构建农场成员。顺便说一下,修复 `GetTypeCollations()` 中的一些疏忽,并删除其重复的去重操作。(我担心它仍然可能是 O(N^2) 或更糟,但这使它稍微好一点。)讨论:https://postgr.es/m/3564817.1618420687@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/f24b156997059c257c697b825f022d115825091d

Michaël Paquier 推送了

Amit Kapila 推送了代码。

Fujii Masao 推送了代码。

Peter Eisentraut 推送了代码。

Thomas Munro 推送了代码。

Noah Misch 推送了代码。

Robert Haas 推送了代码。

Peter Geoghegan 推送

Tomáš Vondra 推送

Andrew Dunstan 推送

  • 允许 TestLib::slurp_file 跳过内容,并根据需要使用。为了避免获取旧的日志文件内容,PostgresNode 中的某些函数正在执行以下两件事之一。在 Windows 上,它会轮换日志文件并重新启动服务器,而在其他地方,它会截断日志文件。这两种方法都是不必要的。我们借鉴了 buildfarm 的做法,它这样做:在开始之前记录日志文件的大小,然后在获取日志文件时,跳到该位置之前累积内容。这在 Windows 上的拼写不同,但效果是相同的。这主要集中在 TestLib 的 slurp_file 函数中,该函数有一个新的可选参数,即在开始读取文件之前要跳过的偏移量。客户端中的代码变得更加简洁。回溯到所有活动分支。Michael Paquier,我略作修改。讨论:https://postgr.es/m/YHajnhcMAI3++pJL@paquier.xyz https://git.postgresql.org/pg/commitdiff/3c5b0685b921533f37622345beb0f8dd49200c01

待定补丁

Andy Fan 提交了一个补丁,用于记录 RelOptInfo.partexprs 和 nullable_partexprs 的增强功能,并将 gen_prune_steps_from_exprs 分割成更小的块。

Luc Vlaming 提交了另一个补丁版本,以添加显式的部分 UNION ALL 路径,并改进并行子查询的行数和成本计算。

Luc Vlaming 提交了另一个补丁版本,通过不发出 LLVMPassManagerBuilderUseInlinerWithThreshold pass,并在首次调用时惰性地生成 IR 代码,来提高 JIT 性能。

Amul Sul 提交了另一个补丁版本,以实现 ALTER SYSTEM ... READ {ONLY | WRITE}。

James Coleman 提交了一个补丁,以添加对 NOT IN 的 HashedScalarArrayOp 支持。

Amit Langote 提交了一个补丁,以修复 PartitionDesc includes_detached 中的一个错误。

Masahiko Sawada 提交了一个补丁,以修复 REFRESH MATERIALIZED VIEW 的性能下降问题。

Peter Smith 提交了另一个补丁版本,以向内置逻辑复制添加对准备事务的支持,并为流式事务添加 prepare API 支持。

Vigneshwaran C 和 traded 补丁,以识别 CREATE/ALTER SUBSCRIPTION 中发布者缺失的发布。

Vigneshwaran C 提交了一个补丁,以修复监控统计文档中的不一致之处。

Bruce Momjian 提交了两个补丁版本,以修复 pg_stat_activity 中最新添加的查询 ID 中的一些命名问题。

Mark Dilger 提交了另外两个 pg_amcheck 应用程序的补丁版本,以添加 TOAST 指针损坏检查。

Melanie Plageman 提交了一个补丁,以添加一个系统视图 pg_stat_buffers_written,该视图如其名称所示。

Fujii Masao、Kyotaro HORIGUCHI 和 Justin Pryzby 交换了补丁,以修复外表上新的 TRUNCATE 功能中的一些不完善之处。

Justin Pryzby 提交了另外两个补丁版本,以完善 14 的文档。

Amit Langote 提交了一个补丁,以按需初始化 WITH CHECK OPTIONS 和 RETURNING 表达式。

Ekaterina Sokolova 提交了另一个补丁版本,以添加额外的统计信息来解释嵌套循环。

Haiying Tang 提交了另一个补丁版本,以支持在 psql 中使用查询结果进行大写字符输入的制表符补全。

Dave Page 提交了一个补丁,以修复 sepgsql 中的日志记录问题。

Andrei Zubkov 提交了另一个补丁版本,以在 pg_stat_statements 中跟踪语句的进入时间戳。

David Christensen 提交了一个补丁,以扩展 pg_size_pretty(numeric) 知道的单位,以包括高达尧字节的单位。

Bharath Rupireddy 提交了另外两个补丁版本,以避免在 slot_store_error_callback 和 conversion_error_callback 中访问系统目录。

Masahiko Sawada 和 Peter Geoghegan 交换了补丁,以确保 VACUUM 记帐的代码注释解释 LP_DEAD 记帐。

Ajin Cherian 提交了另外两个补丁版本,以跳过逻辑复制的空事务。

Julien Rouhaud 提交了一个补丁,用于处理一些关于使用查询 ID 进行日志记录的极端情况。这里的问题是,某些查询在语法上有效时可以被记录,但缺少对它们在目录中引用的对象的存在性检查。该修复程序向 log_line_prefix 添加了一个 %Q 选项,该选项会检查是否实际找到了对象。

Zeng Wenjing 和 Shawn Wang 交换了补丁,以实现全局临时表。

Tom Lane 提交了一个补丁,以将 pg_depend PIN 条目替换为固定范围检查。

Amul Sul 提交了一个补丁,以从 transformCreateStmt 中删除一个冗余变量。

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

Matthias van de Meent 提交了两个补丁版本,用于记录 ATTACH PARTITION 对于默认分区的锁定行为。

Matthias van de Meent 提交了一个补丁,以实现 `_bt_binsrch*` 的页面级动态前缀截断,然后使用相同的方法来实现和使用索引元组属性迭代。

James Coleman、Tomáš Vondra 和 Tom Lane 交换了补丁,旨在修复 TPC-DS 查询 94-96 中表现为“找不到排序的路径键项”的错误。

Masahiro Ikeda 提交了另一个补丁版本,以提高报告 WAL 统计信息的性能。

Tomáš Vondra 提交了一个补丁,以在 generate_orderedappend_path 中生成部分最便宜路径。

Takamichi Osumi 和 Li Japin 交换了补丁,以修复 TRUNCATE 和同步逻辑复制之间的不协调之处。

Michaël Paquier 提交了另一个补丁版本,以修复逻辑复制工作程序中的 relcache 泄漏。

Mark Dilger 提交了两个补丁版本,以向 pg_amcheck 添加 --install-missing 选项。

Sven Klemm 提交了一个补丁,以修复 pg_event_trigger_ddl_commands,在同一事务中删除对象的情况下,它可能会查看无效的缓存。

Andy Fan 提交了一个补丁,以确保 set_append_rel_size 考虑初始分区修剪。

Tom Lane 提交了一个补丁,以在重复的子查询上拉中节省一些周期。