2025年9月25日: PostgreSQL 18 发布!

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

发布于 2021-04-12, 作者 PWN
PWN

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

PostgreSQL 14 的功能冻结已经到来。任何可能包含在 PostgreSQL 14 中的新功能都已在 git 仓库中。

PostgreSQL 产品新闻

AGE 0.4.0 发布,这是一个提供图数据库功能的 PostgreSQL 扩展。 https://github.com/apache/incubator-age/releases/tag/0.4.0

四月 PostgreSQL 工作机会

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

PostgreSQL 相关新闻

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

本周 PostgreSQL 周报由 David Fetter 提供。

请在太平洋标准时间(PST8PDT)周日晚上3:00之前将新闻和公告发送至 david@fetter.org。

已应用补丁

Tom Lane 提交

  • 修复 SP-GiST 中的更多混乱。spg_box_quad_leaf_consistent 无条件地将叶子节点数据(leaf datum)作为 leafValue 返回,即使在使用 poly_ops 时,该值类型完全错误。在 12 版本之前,这并无害处,因为核心代码在非仅索引扫描(non-index-only scans)中不会对 leafValue 进行任何操作……但自从提交 2a6368343 以来,如果我们进行 KNN 风格的扫描,spgNewHeapItem 会无条件地尝试使用错误的数据类型参数复制该值。如果我们最终不返回数据,这种复制就是浪费时间和空间,但直到我修复了 ac9099fc1 中的数据类型混乱,它才意外地失败。因此,更改 spgNewHeapItem,除非确实要稍后返回数据,否则不复制数据。这可以节省周期,并避免了有损操作符类(lossy opclasses)是否返回正确类型的问题。另外,更改 spg_box_quad_leaf_consistent 以不返回可能类型错误的数据,以防止有人在未来将类似的 bug 引入核心代码。我建议将这两项更改回溯到 v12 和 v13 版本,尽管我担心在这些分支中更改 spgNewHeapItem 使用错误数据类型的错误观念。根据 ac9099fc1 的 buildfarm 结果。讨论: https://postgr.es/m/3728741.1617381471@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/dfc843d465689d2c2af8b0e01c66c51ccaae2343

  • 支持 SP-GiST 中的 INCLUDE 列。这里没什么好说的:它实现了其名称所表示的功能。我们从叶子索引元组(leaf index tuples)的 nextOffset 字段中窃取了一个之前始终为零的位,用于跟踪是否存在 null 位图。否则,它的工作方式与其它索引类型的包含列(included columns)类似。Pavel Borisov,由 Andrey Borodin 和 Anastasia Lubennikova 审查,并由我进行了大量的编辑。讨论: https://postgr.es/m/CALT9ZEFi-vMp4faht9f9Junb1nO3NOSjhpxTmbm1UGLMsLqiEQ@mail.gmail.com https://git.postgresql.org/pg/commitdiff/09c1c6ab4bc5764dd69c53ccfd43b2060b1fd090

  • 清理默认值和 CHECK 约束记录的处理。Andrew Gierth 报告说,如果在查找与设置了 atthasdef 的属性匹配的 pg_attrdef 记录时找不到任何记录,则可能导致后端崩溃。AttrDefaultFetch 会对此情况发出警告,但随后会留下一个 relation tupdesc,其中包含 null "adbin" 指针,大多数地方都未对此进行防护。我们曾考虑将警告提升为错误,但如果在 relcache 加载期间抛出错误,那将非常严重:它基本上会阻止对该 relation 的任何使用。更好的做法是让加载时的行为保持为警告,然后在任何想要使用默认值但找不到它的代码路径中抛出错误。这将错误限制在表的 INSERT/UPDATE 操作的子集中,并且特别允许 pg_dump 成功。此外,我们应该修复 AttrDefaultFetch,使其不留下任何 null 指针在 tupdesc 中,因为这会制造一个未经测试的 bug 隐患。在进行过程中,将“加载时警告,仅在使用已知缺失信息时抛出错误”的相同理念应用于 CHECK 约束。CheckConstraintFetch 的逻辑与 AttrDefaultFetch 非常相似,但由于一些原因不明的原因,它在 AttrDefaultFetch 视为 WARNING 的相同情况下抛出 ERROR。使这两个函数更加相似。顺便,通过让 AttrDefaultFetch 在提取条目后对其进行排序,来摆脱 equalTupleDesc 中潜在的 O(N^2) 循环,这样 equalTupleDesc 就可以假定两个相等 tupdesc 中的条目顺序是匹配的。(CheckConstraintFetch 已经对 CHECK 约束进行了排序,但 equalTupleDesc 并未被告知。)对此进行回溯是有一定道理的,但由于只有很少的现场报告,我对此在 HEAD 中修复感到满意。讨论: https://postgr.es/m/87pmzaq4gx.fsf@news-spur.riddles.org.uk https://git.postgresql.org/pg/commitdiff/091e22b2e673e3e8480abd68fbb827c5d6979615

  • 修复 nodeResultCache.h 中丢失的 #include。根据 cpluspluscheck。 https://git.postgresql.org/pg/commitdiff/789d81de8a50d9a23cc1a3b8ea5d839246020689

  • 将 ExecInitModifyTable 中的一些操作推迟。安排按需执行某些操作,而不是在执行器启动时立即执行,因为很可能永远不需要执行它们:* 结果关系(result relations)的索引在需要时才打开。* 分区元组路由(partition tuple routing)以及子表到根表的元组转换映射(child-to-root tuple conversion map)在需要时才初始化。这在分区表的 UPDATE 操作中很有用,当只有部分分区实际接收更新时:随着分区数量的增加,节省的效果非常显著。此外,我们可以移除 ExecInitModifyTable 中关于是否设置元组路由的一些不确定性启发式方法。还移除 execPartition.c 的私有哈希表,该表跟踪 ModifyTable 节点已打开的分区。相反,使用提交 86dc90056 添加到 ModifyTable 本身的哈希。为了允许延迟计算转换映射,我们现在在所有子 ResultRelInfo 中设置 ri_RootResultRelInfo。以前我们只在某些不太明确定义的情况下设置它。这会产生用户可见的副作用,因为现在更多错误消息会引用根关系而不是某个分区(并且错误数据也以根关系的列顺序提供!)。在我看来,这是对一致性的严格改进,所以我对这个提交中可见的输出更改没有异议。从一个较大的补丁中提取,该补丁在我看来过于混乱,无法一次提交。Amit Langote,在不同时间由 Heikki Linnakangas 和我审查。讨论: https://postgr.es/m/CA+HiwqG7ZruBmmih3wPsBZ4s0H2EhywrnXEduckY5Hr3fWzPWA@mail.gmail.com https://git.postgresql.org/pg/commitdiff/c5b7ba4e67aeb5d6f824b74f94114d99ed6e42b7

  • 将 ExecInitModifyTable 中的更多操作推迟。延迟创建 INSERT 和 UPDATE 元组的投影,直到它们被需要。这在只有部分分区被实际触及时,节省了相当多的工作。与识别 UPDATE/DELETE 中的垃圾列相关的逻辑被移到另一个循环,从而可以移除对目标关系的循环;但实际上并没有改变。从一个较大的补丁中提取,该补丁在我看来过于混乱,无法一次提交。Amit Langote,在不同时间由 Heikki Linnakangas 和我审查。讨论: https://postgr.es/m/CA+HiwqG7ZruBmmih3wPsBZ4s0H2EhywrnXEduckY5Hr3fWzPWA@mail.gmail.com https://git.postgresql.org/pg/commitdiff/a1115fa0782378a8238045d238ae70cac36be8ae

  • 收紧自定义 GUC 参数的允许名称。以前我们对自定义 GUC 的名称相当宽松;只要它包含至少一个点,我们就会接受它。然而,名称中包含连字符或等号等边缘情况会导致各种功能出现问题。与其试图让世界完全安全地处理这些,不如要求自定义名称看起来像“identifier.identifier”,其中“identifier”是指 scan.l 在不加引号的情况下可以接受的东西。在此过程中,此补丁略微重构了 guc.c,使 find_option() 负责报告 GUC 未找到的情况,从而允许从其调用者中移除重复的代码。根据 Hubert Depesz Lubaczewski 的报告。不回溯,因为问题的后果似乎不值得更改稳定分支的行为。讨论: https://postgr.es/m/951335.1612910077@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/3db826bd55cd1df0dd8c3d811f8e5b936d7ba1e4

  • a1115fa07 的注释清理。Amit Langote 讨论: https://postgr.es/m/CA+HiwqEcawatEaUh1uTbZMEZTJeLzbroRTz9_X9Z5CFjTWJkhw@mail.gmail.com https://git.postgresql.org/pg/commitdiff/0d46771eaaf77ad08555cf34e421234d5943edfa

  • 从 clientcert=verify-full 测试中移除通道绑定要求。这在不支持通道绑定的旧版 OpenSSL 上会失败。由于该功能对此测试用例并非必需,因此只需将其移除,而不是使事情复杂化。根据 buildfarm。Jacob Champion 讨论: https://postgr.es/m/fa8dbbb58c20b1d1adf0082769f80d5466eaf485.camel@vmware.com https://git.postgresql.org/pg/commitdiff/a282ee68a070a8adc6e6d45e8e643769c587ecc3

  • 允许 psql 的 \df 和 \do 命令指定参数类型。当处理重载的函数或运算符名称时,不得不查看长长的匹配列表会很繁琐。让我们扩展这些命令,允许指定(输入)参数类型,从而缩小匹配结果。每个附加参数的处理方式与 \dT 的模式参数相同,并与相应的参数类型名称进行匹配。同时,修复 \dT(以及这些新选项)以识别“foo[]”表示“foo 之上的数组类型”的常规表示法,并处理后端语法允许的特殊缩写,例如“int”代表“integer”。Greg Sabino Mullane,由我进行了相当大的修改。讨论: https://postgr.es/m/CAKAnmmLF9Hhu02N+s7uAyLc5J1xZReg72HQUoiKhNiJV3_jACQ@mail.gmail.com https://git.postgresql.org/pg/commitdiff/a3027e1e7f3d3a107ecd72d3b4d6333ea2aab6a5

  • 抑制未初始化变量警告。一些通常不会产生此类警告的 buildfarm 机器报告了 e717a9a18 的问题。我认为它实际上是安全的,但移动初始化以抑制警告。 https://git.postgresql.org/pg/commitdiff/01add89454d5dc289ed3126d5de03169bdeff41b

  • 为 \df, \do 中的类型参数添加制表符补全支持。提交 a3027e1e7 中的疏忽。 https://git.postgresql.org/pg/commitdiff/d1fcbde579d440c35023baa0de7ebf27f644a314

  • 文档:更新 check_function_bodies 的文档。调整文档和描述字符串,以指出 check_function_bodies 也适用于过程(procedures)。(事后看来,它应该命名为 check_routine_bodies,但现在似乎太晚了。)Daniel Westermann 讨论: https://postgr.es/m/GV0P278MB04834A9EB9A74B036DC7CE49D2739@GV0P278MB0483.CHEP278.PROD.OUTLOOK.COM https://git.postgresql.org/pg/commitdiff/07b76833b15163c6574ea2c12d05d9a0800665e2

  • 修复 xlogprefetch.h 未包含所有必需头文件的问题。根据 cpluspluscheck。 https://git.postgresql.org/pg/commitdiff/99964c4ade468c35a3f6e248a2380a1ff67d9cd3

  • 修复提交 a4d75c86b 中的未初始化变量。*exprs != NIL 的路径将出现错误,并可能崩溃,因为 pull_varattnos 期望其最后一个参数在调用时有效。由 Coverity 发现——我们在回归测试中没有覆盖此路径。 https://git.postgresql.org/pg/commitdiff/9cb92334092fa75afc62a71243bbc1f4612ecfa4

  • 添加宏 PGWARNING,并使 PGERROR 在所有平台上可用。我们之前注意到需要处理 Windows 头文件,这些头文件提供了与 elog.h 不同的宏“ERROR”定义。事实证明 R 也想定义 ERROR 和 WARNING。PL/R 一直以一种 hacky 的方式解决这个问题,但在我们最近更改 ERROR 的数字值时,这种方式失效了。为了让他们有一个更面向未来的解决方案,我们提供了另一个宏 PGWARNING 来代替 WARNING,并始终使 PGERROR 可见,而不仅仅是在 #ifdef WIN32 时。讨论: https://postgr.es/m/CADK3HHK6iMChd1yoOqssxBn5Z14Zar8Ztr3G-N_fuG7F8YTP3w@mail.gmail.com https://git.postgresql.org/pg/commitdiff/d7cff12c4c035b7cf12bb8454824f48f13018730

Michaël Paquier 提交

  • 重构所有执行连接检查的 TAP 测试套件。此提交重构了更多 TAP 测试,以适应 PostgresNode 中最近引入的 connect_ok() 和 connect_fails(),这些是在 0d1a3343 中引入的。这改变了以下测试套件使用相同的代码路径进行连接检查:- Kerberos - LDAP - SSL - Authentication 这些例程已扩展为能够处理可选参数,这些参数根据每个套件的需求进行设置,例如:- 自定义 SQL 查询。- 预期的 stderr 匹配模式。- 预期的 stdout 匹配模式。新设计是可扩展的,可以添加更多参数,并且未来有一些关于这些例程的计划,包括基于后端日志内容的检查。作者:Jacob Champion,Michael Paquier 讨论: https://postgr.es/m/d17b919e27474abfa55d97786cb9cfadfe2b59e9.camel@vmware.com https://git.postgresql.org/pg/commitdiff/c50624cdd248c13b4ba199f95e24c88d2cc8a097

  • 修复 collationcmds.c 中的拼写错误。由 51e225d 引入。作者:Anton Voloshin 讨论: https://postgr.es/m/05477da0-703c-7de7-998c-5879738e8f39@postgrespro.ru https://git.postgresql.org/pg/commitdiff/9f6f1f9b8e61f9ce47e1936fc68c21a4a8d6722c

  • 更改 PostgresNode::connect_fails() 以永远不向下发送查询。这种失败类型类似于 c757a3da 中修复的问题,其中身份验证失败与 psql 将命令推送到其通信管道结合,会导致测试失败。此例程旨在失败,因此发送查询无论如何都意义不大。根据 buildfarm 成员 gaur 和 hoverfly 的报告,基于 Tom Lane 的分析和修复。讨论: https://postgr.es/m/513200.1617634642@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/6d41dd045ada28ee14182112fc4cf50fb3879d28

  • 修复 SSL 和 Kerberos 测试中的一些问题。c50624c 中最近的重构意外地破坏了 Kerberos 测试中查询后检查的一部分,因此将该功能恢复回来。一些不活动的 SSL 测试的参数顺序不正确,如果运行它们会导致失败。作者:Jacob Champion 讨论: https://postgr.es/m/4f5b0b3dc0b6fe9ae6a34886b4d4000f61eb567e.camel@vmware.com https://git.postgresql.org/pg/commitdiff/5a71964a832febfee23cedc3bb354049d6ca78a7

  • 通过 log_connections 添加有关已验证身份的信息。“已验证身份”(authenticated identity)是身份验证方法用来标识特定用户的字符串。在许多常见情况下,这与 PostgreSQL 用户名相同,但对于某些第三方身份验证方法,所使用的标识符可能在服务器存储它之前被缩短或以其他方式转换(例如,通过 pg_ident 用户映射)。为了帮助管理员查看谁实际与系统交互,此提交添加了在身份验证成功时将原始身份存储在后端 Port 中的功能,并在启用 log_connections 时生成日志条目。生成的日志条目大致如下(其中本地用户“foouser”连接到数据库作为名为“admin”的数据库用户):LOG:connection received: host=[local] LOG:connection authenticated: identity="foouser" method=peer (/data/pg_hba.conf:88) LOG:connection authorized: user=admin database=postgres application_name=psql Port->authn_id 根据身份验证方法设置: bsd:PostgreSQL 用户名(即本地用户名) cert:客户端的主体 DN gss:用户主体 ident:远程用户名 ldap:最终绑定 DN pam:PostgreSQL 用户名(即 PAM 用户名) password(以及所有 pw-challenge 方法):PostgreSQL 用户名(即 RADIUS 用户名) sspi:如果 compat_realm=1,则为下级(SAM 兼容)登录名,否则为用户主体名称(User Principal Name) trust 身份验证方法不设置已验证身份。clientcert=verify-full 也不设置。Port->authn_id 可用于其他目的,例如 pg_stat_activity 中的超级用户专用附加列,但这留作将来工作。PostgresNode::connect_{ok,fails}() 已修改,允许测试使用新的 log_like 和 log_unlike 参数检查后端日志文件是否包含必需或禁止的模式。这使用了一种基于截断现有服务器日志文件的方​​法,类似于 issues_sql_like()。在 ldap、kerberos、authentication 和 SSL 测试套件中添加了测试。作者:Jacob Champion 审阅者:Stephen Frost、Magnus Hagander、Tom Lane、Michael Paquier 讨论: https://postgr.es/m/c55788dd1773c521c862e8e0dddb367df51222be.camel@vmware.com https://git.postgresql.org/pg/commitdiff/9afffcb833d3c5e59a328a2af674fac7e7334fc1

  • 移除一些索引 AM 页初始化时冗余的 memset(0) 调用。Bloom、GIN、GiST 和 SP-GiST 依赖 PageInit() 来初始化页面内容,该例程用零填充 BLCKSZ 大小的整个页面,包括特殊空间。这些索引 AM 使用额外的 memset() 调用将零填充到页面特殊空间,甚至整个页面,这是不必要的,因为 PageInit() 已经完成了这项工作,所以让我们移除它们。GiST 没有进行这种额外的调用,但自 6236991 以来,它注释掉了执行此操作的系统调用。在进行此操作时,还为 SP-GiST 移除了一个 MAXALIGN(),因为 PageInit() 已经处理了它。这使得所有索引 AM 的整个页面初始化逻辑更加一致。作者:Bharath Rupireddy 审阅者:Vignesh C、Mahendra Singh Thalor 讨论: https://postgr.es/m/CALj2ACViOo2qyaPT7krWm4LRyRTw9kOXt+g6PfNmYuGA=YHj9A@mail.gmail.com https://git.postgresql.org/pg/commitdiff/4c0239cb7a7775e3183cb575e62703d71bf3302d

  • 修复 Windows 主机上连接测试的一些问题。此测试集依赖的日志文件截断,以确保连接尝试与预期的后端日志模式匹配,但失败了,正如 buildfarm 成员 fairywren 所报告的。而不是截断,执行日志文件的轮换并重新启动节点。这将确保每次测试的连接尝试数据都是唯一的。讨论: https://postgr.es/m/YG05nCI8x8B+Ad3G@paquier.xyz https://git.postgresql.org/pg/commitdiff/c7578fa64019f27edc31261ea49066a4b2569a6c

  • 修复文档和代码注释中的拼写和语法错误。注释修复应用于 HEAD,文档改进应用于需要回溯的版本。作者:Justin Pryzby 讨论: https://postgr.es/m/20210408164008.GJ6592@telsasoft.com 回溯至:9.6 https://git.postgresql.org/pg/commitdiff/609b0652af00374b89411ea2613fd5bb92bca92c

Peter Eisentraut 提交

Álvaro Herrera 提交

Fujii Masao 提交

  • 在启动进程退出时关闭事务跟踪。Maxim Orlov 报告说,备用服务器(standby server)的关闭可能导致以下断言失败。此问题的原因是,当关闭导致启动进程退出时,恢复时期的事务跟踪(recovery-time transaction tracking)即使已初始化,也不会被关闭,并且被跟踪的事务持有的某些锁无法被释放。在这种情况下,如果调用了其他进程,并且启动进程使用的 PGPROC 条目被分配给它,它会发现这些未释放的锁并导致初始化期间的断言失败。TRAP: FailedAssertion("SHMQueueEmpty(&(MyProc->myProcLocks[i]))" 此提交通过使启动进程关闭事务跟踪并释放所有锁来修复此问题。回溯到所有支持的分支。报告者:Maxim Orlov 作者:Fujii Masao 审阅者:Maxim Orlov 讨论: https://postgr.es/m/ad4ce692cc1d89a093b471ab1d969b0b@postgrespro.ru https://git.postgresql.org/pg/commitdiff/ad8b674922eb70dc5cd02951dd82fe2c4c37c80a

  • 添加函数以记录指定后端进程的内存上下文。提交 3e98c0bafb 添加了 pg_backend_memory_contexts 视图来显示后端进程的内存上下文。但是,其目标进程仅限于访问视图的后端。因此,在调查其他后端进程的本地内存膨胀时,这并不太方便。为了改善这种情况,此提交添加了 pg_log_backend_memory_contexts() 函数,该函数请求记录指定后端进程的内存上下文。还可以通过调试器调用 MemoryContextStats(TopMemoryContext) 来收集此信息。但在某些环境中无法使用此技术,因为那里没有调试器。因此,pg_log_backend_memory_contexts() 使我们能够更轻松地查看指定后端的内存上下文。只有超级用户可以请求记录内存上下文,因为允许任何用户以不受限制的比率发出此请求会导致大量日志消息,并可能导致拒绝服务。收到请求后,在下一个 CHECK_FOR_INTERRUPTS() 时,目标后端会以 LOG_SERVER_ONLY 级别记录其内存上下文,以便这些内存上下文出现在服务器日志中,但不会发送给客户端。它每个内存上下文记录一条消息。因为如果它将所有内存上下文缓冲到 StringInfo 以便作为一条消息记录,这可能需要非常大的缓冲区,并可能导致 OOM 错误,因为后端可能存在大量内存上下文。当后端进程消耗大量内存时,记录其所有内存上下文可能会耗尽可用磁盘空间。为防止这种情况,此补丁现在将每个父项下的子上下文数量限制为 100。与 MemoryContextStats() 一样,它假设在实际情况下,日志会很长,通常是在同一父上下文下有大量同级节点;而看到超过 100 个单独同级节点的详细信息不会有太大的附加调试价值。在讨论中还有另一个提议的补丁,该补丁添加了一个函数,该函数返回指定后端的内存上下文作为结果集,而不是记录它们。但是,由于需要解决几个问题,因此此补丁未包含在此提交中。感谢 Tatsuhito Kasahara、Andres Freund、Tom Lane、Tomas Vondra、Michael Paquier、Kyotaro Horiguchi 和 Zhihong Yu 的讨论。增加目录版本。作者:Atsushi Torikoshi 审阅者:Kyotaro Horiguchi、Zhihong Yu、Fujii Masao 讨论: https://postgr.es/m/0271f440ac77f2a4180e0e56ebd944d1@oss.nttdata.com https://git.postgresql.org/pg/commitdiff/43620e328617c1f41a2a54c8cee01723064e3ffa

  • 修复 pgstat.c 中的拼写错误。由 9868167500 引入。作者:Vignesh C 讨论: https://postgr.es/m/CALDaNm1DqgaLBAJrtGznKk1sR1mH-augmp7LfGvxWwTUhah+rg@mail.gmail.com https://git.postgresql.org/pg/commitdiff/f5d94e405e17a49487672316610630be2f9d0bb7

  • 如果在 wal_level=minimal 下生成的 WAL 被找到,则停止归档恢复。以前,如果启用了 hot standby,归档恢复在找到 wal_level=minimal 生成的 WAL 时会以错误退出。但是,如果禁用了 hot standby,它只会报告警告并继续。这可能导致数据丢失或正常操作期间出错。发出警告,但用户很容易错过警告,直到遇到实际错误才意识到这种情况的严重性。为了改善这种情况,此提交更改了归档恢复,使其在找到 wal_level=minimal 生成的 WAL 时,无论 hot standby 的设置如何,都会以 FATAL 错误退出。这使用户能够很快意识到这种情况的严重性。如果归档恢复从 wal_level 更改为 minimal 之前采取的基线备份开始,则会抛出 FATAL 错误。当归档恢复因错误而退出时,如果用户拥有 wal_level 设置为高于 minimal 的基线备份,他们可以通过从该较新备份开始归档恢复来恢复数据库。但请注意,如果不存在这样的备份,则没有简单的方法来完成归档恢复,这可能导致数据库服务器无法启动,并且用户可能丢失整个数据库。此提交将此风险的注意事项添加到文档中。即使在数据库服务器无法启动的情况下,以前通过仅禁用 hot standby,用户可以避免归档恢复期间的错误,强制启动服务器并从中挽救数据。但请注意,此提交完全禁用了此过程。作者:Takamichi Osumi 审阅者:Laurenz Albe、Kyotaro Horiguchi、David Steele、Fujii Masao 讨论: https://postgr.es/m/OSBPR01MB4888CBE1DA08818FD2D90ED8EDF90@OSBPR01MB4888.jpnprd01.prod.outlook.com https://git.postgresql.org/pg/commitdiff/9de9294b0c4dac77edb80f029648afca79d14653

  • postgres_fdw:允许导入 LIMIT TO 中指定的表分区。提交 f49bcd4ef3 禁止了 postgres_fdw 导入表分区。因为所有数据都可以通过作为分区层级根节点的分区表来访问,仅导入分区表应该可以访问所有数据而无需创建额外的对象。当导入整个模式时,这是一个合理的默认行为。但是,有时用户可能希望显式导入分区表的一个分区。为了实现这一目标,此提交允许 postgres_fdw 导入表或作为其他表分区的外部表,前提是它们在 LIMIT TO 子句中被明确指定。它不改变 IMPORT FOREIGN SCHEMA 命令中自动排除任何未在 LIMIT TO 中指定的分区的行为。作者:Matthias van de Meent 审阅者:Bernd Helmle、Amit Langote、Michael Paquier、Fujii Masao 讨论: https://postgr.es/m/CAEze2Whwg4i=mzApMe+PXxCEfgoZmHGqdqQFW7J4bmj_5p6t1A@mail.gmail.com https://git.postgresql.org/pg/commitdiff/a3740c48eb2f91663c7c06c948dfcfb6493d2588

  • 修复提交 9de9294b0c 添加的测试。buildfarm 成员“drongo”和“fairywren”报告说,提交 9de9294b0c 添加的回归测试(024_archive_recovery.pl)失败了。此失败的原因是测试在没有“allows_streaming => 1”的情况下调用 $node->init(),并且这没有为 pg_basebackup 的 TCP/IP 连接添加 pg_hba.conf 条目。此提交通过在调用 $node->init() 时指定“allows_streaming => 1”来修复此问题。作者:Fujii Masao 讨论: https://postgr.es/m/3cc3909d-f779-7a74-c201-f1f7f62c7497@oss.nttdata.com https://git.postgresql.org/pg/commitdiff/8ee9b662daa6d51b54d21ec274f22a218462ad2d

  • 允许 TRUNCATE 命令截断外部表。此提交为 TRUNCATE 引入了新的外部数据包装器 API。它扩展了 TRUNCATE 命令,使其可以接受外部表作为目标进行截断,并调用该 API。此外,它还扩展了 postgres_fdw,使其能够向外部服务器发出 TRUNCATE 命令,方法是添加一个新的例程来处理该 TRUNCATE API。有关 TRUNCATE 命令中指定的选项的信息,例如 ONLY、CASCADE 等,将通过 API 传递给 FDW。要截断的外部表列表也传递给 FDW。FDW 根据这些信息截断所传递的外部表指定的外部数据源。例如,postgres_fdw 使用这些信息构建 TRUNCATE 命令并将其发出到外部服务器。为了性能,TRUNCATE 命令为属于要截断的外部表的每个外部服务器调用一次 FDW TRUNCATE 例程。作者:Kazutaka Onishi、Kohei KaiGai,由 Fujii Masao 微调。审阅者:Bharath Rupireddy、Michael Paquier、Zhihong Yu、Alvaro Herrera、Stephen Frost、Ashutosh Bapat、Amit Langote、Daniel Gustafsson、Ibrar Ahmed、Fujii Masao 讨论: https://postgr.es/m/CAOP8fzb_gkReLput7OvOK+8NHgw-RKqNv59vem7=524krQTcWA@mail.gmail.com 讨论: https://postgr.es/m/CAJuF6cMWDDqU-vn_knZgma+2GMaout68YUgn1uyDnexRhqqM5Q@mail.gmail.com https://git.postgresql.org/pg/commitdiff/8ff1c94649f5c9184ac5f07981d8aea9dfd7ac19

  • 移除 COMMIT_TS_SETTS 记录。提交 438fc4a39c 防止 WAL 重放写入 COMMIT_TS_SETTS 记录。通过此更改,PostgreSQL 核心中没有生成 COMMIT_TS_SETTS 记录的代码。我们也可以认为没有扩展使用该记录,因为我们至今没有收到任何关于 commit 438fc4a39c 修复问题的抱怨。因此,此提交移除 COMMIT_TS_SETTS 记录及其相关代码。即使没有此记录,提交时间戳功能所需的时间戳也可以从 COMMIT 记录中获得。增加 WAL 页面魔术。报告者:lx zou zoulx1982@163.com 作者:Fujii Masao 审阅者:Alvaro Herrera 讨论: https://postgr.es/m/16931-620d0f2fdc6108f1@postgresql.org https://git.postgresql.org/pg/commitdiff/08aa89b326261b669648df97d4f2a6edba22d26a

  • 避免 TRUNCATE 命令中不必要的表打开/关闭。ExecuteTruncate() 会过滤掉 TRUNCATE 命令中指定的重复表,例如在执行“TRUNCATE foo, foo”的情况下。显然,这些重复的表不需要打开和关闭,因为它们被跳过了。但以前它总是在检查表是否重复之前就打开它们,然后再关闭。也就是说,重复的表被不必要地打开和关闭。此提交将 ExecuteTruncate() 更改为在确认表不重复后才打开表,从而避免了不必要的表打开/关闭。不回溯,因为旧版本中存在的这种不必要的表打开/关闭不是 bug。作者:Bharath Rupireddy 审阅者:Amul Sul、Fujii Masao 讨论: https://postgr.es/m/CALj2ACUdBO_sXJTa08OZ0YT0qk7F_gAmRa9hT4dxRcgPS4nsZA@mail.gmail.com https://git.postgresql.org/pg/commitdiff/81a23dd87999ec9fb62554328c69c5b678612d56

Stephen Frost 已推送

  • 添加 pg_read_all_data 和 pg_write_all_data 角色。一个经常被请求的用例是拥有一个角色,该角色可以运行不受限制的 pg_dump,而无需显式授予该用户访问所有表、模式等的权限,而该角色不是超级用户。通过添加一个“pg_read_all_data”角色来解决这个问题,该角色隐式地授予该角色的任何成员对所有表、视图和序列的 SELECT 权限,以及对所有模式的 USAGE 权限。由于也可能存在需要一个具有所有对象写入访问权限的角色,因此还引入了 pg_write_all_data,它赋予用户对所有表、视图和序列的隐式 INSERT、UPDATE 和 DELETE 权限。这些角色不能直接登录,而是应该授予(GRANT)给能够登录的角色。如文档所述,如果正在使用 RLS,那么管理员可以(或可能不)选择将 BYPASSRLS 设置在这些预定义角色被授予(GRANT)到的登录角色上。审阅者:Georgios Kokolatos 讨论: https://postgr.es/m/20200828003023.GU29590@tamriel.snowman.net https://git.postgresql.org/pg/commitdiff/6c3ffd697e2242f5497ea4b40fffc8f6f922ff60

Peter Geoghegan 提交

  • 简化 VACUUM 管理的状态。重新组织 VACUUM 使用的状态结构——将相关项分组在一起,使其更易于理解。另外,停止依赖 lazy_scan_heap() 中的堆栈变量——将它们移入状态结构。通过这种方式可以简化大量相关的函数,这些函数的函数签名中存在许多不必要的冗余。切换到使用 int64 来存储通过 log_autovacuum 和 VACUUM VERBOSE 输出报告给用户的计数字段。我们以前使用 double,但这似乎没有优势。使用 int64 可以添加断言来验证堆的第一遍(修剪)遇到的 LP_DEAD 项的数量是否与第二遍遍历堆时从索引中删除的数量完全相同。这些断言将在后续提交中添加。最后,调整带有 IndexBulkDeleteResult 指针参数的函数的签名,在参数是与单个索引还是所有索引相关存在歧义的情况下。函数现在使用 ambulkdelete() 和 amvacuumcleanup()(在适用时)始终使用的惯例:接受一个可变的 IndexBulkDeleteResult 指针参数,并向调用者返回一个结果 IndexBulkDeleteResult 指针。作者:Peter Geoghegan pg@bowt.ie 审阅者:Masahiko Sawada sawada.mshk@gmail.com 审阅者:Robert Haas robertmhaas@gmail.com 讨论: https://postgr.es/m/CAH2-WzkeOSYwC6KNckbhk2b1aNnWum6Yyn0NKP9D-Hq1LGTDPw@mail.gmail.com https://git.postgresql.org/pg/commitdiff/b4af70cb210393c9c8f41643acf6b213e21178e7

  • 传播并行 VACUUM 的缓冲区访问策略。并行 VACUUM 依赖于 leader 进程的全局变量状态,该状态在 fork() 时传播给 worker。提交 b4af70cb 移除了 vacuumlazy.c 中大部分全局变量的使用,但没有考虑缓冲区访问策略状态。为修复此问题,通过共享内存传播状态。根据 elver、curculio 和 morepork 上的 buildfarm 故障。非常感谢 Thomas Munro 的线下协助。 https://git.postgresql.org/pg/commitdiff/49f49defe7c0a330cca084de5da14ccdfdafc6a3

  • 在并行 VACUUM worker 中分配访问策略。提交 49f49def 采取了完全错误的方法来解决这个问题。只需在每个单独的 worker 中分配一个本地缓冲区访问策略,而不是尝试传播状态。并行 VACUUM 最初从未传播过此状态。看起来,在提交 40d964ec 之后,这之所以能起作用,唯一的原因是它涉及到静态全局变量,这些变量根据 C 标准初始化为 0。即使在 HEAD 上,也可能需要更全面的修复。此修复至少应使 buildfarm 再次变绿。再次感谢 Thomas Munro 对此问题的持续线下协助。 https://git.postgresql.org/pg/commitdiff/f6b8f19a084ce949522fcbc940dc116c034cfc47

  • 重构 lazy_scan_heap() 循环。添加一个 lazy_scan_heap() 的辅助函数,该函数处理堆修剪和元组冻结:lazy_scan_prune()。这更清晰。lazy_scan_heap() 中每个块循环中剩余的代码现在可以被视为调用 lazy_scan_prune() 之前的代码或之后的代码,后者是现在的清晰焦点。此划分由我们现在管理状态的方式强制执行。lazy_scan_prune() 输出状态(使用自己的 struct),描述修剪和冻结后如何处理页面(例如,可见性图维护,在 FSM 中记录空闲空间)。它不接收来自 preamble 代码的任何特殊指令状态。还清晰地分离了 INDEX_CLEANUP=off 的 VACUUM 使用的逻辑与单次堆传递 VACUUM 使用的逻辑。前者现在被构造为双次 VACUUM 排除索引和堆的真空处理。后者又回到了仅在表碰巧没有索引时使用(就像在提交 a96c41fe 之前一样)。这种结构更自然,因为 INDEX_CLEANUP=off 的全部意义在于跳过本来会发生的索引和堆真空处理。但是,单次堆传递情况并未跳过任何有用的工作——它只是在表碰巧没有索引时同时执行堆修剪和堆真空处理。这两种更改都是为了准备一个即将到来的补丁,该补丁将通用 INDEX_CLEANUP=off 使用的机制。后一个补丁将允许 VACUUM 在出现问题时(例如,回绕)动态地放弃索引和堆的真空处理,以便受影响的 VACUUM 操作可以尽快完成。还修复了单次传递 VACUUM VERBOSE 输出中的一个非常旧的 bug。我们曾将通过修剪删除的元组数量报告为在处理堆的第二遍的函数中删除 LP_DEAD 项数量的直接替代。但这完全不起作用——它们是两件不同的事情。为了修复,开始跟踪修剪期间遇到的 LP_DEAD 项的总数,并在报告中使用它。单次传递的 VACUUM 将在页面修剪后立即清除该页面上的任何 LP_DEAD 项,因此修剪期间遇到的 LP_DEAD 项总数等于被清除的总数。(在 INDEX_CLEANUP=off 的情况下,它们相等,但这没关系,因为跳过索引真空处理现在是一个与单次 VACUUM 完全正交的概念。)还停止报告 VACUUM VERBOSE 输出中的 LP_UNUSED 项计数。这使得 VACUUM VERBOSE 的输出与 log_autovacuum 的输出更一致(因为它从未显示关于 LP_UNUSED 项的信息)。VACUUM VERBOSE 报告了上一个 VACUUM 留下的 LP_UNUSED 项,以及当前 VACUUM 在 HOT 链期间创建的 LP_UNUSED 项(它从未包含当前 VACUUM 第二遍堆传递留下的 LP_UNUSED 项)。这使得它作为行指针膨胀的指示器毫无用处,这可能是原来的意图。(与第一个 VACUUM VERBOSE 问题一样,此问题可能是提交 282d2a03 的疏忽,该提交添加了仅堆元组优化。)最后,停止在 VACUUM VERBOSE 输出中报告 empty_pages,并开始报告 pages_removed。这也使得 VACUUM VERBOSE 的输出与 log_autovacuum 的输出更一致(它不显示 empty_pages,但显示 pages_removed)。一个空页面与一个几乎空的页面,或者一个只剩下少量 LP_UNUSED 项的空页面,在语义上没有区别。作者:Peter Geoghegan pg@bowt.ie 审阅者:Robert Haas robertmhaas@gmail.com 审阅者:Masahiko Sawada sawada.mshk@gmail.com 讨论: https://postgr.es/m/CAH2-WznneCXTzuFmcwx_EyRQgfsfJAAsu+CsqRFmFXCAar=nJw@mail.gmail.com https://git.postgresql.org/pg/commitdiff/7ab96cf6b312cfcd79cdc1a69c6bdb75de0ed30f

  • 从 vacuumlazy.c 中移除 tupgone 特殊情况。在 heap_prune_page() 调用和紧随其后的 HeapTupleSatisfiesVacuum() 调用之间存在不一致的罕见情况下,重试 heap_prune_page() 调用。当一个并发中止的事务在两个步骤之间的极小窗口期内将元组标记为 DEAD 时,可能会发生不一致。这是 VACUUM 仍认为 DEAD 的元组在修剪后仍有存储的唯一情况。VACUUM 对 dead tuples 的定义现在是统一简单且明确的:每个页面上的 dead tuples 始终是我们在执行修剪(并在考虑冻结剩余带有元组存储的项之前)之后遇到的 LP_DEAD 行指针。消除 tupgone=true 的特殊情况,使得基于灵活、动态标准的 INDEX_CLEANUP=off 风格的索引真空跳过成为可能。以前,INDEX_CLEANUP=off 情况必须预先知道跳过索引,因为与特殊情况存在微妙的交互(参见提交 dd695979)——这本身就是一个特殊情况。现在没有特殊情况了。因此,无论何时或如何决定跳过索引真空处理,都不会影响其行为:它不会影响修剪的行为,也不会受到修剪或冻结的任何实现细节的影响。还移除 XLOG_HEAP2_CLEANUP_INFO 记录。这些记录不再是必需的,因为我们现在完全依赖堆修剪来处理恢复冲突。不再需要为修剪刚刚错过的 DEAD 元组生成恢复冲突。这也意味着堆真空现在使用与索引真空始终相同的恢复冲突策略:REDO 例程永远不需要处理 WAL 记录中的 latestRemovedXid,因为在所有情况下,来自修剪的 WAL 记录的早期 REDO 已足够。通用的 XLOG_HEAP2_CLEAN 记录类型现在被分为两个新的记录类型,以反映这种新的划分(它们被称为 XLOG_HEAP2_PRUNE 和 XLOG_HEAP2_VACUUM)。在 VACUUM 的第二次堆传递中对堆页面进行真空处理时,也停止获取超级排他锁。常规的排他锁就足够了。这是正确的,因为堆页面真空现在仅仅是将 LP_DEAD 行指针设置为 LP_UNUSED。任何其他后端都无法指向固定缓冲区中的元组,该缓冲区可能会被并发堆页面真空操作无效。堆真空现在可以被认为是概念上类似于索引真空,并且在概念上不同于堆修剪。堆修剪现在负有处理数据库逻辑内容(例如,管理事务状态信息、恢复冲突、考虑如何处理 HOT 链)的所有责任。索引真空和堆真空现在只关心从逻辑数据库的物理数据结构中回收垃圾项。由于修剪和堆页面真空 WAL 记录的更改,增加 XLOG_PAGE_MAGIC。将页面修剪页面以避免 tupgone 情况的这个想法归功于 Andres Freund。作者:Peter Geoghegan pg@bowt.ie 审阅者:Andres Freund andres@anarazel.de 审阅者:Masahiko Sawada sawada.mshk@gmail.com 讨论: https://postgr.es/m/CAH2-WznneCXTzuFmcwx_EyRQgfsfJAAsu+CsqRFmFXCAar=nJw@mail.gmail.com https://git.postgresql.org/pg/commitdiff/8523492d4e349c4714aa2ab0291be175a88cb4fc

  • 在 VACUUM 期间截断行指针数组。教会 VACUUM 截断每个堆页面的行指针数组,当页面末尾出现连续的 LP_UNUSED 行指针时——这些未使用的、未引用的项将被排除。此过程发生在 VACUUM 的第二次堆遍历期间,紧接着页面上的 LP_DEAD 行指针(在第一次传递中遇到/修剪的)被标记为 LP_UNUSED。对于某些工作负载,特别是涉及对同一表的持续范围 DELETE 和批量 INSERT 的工作负载,截断可以避免行指针膨胀。还加固了 heapam 代码,在尚未检查的地方检查页偏移量编号是否超出范围。作者:Matthias van de Meent boekewurm+postgres@gmail.com 作者:Peter Geoghegan pg@bowt.ie 审阅者:Masahiko Sawada sawada.mshk@gmail.com 审阅者:Peter Geoghegan pg@bowt.ie 讨论: https://postgr.es/m/CAEze2WjgaQc55Y5f5CQd3L=eS5CZcff2Obxp=O6pto8-f0hC4w@mail.gmail.com 讨论: https://postgr.es/m/CAH2-Wzn6a64PJM1Ggzm=uvx2otsopJMhFQj_g1rAj4GWr3ZSzw@mail.gmail.com https://git.postgresql.org/pg/commitdiff/3c3b8a4b26891892bccf3d220580a7f413c0b9ca

  • 为 VACUUM 添加循环防止故障转移。添加一个故障转移机制,当 VACUUM 检测到表的 relfrozenxid 和/或 relminmxid 很久以前时触发。VACUUM 会定期动态检查表的年龄。当故障转移触发时,VACUUM 会采取非常规措施尽快完成,以便 relfrozenxid 和/或 relminmxid 可以向前推进。VACUUM 将停止应用任何可能正在生效的基于成本的延迟。VACUUM 还会绕过任何进一步的索引清理和堆清理——它只会完成剩余的修剪和冻结。绕过索引/堆清理由提交 8523492d 启用,该提交使得可以在运行时动态触发 VACUUM 内部已使用的机制,当 INDEX_CLEANUP 关闭时。预计故障转移几乎总会在 autovacuum 中触发以防止循环,在 autovacuum 开始很久之后。但是,故障转移机制可以在任何 VACUUM 操作中触发。即使在非侵略性的 VACUUM 中,我们也可能无法推进 relfrozenxid,完成剩余的修剪和冻结似乎仍然是个好主意。之后将立即启动一个侵略性/反循环 VACUUM。请注意,随后的反循环 VACUUM 本身将触发故障转移,通常在它开始对堆进行第一次(也是唯一一次)扫描之前。故障转移由两个新的 GUC 控制:vacuum_failsafe_age 和 vacuum_multixact_failsafe_age。没有等效的 reloptions,因为它们被认为没有用。GUC 具有相当高的默认值(两者都默认为 16 亿),并且通常只用于使故障转移更快/更频繁地触发。作者:Masahiko Sawada sawada.mshk@gmail.com 作者:Peter Geoghegan pg@bowt.ie 讨论:https://postgr.es/m/CAD21AoD0SkE11fMw4jD4RENAwBMcw1wasVnwpJVw3tVqPOQgAw@mail.gmail.com 讨论:https://postgr.es/m/CAH2-WzmgH3ySGYeC-m-eOBsa2=sDwa292-CFghV4rESYo39FsQ@mail.gmail.com https://git.postgresql.org/pg/commitdiff/1e55e7d1755cefbb44982fbacc7da461fa8684e6

  • 教会 VACUUM 绕过不必要的索引清理。在堆的第一次扫描(在此场景下也是唯一的堆扫描)结束时,如果 dead_tuples 数组中精确地为零个 TID,VACUUM 则无需为每个索引调用 ambulkdelete()。发生这种情况时,根本不需要进行索引清理。索引清理仍将进行,但在实践中,当先前没有 ambulkdelete() 调用时,大多数 amvacuumcleanup() 调用通常是无操作。简而言之,当显然没有要从索引中删除的索引元组时,VACUUM 通常会设法避免索引扫描。但是,对于接近零个要删除的索引元组的情况是另一回事——执行了一轮 ambulkdelete() 调用(每个索引一个),其中每个调用都执行了完整的索引扫描。VACUUM 现在将处理“几乎为零”此类元组的情况,就像处理零个要删除的索引元组的情况一样。也就是说,它可以作为一种优化来绕过索引清理和堆清理(但不是索引清理)。VACUUM 是否绕过索引是动态确定的,基于表中最近观察到的具有一个或多个 LP_DEAD 项的堆页数(堆页中的 LP_DEAD 项在最坏情况下与每个索引中仍需删除的索引元组一一对应)。仅当 2% 或更少的表页具有一个或多个 LP_DEAD 项时,我们才跳过索引清理——作为一种优化绕过索引清理不得明显妨碍在可见性映射中设置位。作为进一步的条件,在堆第一次扫描完成时(这也是决定是否绕过的时点),dead_tuples 数组(即 VACUUM 的 LP_DEAD 项 TID 数组)不得超过 32MB。(VACUUM 还必须能够将其所有 TID 放入其 maintenance_work_mem 限制的 dead_tuples 空间中,尽管对于默认的 maintenance_work_mem 设置来说,这可能无关紧要。)这可以避免在连续的 VACUUM 操作始终几乎没有死索引元组的工作负载下,例行清理的持续时间和开销出现意外的跳跃。LP_DEAD 项的数量可能会在多个 VACUUM 操作中累积,然后最终跨过阈值,VACUUM 将执行传统的索引清理。即使如此,该优化也将避免大量基本不必要的索引清理。将来,我们可能会教会 VACUUM 逐个索引地跳过索引清理,使用一种更复杂的方法。目前,我们只考虑极端情况,在这种情况下,我们可以相当自信地认为使用简单的启发式方法进行索引清理是不值得的。当启用了 autovacuum 日志记录时,还会记录有关具有一个或多个 LP_DEAD 项的堆页数的有关信息。作者:Masahiko Sawada sawada.mshk@gmail.com 作者:Peter Geoghegan pg@bowt.ie 讨论:https://postgr.es/m/CAD21AoD0SkE11fMw4jD4RENAwBMcw1wasVnwpJVw3tVqPOQgAw@mail.gmail.com 讨论:https://postgr.es/m/CAH2-WzmkebqPd4MVGuPTOS9bMFvp9MDs5cRTCOsv1rQJ3jCbXw@mail.gmail.com https://git.postgresql.org/pg/commitdiff/5100010ee4d5c8ef46619dbd1d17090c627e6d0a

  • 消除另一个 _bt_check_unique 编译器警告。根据 Tom Lane 的投诉 讨论:https://postgr.es/m/1922884.1617909599@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/796092fb84c08162ae803e83a13aa8bd6d9b23d0

Amit Kapila 提交

David Rowley 提交

  • 修复 MSVC 的 fe-trace.c 中的编译器警告。似乎在 MSVC 中 timeval 的 tv_sec 字段是 long 类型。localtime() 接受一个 time_t 指针。由于在 MSVC 的 64 位构建中,long 即使在 64 位构建中也是 32 位,传递 long 指针而不是正确的 time_t 指针会产生编译器警告。修复此问题。评审者:Tom Lane 讨论:https://postgr.es/m/CAApHDvoRG25X_=ZCGSPb4KN_j2iu=G2uXsRSg8NBZeuhkOSETg@mail.gmail.com https://git.postgresql.org/pg/commitdiff/9bc9b4609a246ded5caf3f3d4c0013a002ba2323

  • 修复 MSVC 在 libpq_pipeline.c 中的编译器警告。DEBUG 已由 MSVC 工具链在“Debug”构建中定义。在这些系统上,无条件 #define DEBUG 会导致“DEBUG”:宏重定义警告。这里我们将 DEBUG 重命名为 DEBUG_OUPUT,并删除定义此常量的 #define。这似乎是代码中意外遗留的。讨论:https://postgr.es/m/CAApHDvqTTgDm38s4HRj03nhzhzQ1oMOj-RXFUB1pE6Bj07jyuQ@mail.gmail.com https://git.postgresql.org/pg/commitdiff/3b82d990ab784881153c0f127e4c1211e9b6065c

  • 清理分区修剪步骤生成。gen_prune_steps_from_opexps 中有一些代码不必要地检查列表是否为空,而它显然至少包含一项。这促使对 partprune.c 进行了进一步清理。此外,之前的代码可能会添加额外的、不必要的 INTERSECT 步骤。但是,这些似乎不会导致任何错误行为。gen_prune_steps_from_opexps 现在不再负责生成合并修剪步骤。相反,gen_partprune_steps_internal,它已经执行了一些合并步骤创建,现在被赋予了生成所有合并步骤的唯一责任。这意味着当我们递归调用 gen_partprune_steps_internal 时,由于它现在在生成多个步骤时总是添加一个合并步骤,我们可以只关注返回的最后一个步骤。顺便,对注释进行了大量工作,以更清楚地解释 gen_partprune_steps_internal 和 gen_prune_steps_from_opexps 的作用。这是一段相当复杂的代码,因此为新读者提供对工作原理的概述似乎是个好主意。作者:Amit Langote 报告者:Andy Fan 评审者:Kyotaro Horiguchi, Andy Fan, Ryan Lambert, David Rowley 讨论:https://postgr.es/m/CAKU4AWqWoVii+bRTeBQmeVW+PznkdO8DfbwqNsu9Gj4ubt9A6w@mail.gmail.com https://git.postgresql.org/pg/commitdiff/5ac9c4307337313bedeafc21dbbab93ba809241c

  • 加速 ScalarArrayOpExpr 的求值。具有“useOr=true”且右侧为 Const 集合的 ScalarArrayOpExpr,传统上是通过对数组进行线性搜索来求值的。当这些数组包含大量元素时,这种线性搜索可能会成为执行时间的重要组成部分。这里我们添加了一种新的 ScalarArrayOpExpr 表达式求值方法,允许通过首先构建一个包含每个元素的哈希表来求值,然后在后续求值中,我们只需探测该哈希表以确定是否存在匹配。规划器负责确定何时可以进行此优化,并通过在 ScalarArrayOpExpr 中设置 hashfuncid 来启用它。执行器仅在设置 hashfuncid 时才执行哈希表求值。这意味着并非所有情况都得到了优化。例如,包含 IN 子句的 CHECK 约束不会经过规划器,因此不会设置 hashfuncid。以后我们也许可以解决这个问题。现在不做是因为担心可能会减慢仅计算一次表达式的情况。这些情况可能很常见,例如,向带有包含 IN 子句的 CHECK 约束的表进行单行 INSERT。在规划器中,当 ScalarArrayOpExpr 的运算符有合适的哈希函数时,并且当数组中至少有 MIN_ARRAY_SIZE_FOR_HASHED_SAOP 个元素时,我们启用此功能。阈值目前设置为 9。作者:James Coleman, David Rowley 评审者:David Rowley, Tomas Vondra, Heikki Linnakangas 讨论:https://postgr.es/m/CAAaqYe8x62+=wn0zvNKCj55tPpg-JBHzhZFFc6ANovdqFw7-dA@mail.gmail.com https://git.postgresql.org/pg/commitdiff/50e17ad281b8d1c1b410c9833955bc80fbad4078

  • 改进 nodeFuncs.c 中稍微误导性的注释。nodeFuncs.c 中的一些注释,取决于您对“result”一词的解释,可能会让您认为这些注释是从别处复制粘贴而来的。如果您将“result”理解为注释所写函数的返回值,那么您就会被误导。然而,如果您正确地将“result”解释为给定节点类型的“结果类型”,那么您就不会遇到任何问题。这里我们进行一些小的清理工作,以尝试防止未来的误解。根据 Tom Lane 的措辞建议。评审者:Tom Lane 讨论:https://postgr.es/m/CAApHDvp+Bw=2Qiu5=uXMKfC7gd0+B=4JvexVgGJU=am2g9a1CA@mail.gmail.com https://git.postgresql.org/pg/commitdiff/152d33bccec7176f50be225bdbedf2e6de214e54

Etsuro Fujita 推送

Dean Rasheed 已推送

  • pgbench:生成随机排列的函数。添加了一个新函数 permute(),该函数生成任意大小的伪随机排列。这可用于随机打乱一组值以消除不必要的关联。例如,打乱来自非均匀随机分布的输出,使得所有最常见的值不会聚集在一起,从而可以进行更真实的测试。以前,hash() 被推荐用于此目的,但它存在可能改变分布的冲突,因此建议改用 permute()。Fabien Coelho 和 Hironobu Suzuki,我进行了额外的修改。由 Thomas Munro、Alvaro Herrera 和 Muhammad Usama 评审。讨论:https://postgr.es/m/alpine.DEB.2.21.1807280944370.5142@lancre https://git.postgresql.org/pg/commitdiff/6b258e3d688db14aadb58dde2a72939362310684

Heikki Linnakangas 提交

Tomáš Vondra 提交了

  • 修复处理与扩展统计信息不兼容的子句。处理不兼容子句时应用扩展统计信息的处理有点混乱——在处理兼容和不兼容子句的混合时,它有时会错误地将不兼容子句视为兼容子句,从而导致崩溃。通过重构应用所选统计信息对象的代码使其更易于理解,并添加了适当的兼容性检查来修复此问题。报告者:David Rowley 讨论:https://postgr.es/m/CAApHDvpYT10-nkSp8xXe-nbO3jmoaRyRFHbzh-RWMfAJynqgpQ%40mail.gmail.com https://git.postgresql.org/pg/commitdiff/518442c7f334f3b05ea28b7ef50f1b551cfcc23e

  • 不要从 BRIN 向位图中添加不存在的页面。bringetbitmap() 中的代码只是将由 pages_per_range 确定的整个匹配的页面范围添加到 TID 位图中,即使某些页面超出了堆的末尾。然后查询可能会因类似以下的错误而失败:ERROR: could not open file "base/20176/20228.2" (target block 262144): previous segment is only 131021 blocks 在此情况下,关系有 262093 页(131072 页和 131021 页),但我们正在尝试访问块 262144,即第三个段的第一个块。此时 _mdfd_getseg() 会发现前一个段不完整,并失败。在实践中遇到这种情况的可能性相当小,因为

  • 大多数索引使用 2 的幂次范围,因此段和页范围完美对齐(段的末尾也是页范围的末尾)。* 表大小必须恰好合适,最后一个段几乎满——距离满段不到一个页范围,因此最后一个页范围会跨越段边界。* 必须启用预取。常规的页面访问检查页面是否超出堆末尾,但预取则不会。在旧版本(12 之前)中,执行会在遇到第一个不存在的页面后停止,因此预取距离必须足以到达下一个段的第一个页面以触发问题。自 12 版本以来,只需启用预取就足够了,预取距离无关紧要。通过不将不存在的页面添加到 TID 位图中来修复。回溯补丁一直到 9.6(BRIN 索引在 9.5 中引入,但该版本已 EOL)。回溯补丁:9.6 https://git.postgresql.org/pg/commitdiff/23607a8156d595522c232ff3933d77041d3adaa1

Andres Freund 提交

Magnus Hagander 已推送

Robert Haas 提交

  • amcheck:删除重复的 XID/MXID 边界检查。提交 3b6c1259f9ca8e21860aaf24ec6735a8e5598ea0 导致在 check_tuple() 和 check_tuple_visibility() 中都执行了相同的 xmin 和 xmax 边界检查。删除重复项。同时,调整一些在此提交中被忽略的代码注释。Mark Dilger 讨论:http://postgr.es/m/AC5479E4-6321-473D-AC92-5EC36299FBC2@enterprisedb.com https://git.postgresql.org/pg/commitdiff/4573f6a9af6e232ba073392716a051ae2017d1e9

  • amcheck:修复 TOAST 指针验证的多个问题。首先,在持有缓冲区锁时不要执行数据库访问。在检查堆时,我们可以通过扫描 TOAST 索引并查找主表中 TOAST 指针中出现的值 ID 对应的块来验证 TOAST 指针是否完好。但是,在持有缓冲区锁时这样做至少有导致其他后端无限期等待的风险,并且很可能导致未检测到的无限期死锁。因此,改为创建要执行的检查列表,然后在释放锁后执行检查。其次,调整设置,以便我们不会尝试跟踪已经可以被修剪的元组的 TOAST 指针。TOAST 元组与主元组在同一时间可以被修剪,因此尝试检查它们可能会导致虚假的损坏报告,正如 buildfarm 所观察到的那样。决定要检查的元组是否可修剪的必要基础设施已由提交 3b6c1259f9ca8e21860aaf24ec6735a8e5598ea0 添加,但在此补丁之前,它实际上并未用于其预期目的。Mark Dilger,我进行了调整以避免内存泄漏。讨论:http://postgr.es/m/AC5479E4-6321-473D-AC92-5EC36299FBC2@enterprisedb.com https://git.postgresql.org/pg/commitdiff/ec7ffb8096e8eb90f4c9230f7ba9487f0abe1a9f

Bruce Momjian 已推送

Thomas Munro 推送

Noah Misch 推送

待处理补丁

Bharath Rupireddy 发送了另一个版本的补丁,用于为多重和单次插入添加表 AM,并将其用于 CTAS、REFRESH MATERIALIZED VIEW 和 COPY。

Sait Talha Nisanci 发送了另一个版本的补丁,旨在修复一个表现为 record_type_typmod_compare 崩溃的错误。

Bharath Rupireddy 发送了另外两个版本的补丁,以澄清添加非表到发布者时引起的错误消息,命名为对象的类型而不是它不是的类型(表)。

Jaime Casanova 发送了一个补丁,用于 GIN 挂起列表的清理使用 AV worker 项基础设施。

Jürgen Purtz 发送了另一个版本的补丁,用于在教程中添加一个关于架构的章节。

Andres Freund 发送了另一个版本的补丁,用于将统计信息收集器的临时存储从文件移到共享内存。

Amul Sul 发送了三个版本的补丁,用于实现 ALTER SYSTEM READ {ONLY | WRITE}。

Michaël Paquier 发送了另一个版本的补丁,使得可以使用 NSS 作为 libpq TLS 后端。

Vigneshwaran C、Amit Kapila 和 Masahiko Sawada 交换了补丁,用于为复制槽统计信息使用 HTAB。

Bruce Momjian 发送了两个版本的补丁,用于修复和澄清间隔算术中一些边缘情况的文档。

Jaime Casanova 发送了一个补丁,用于记录 BRIN 的 autosummarize 参数默认关闭的事实。

Heikki Linnakangas 发送了另一个版本的补丁,通过强制前瞻来简化 COPY FROM 解析。

Bruce Momjian 发送了另一个版本的补丁,用于实现密钥管理。

Amit Langote 发送了两个版本的补丁,以允许在跨分区更新期间批量插入。

Bertrand Drouvot 发送了三个版本的补丁,使得可以在备用服务器上进行最小的逻辑解码。

Himanshu Upadhyaya 发送了两个版本的补丁,用于修复 PREPARE TRANSACTION 和 TEMP TABLE 之间的不协调。

Thomas Munro 和 Kyotaro HORIGUCHI 交换了补丁,从 XLogReadRecord 中移除了 read_page 回调。

Justin Pryzby 发送了另外两个版本的补丁,使 pg_ls_* 显示目录和共享文件集。

Hou Zhijie、Masahiko Sawada、Amit Langote 和 Shi Yu 交换了补丁,用于修复逻辑复制中的表引用泄漏。

Fabien COELHO 和 Michaël Paquier 交换了补丁,为 psql 添加了 SHOW_ALL_RESULTS 选项。

Takamichi Osumi 发送了另一个版本的补丁,用于禁用 WAL 日志记录以加快数据加载速度。

Yugo Nagata 发送了另一个版本的补丁,用于实现增量视图维护。

Michael Banck 发送了另一个版本的补丁,用于添加一个新的 PGC_ADMINSET GUC 上下文、管理员,并添加一个 pg_change_role_settings 预定义角色。

Pavel Borisov 发送了一个补丁,用于在页面初始化期间确保页面头和页面特殊大小对齐的相同处理。两者现在都只通过断言进行适当的对齐,而不是静默地最大化对齐。调用者应向页面初始化函数提供正确最大对齐的值。

Thomas Munro 发送了另一个版本的补丁,用于为 psql 的 \watch 命令添加 PSQL_WATCH_PAGER 设置。

Tom Lane 发送了三个版本的补丁,使得 psql \df 可以根据参数选择函数。

Vigneshwaran C 发送了另一个版本的补丁,用于在 CREATE/ALTER SUBSCRIPTION 时识别发布者中缺少的发布。

Ajin Cherian 和 Amit Kapila 交换了补丁,为流式传输进行中的事务添加了缺失的文档。

Peter Smith 发送了三个版本的补丁,用于添加两阶段事务的逻辑解码。

Thomas Munro 发送了另一个版本的补丁,用于实现 WAL 预取。

Thomas Munro 和 Andrey Borodin 交换了补丁,使得所有 SLRU 缓冲区大小都可以配置。

Andrey V. Lepikhov 发送了另一个版本的补丁,用于移除 64k rangetable 限制。

Haotian Wu 发送了一个补丁,为 pg_dump/restore 添加了 --drop-cascade。

Bharath Rupireddy 发送了一个补丁,禁止 CREATE SEQUENCE 的 RESTART 选项,因为它只在 ALTER SEQUENCE 的情况下才有意义。

Andres Freund 发送了一个补丁,用于修复 InvalidateObsoleteReplicationSlots() 中的竞态条件并重新移除 SlotAcquireBehavior。

Bharath Rupireddy 发送了三个版本的补丁,用于简化 postgres_fdw 测试中的后端终止和等待逻辑。

Justin Pryzby 发送了另一个版本的补丁,将 track_activity_query_size 从之前的正确分类(Resource Usage / Memory)更改为 STATS_COLLECTOR 类别,将 log_autovacuum_min_duration 设置为 LOGGING_WHAT,将 track_commit_timestamp 设置为 REPLICATION_SENDING,并将 force_parallel_mode 更改为 DEVELOPER GUC,并从示例配置中移除它,以帮助避免用户发现此选项并更改它以期让查询更快,但又不阅读文档或理解其作用。

Justin Pryzby 发送了另一个版本的补丁,以加快 COPY FROM 到具有外部分区的分区表的进程。

Thomas Munro 发送了一个补丁,用于使用 SIGIO 检测 postmaster 死亡。

Pavel Borisov 发送了一个补丁,用于稳定分区索引的表空间测试。在进行表空间测试时,有时(非常罕见地)父表和子表的顺序会改变,导致测试失败。

Maxim Orlov 发送了另一个版本的补丁,旨在修复一个表现为大量连接/断开时 SSL 协商错误的 bug。

Andrey V. Lepikhov 发送了另一个版本的补丁,通过教会优化器考虑非分区表与分区表每个分区的分区连接,使非对称分区连接工作更有效率。这项技术导致“按子分区重构”机制发生变化。

Michaël Paquier 发送了一个补丁,将表空间路径的重新创建从 makefiles 移到 pg_regress。

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

Tom Lane 发送了一个补丁,旨在修复一个表现为类型引用泄漏的 bug,通过放弃为这些表达式节点关联一个长期的 tupdesc refcount,而是依赖于 typcache 条目一旦创建就不会消失的事实。

Rémi Lapeyre 发送了三个版本的补丁,为“COPY TO”文本格式添加了头部支持,以及相应的“COPY FROM”头部匹配模式。

Justin Pryzby 发送了另一个版本的补丁,用于 ALTER TABLE ... DETACH CONCURRENTLY,以避免创建冗余约束。

Pavel Stěhule 发送了另一个版本的补丁,为 pg_dump/pg_restore 添加了一个 --options-file 选项。

Tom Lane 发送了一个补丁,使 PGWARNING 和 PGERROR 在所有地方都可用。

Peter Geoghegan 发送了一个补丁,旨在修复一个表现为 PANIC: wrong buffer passed to visibilitymap_clear 的 bug,方法是在 lazy_vacuum_heap_rel() 中再次获取一个超级独占锁。

Ranier Vilela 发送了一个补丁,用于修复 src/backend/statistics/extended_stats.c 中未初始化的标量变量。