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

PostgreSQL 每周新闻 - 2021 年 6 月 21 日

发布于 2021-06-21,作者 PWN
PWN

PostgreSQL 每周新闻 - 2021 年 6 月 21 日

pgMustard 4 发布,这是一个提供性能提示的 'explain analyze' 用户界面。

psycopg2 2.9.0 发布,这是一个 PostgreSQL 的 Python 连接器。

pgAdmin4 5.4 发布,这是一个 PostgreSQL 的 Web 和原生 GUI 控制中心。

本周人物

PostgreSQL 产品新闻

六月 PostgreSQL 招聘信息

招聘

PostgreSQL 相关新闻

Planet PostgreSQL: Planet

本周 PostgreSQL 周报由 David Fetter 提供。

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

已应用补丁

Tom Lane 提交

  • 解决 mktime() 新版本中的可移植性问题。最近的 glibc 版本在 tm_isdst 与当前时区不一致时会导致 mktime() 失败;特别是在时区为 UTC 且 tm_isdst = 1 时会失败。(在我看来,这似乎与 POSIX 规定的对 struct tm 其他字段“不正确”值的处理方式完全不一致,所以我想他们会说这是故意的。)据观察,这会导致在不同时区创建的归档文件使用 pg_restore 进行恢复时出现一些外观上的问题。解决方法是:使用归档文件中的字段值进行 mktime() 调用,如果失败,则尝试使用 tm_isdst = -1 再次尝试。这将导致结果与原始时区相比有 UTC 偏移量的差异,但以前也是如此。这并不是非常关键,因为除了可能打印之外,我们不会对结果做任何事情。(总有一天,我们应该冲刷掉这整块逻辑,并在归档中记录标准格式的时间戳。但这对于向后兼容的错误修复来说是不合适的。)此外,通过让 initdb 的 build_time_t() 设置 tm_isdst = -1 而不是 0,来保护我们对 mktime() 的唯一其他使用。这种情况只有在一年四季都处于夏令时(DST)的时区中才可能出现问题;但我认为有些时区确实存在,或者将来可能会存在。根据 Wells Oliver 的报告。向所有支持的版本回溯补丁,因为它们中的任何一个都可能需要用较新的 glibc 运行。讨论:https://postgr.es/m/CAOC+FBWDhDHO7G-i1_n_hjRzCnUeFO+H-Czi1y10mFhRWpBrew@mail.gmail.com https://git.postgresql.org/pg/commitdiff/f807e3410fdfc29ced6590c7c2afa76637e001ad

  • 删除孤立的预期结果文件。这应该在 43e084197 中被删除,该提交删除了对应的 spec 文件。在把玩 isolationtester 时注意到。 https://git.postgresql.org/pg/commitdiff/ffbe9dec13599fa786ea6567df1c6a3f3ee3c673

  • 更新变体预期结果文件。这应该在 d2d8a229b 中更新,但被忽略了。根据添加它的 31a877f18,该文件旨在显示在 default_transaction_isolation = serializable 下获得的结果。我们在其他隔离测试中很大程度上已经失去了这个目标,但只要我们还有这个测试,它就应该被正确处理。在把玩 isolationtester 时注意到。 https://git.postgresql.org/pg/commitdiff/0a1e80c5c4f094087257fc4284a87e0bc7bca591

  • 删除另一个孤立的预期结果文件。aborted-keyrevoke_2.out 在添加时(在提交 0ac5ad513 中)似乎需要处理 serializable 事务模式的情况。然而,serializable 模式下的输出实际上与常规的 aborted-keyrevoke.out 文件匹配,而且据我所知,长期以来一直如此。没有必要继续携带这个变体。 https://git.postgresql.org/pg/commitdiff/f6352a0d4e437ac8bc266f77df22d064592056c9

  • 更新另一个变体预期结果文件。这应该在 533e9c6b0 中更新,但被忽略了。鉴于没有抱怨,我将不回溯补丁。 https://git.postgresql.org/pg/commitdiff/d3c878499c9d639ff06e0664d06b8c731e30c2fc

  • 改进一些与复制相关的代码中的 SQLSTATE 报告。我最初的目标是在 walrcv_connect() 失败时报告 ERRCODE_CONNECTION_FAILURE,但当我环顾四周时,我意识到编写这段代码的人认为 errcodes 是纯粹可选的。这与我对我们项目策略的理解不符。因此,确保在 (a) 级别为 ERROR 或更高,并且 (b) 不可能被认为是内部逻辑错误的每个 ereport 中都提供 errcode。还修复了一些非常可疑的现有 errcode 分配。虽然这不符合政策,但它在很大程度上是表面上的,因为这些情况很少能报告给应用程序。所以我认为没有必要回溯补丁。讨论:https://postgr.es/m/2189704.1623512522@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/6b787d9e32005867ee3660d1ea20f447810a403d

  • 修复 ExecuteQuery 中错误后的 plancache refcount 泄漏。将 plancache 中的计划放入 Portal 时,不应该冒险在 GetCachedPlan 和 PortalDefineQuery 之间抛出错误;如果发生这种情况,GetCachedPlan 增加的计划 refcount 将会泄漏。我在重构 9dbf2b7d7 中的代码时打破了这条规则。除了某些内存泄漏外,没有明显的后果,而且由于没有人可能多次连续触发相关的错误条件,所以我们没有注意到也就不足为奇了。尽管如此,这是一个错误,所以重新安排操作顺序以消除危险。在寻找 bug #17053 的更好修复方法的过程中注意到。这个错误相当老了,所以回溯到所有支持的分支。 https://git.postgresql.org/pg/commitdiff/131ea3e908d3c97a2fe1ab25cce5046dd5cb905f

  • 集中处理实用语句的保护性复制逻辑。在“简单查询”代码路径中,解析分析或执行实用语句可以随意修改语句的节点树,因为之后就会被丢弃,这是可以接受的。然而,如果节点树在计划缓存中,则不行,因为它会被后续执行损坏。到目前为止,我们通过让各个实用语句函数在修改树时调用 copyObject() 来处理这个问题。但这容易遗漏。Charles Samborski 的 Bug #17053 表明 CREATE/ALTER DOMAIN 没有遵守这条规则,并且在从计划缓存重复执行时可能会崩溃。在向后分支中,我们将只为该问题应用一个狭窄的临时修复,但在 HEAD 中,似乎有必要采取更原则性的修复方法,以防止将来出现其他类似错误的可能性。因此,我们将 copyObject 的责任从子节点提升到 ProcessUtility,从而确保所有实用语句类型都执行此操作。此外,修改 ProcessUtility 的 API,以便其调用者可以告知它是否需要复制步骤。事实证明,在所有情况下,直接调用者都知道节点树是否是临时的,因此这不涉及大量的代码调整。通过这种方式,虽然我们在从缓存执行的代码路径中由于有时复制不会被改变的节点树而损失了一些性能,但我们在简单查询代码路径中通过不复制丢弃的节点树而获得了一些性能。足够复杂的语句几乎肯定会被复制,因此在缓存代码路径中的损失应该不大。(请注意,整个问题仅适用于实用语句。可优化语句没有这个问题,因为我们很久以前就让执行器将 Plan 树视为只读。也许有一天我们也会让实用语句的执行表现得一样,但我对此不抱希望。)讨论:https://postgr.es/m/931771.1623893989@sss.pgh.pa.us 讨论:https://postgr.es/m/17053-3ca3f501bbc212b4@postgresql.org https://git.postgresql.org/pg/commitdiff/7c337b6b527b7052e6a751f966d5734c56f668b5

  • 改进 pgbench 中的版本报告。提交 547f04e73 导致 pgbench 开始打印其版本号,这似乎是个好主意,但还需要一些工作:* 打印服务器版本号(如果不同)。* 打印 PG_VERSION 字符串,而不是一些近似的重构值。此补丁复制了 psql 用于相同目的的经过充分测试的代码。讨论:https://postgr.es/m/1226654.1624036821@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/84bee9610965331d5110971d8de390a5bbe2effc

  • 修复 DROP OWNED BY 对重复的 polroles 条目时的错误行为。通常,pg_policy.polroles 数组不会重复列出同一个角色;但 CREATE POLICY 不会阻止这种情况。如果我们对一个被列出多次的角色执行 DROP OWNED BY,RemoveRoleFromObjectPolicy 要么会遇到断言失败,要么会遇到由自身更新的元组错误。重写它以正确处理重复条目,并添加一个 CommandCounterIncrement 调用来防止另一个问题。根据讨论,这里还有其他清理工作应该进行,但这似乎是最低限度的必要修复。根据 Alexander Lakhin 的 bug #17062。它一直存在问题,所以回溯到所有支持的分支。讨论:https://postgr.es/m/17062-11f471ae3199ca23@postgresql.org https://git.postgresql.org/pg/commitdiff/d21fca084356946664bfce19d66d2df2bb873cbd

  • 为 v14 中添加的 libpq 功能提供特性测试宏。我们收到一个请求,希望提供一种在编译时测试新管道功能可用性的方法。更广泛地说,通过 #ifdef 来测试所有新的 libpq API 功能似乎是个好主意。人们一直使用 pg_config.h 的版本来做到这一点;但在越来越多见的服务器版本和 libpq 版本不同的情况下,它更可能代表服务器版本而非 libpq 版本。如果 libpq-fe.h 本身是关于它提供哪些功能的真实来源,那会更安全。因此,我们建立一项政策,从 v14 开始,当我们向 libpq-fe.h 添加新的 API 时,将添加一个合适的 feature-is-present 宏。(为 v14 回溯应用此政策似乎意义不大,但对于 v14 来说还不算太晚。)Tom Lane 和 Alvaro Herrera,根据 Boris Kolpackov 的建议。讨论:https://postgr.es/m/boris.20210617102439@codesynthesis.com https://git.postgresql.org/pg/commitdiff/6991e774e0304f5ef488cf1ae4fa79578b6ae3d5

  • 稳定化由提交 f61db909d 添加的测试用例。Buildfarm 成员 ayu 和 tern 有时会显示与预期不同的查询计划。我之前一直无法重现这一点,但今天终于明白了。如果存在并发的开放事务(可能是 buildfarm 中的 autovacuum 运行,但也可以手动安排),那么由几行之前的 DELETE 删除的行的索引条目不会立即被杀死,导致规划器对 ft2.c1 的极值估计发生变化,从而将“c1 > 1100”的行数估计改变到足以将连接计划从 nestloop 更改为 hash。为了修复,将查询条件更改为“c1 > 1000”,无论是否存在并发开放事务,都会优先选择 hash 计划。由于此 UPDATE 被调整为无操作,因此其他方面没有变化。报告:https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=ayu&dt=2021-06-09%2022%3A45%3A48 报告:https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=ayu&dt=2021-06-13%2022%3A38%3A18 报告:https://buildfarm.postgresql.org/cgi-bin/show_log.pl?nm=tern&dt=2021-06-20%2004%3A55%3A36 https://git.postgresql.org/pg/commitdiff/5843659d091bfb6f2c60e010ea1fd00e55ee6ada

Michaël Paquier 提交

Bruce Momjian 已推送

Álvaro Herrera 提交

Noah Misch 推送

Amit Kapila 提交

Alexander Korotkov 提交了

Peter Geoghegan 提交

  • 移除 VACUUM 状态中不必要的字段。Bugfix 提交 5fc89376 有效地将 lazy_truncate_heap() 的全局状态结构中的 lock_waiter_detected 字段变成了私有状态。通过将结构字段替换为局部变量来完成此操作。 https://git.postgresql.org/pg/commitdiff/958cfbcf2dd338e3179c2d8a35f48bde020eba60

  • 支持 VACUUM 禁用索引绕过。通用化 INDEX_CLEANUP VACUUM 参数(以及对应的 reloption):将其变为三元布尔参数。它现在公开第三个选项,“auto”。“auto”选项(现在是默认值)启用提交 1e55e7d1 添加的“绕过索引 vacuuming”优化。“VACUUM (INDEX_CLEANUP TRUE)”被重新定义为再次使 VACUUM 简单地执行任何需要的索引 vacuuming,而不管在目标堆关系的第一扫描中遇到的死元组数量有多少(除非为零)。这为用户提供了一种选择退出“绕过索引 vacuuming”优化的方法,如果出于任何原因有必要的话。它也预计会被 PostgreSQL 开发者不时用作测试选项。“VACUUM (INDEX_CLEANUP FALSE)”与以前一样:它强制禁用索引 vacuuming 和索引清理。预计在 PostgreSQL 中使用不多

  • 提交 1e55e7d1 添加的故障安全机制以更简单的方式解决了相同的问题。现在可以将 INDEX_CLEANUP 视为测试和兼容性选项。作者:Peter Geoghegan pg@bowt.ie 审阅者:Masahiko Sawada sawada.mshk@gmail.com 审阅者:Justin Pryzby pryzby@telsasoft.com 讨论:https://postgr.es/m/CAH2-WznrBoCST4_Gxh_G9hA8NzGUbeBGnOUC8FcXcrhqsv6OHQ@mail.gmail.com https://git.postgresql.org/pg/commitdiff/3499df0dee8c4ea51d264a674df5b5e31991319a

Andrew Dunstan 推送

Heikki Linnakangas 提交

  • 修复了关于 WAL 文件搜索位置的过时注释。自提交 c24dcd0cfd 以来,我们一直使用 pg_pread() 读取 WAL 文件,这不会改变搜索位置(除非我们回退到 src/port/pread.c 中的实现)。相应地更新注释。向后移植到:12,在那里我们开始使用 pg_pread() https://git.postgresql.org/pg/commitdiff/d0303bc8d2670d11c9df9220aa08a2c33529e100

  • 整理 `GetMultiXactIdMembers()` 在错误时的行为。其中一个错误路径使 `*members` 未初始化。这不是一个活动 bug,因为大多数调用者在函数返回 -1 时不检查 `*members`,但让我们保持整洁。一个调用者 heap_lock_tuple() 在 `members != NULL` 时会 pfree(members),但据我所知,它从不传递无效的 'multi' 值,因此不应该到达该错误情况。调用者在期望上也有些不一致。heap_lock_tuple() 在 `members` 非 NULL 时 pfree 数组,其他调用者在 `nmembers >= 0` 时 pfree,还有些在 `nmembers > 0` 时 pfree。这也不是一个活动 bug,因为函数永远不应该返回 0,但添加一个 Assert 以使其更清晰。我暂时保留了调用者。我还移动了设置 `*nmembers` 的行。它以前没有错,但我喜欢将其放在 'return' 语句旁边,以使其清楚在返回时它总是被设置。另外,为了简洁并与紧随其后的类似 if 块保持一致,删除了一个在 ereport(ERROR) 之后的不可达返回语句。作者:Greg Nancarrow,附加更改由我完成。向后移植到:9.6,所有支持的版本 https://git.postgresql.org/pg/commitdiff/d24c5658a80c8f5037e9e1948de311d3f3350f12

Tomáš Vondra 提交了

  • 修复将数据复制到带有 FDW 批处理的槽中。提交 b676ac443b 优化了对外表进行批量插入的元组槽处理,使得槽只初始化一次并在所有批次中重用。然而,数据是在初始化之后才复制到槽中的,当槽被重用时会插入重复的值。通过将 ExecCopySlot 移到 init 分支之外来修复。现有的 postgres_fdw 测试未能捕获这一点,因为它们在没有唯一索引的外表中插入数据,然后仅检查插入的行数。这添加了一个新的测试,包含唯一索引和插入值检查。报告人:Alexander Pyhalov 讨论:https://postgr.es/m/7a8cf8d56b3d18e5c0bccd6cd42d04ac%40postgrespro.ru https://git.postgresql.org/pg/commitdiff/99cea49d6525e30bc3768e4ffb95377e7584dea1

Fujii Masao 提交

待处理补丁

Amit Khandekar 发送了一个 WIP 补丁,允许在 worker 进程中使用子事务。

Bertrand Drouvot 发送了另一个版本的补丁,允许在 standbys 上进行逻辑解码。

Thomas Munro 发送了另一个版本的补丁,为 index-only scan 使用 tuple 级 SIREAD 锁,并在可能时跳过 btree 页上的 SIREAD 锁。

Andrew Dunstan 发送了另一个版本的补丁,旨在修复一个错误,该错误表现为在更改具有默认值的外部表列类型时出现段错误。

Tomáš Vondra 发送了另一个版本的补丁,使用扩展统计信息来改进 join 估计。

Bharath Rupireddy 发送了另一个版本的补丁,以移除 pg_wait_for_backend_termination()。

Fabien COELHO 发送了另一个版本的补丁,将 psql 中的 echo 系统整合到其自己的函数中。

Yugo Nagata 和 Fabien COELHO 交换了 pgbench 的补丁,确保仅在请求时才计算和存储 conn_duration。

Jehan-Guillaume de Rorthais 发送了一个 PoC 补丁,用于在 log_statement_stats=on 时将等待事件跟踪到日志文件。

Yugo Nagata 和 Fabien COELHO 交换了补丁,以避免 pgbench 中因跳过的事务而导致的卡住状态。

Jacob Champion 和 Daniel Gustafsson 交换了补丁,以支持 NSS 作为 libpq TLS 后端。

Dilip Kumar 和 Amit Langote 交换了补丁,旨在修复一个错误,该错误表现为解码具有 toast 的投机插入时内存泄漏。

Yugo Nagata 和 Fabien COELHO 交换了补丁,旨在修复 pgbench 中出现的“初始连接时间”为负数的错误。

Takamichi Osumi 和 Amit Kapila 交换了补丁,以修复在锁定 [user] catalog 表、2PC 和逻辑复制之间的一个不适宜之处。

Justin Pryzby 和 Michaël Paquier 交换了补丁,为 WAL 压缩添加了更多选项。

Ranier Vilela 发送了另一个版本的补丁,使对 ProcArray 的访问更有效。

David Fetter 发送了一个补丁,在回归测试中使用适当的单数。

Alexander Pyhalov 发送了另一个版本的补丁,以实现 case 表达式下推。

Ranier Vilela 发送了一个补丁,以修复 ecpg 中未以 null 结尾的缓冲区。

Fabien COELHO 和 Yugo Nagata 交换了补丁,旨在修复 pgbench 日志记录中出现的错误。

Dmitry Dolgov 发送了另外两个版本的补丁,以防止 ArrayExpr 中的所有元素错乱。

Dilip Kumar 发送了一个补丁,使 CREATE DATABASE 完全 WAL 记录,因此发出该命令不再强制执行检查点。

Ajin Cherian 发送了另一个版本的补丁,为 CREATE_REPLICATION_SLOT 命令添加了一个设置两阶段的选项,并在 pg_recvlogical 中支持两阶段解码。

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

Daniel Gustafsson 发送了一个补丁,在文档中使用更正确和更现代的 TLS/SSL 而不是 SSL。

Thomas Munro 发送了另一个版本的补丁,用于在共享内存中跟踪关系大小,为 smgrnblocks() 提供无锁快速路径,并将 fifo 更改为 lru 以扫描有效的缓存。

Kyotaro HORIGUCHI 发送了另一个版本的补丁,用于在 pg_waldump 中显示更多错误详情。

Tom Lane 发送了一个补丁,允许在 isolationtester 脚本中使用常规标识符。

Matthias van de Meent 发送了另一个版本的补丁,以修复 GetOldestNonRemovableTransactionId 中的一个错误,该错误未返回与 GlobalVisTestFor(rel) 一致的值。此外,lazy_scan_prune 存在一个不正确的假设,即 GlobalVis*Rels 的 OldestXmin 永远不会小于 vacrel->OldestXmin,这是不正确的。此假设现已修复,并已记录相关更改。

Heikki Linnakangas 发送了一个补丁,将 xlog.c 分割开,因为它变得越来越庞大。

Thomas Munro 发送了另一个版本的补丁,用于制作和使用 qsort 模板。

Amit Langote 发送了另外三个版本的补丁,以在分区键为常量时跳过分区元组路由。

Jeff Davis 发送了两个版本的补丁,以澄清复制协议的文档。

Tomáš Vondra 发送了一个 PoC 补丁,使用 count-min sketch 进行 join 基数估计。

Jeff Davis 发送了另一个版本的补丁,记录了 START REPLICATION 中的情况。

Alexander Korotkov 发送了另外三个版本的补丁,以实现 multiranges 的 UNNEST。

Vigneshwaran C 发送了另一个版本的补丁,为 PUBLICATION 添加了模式级别支持。

Amul Sul 发送了另一个版本的补丁,实现了 ALTER SYSTEM SET READ {WRITE | ONLY}。

Nitin Jadhav 发送了另一个版本的补丁,以实现启动进程进度指示器。

Matthias van de Meent 发送了另一个版本的补丁,以实现并使用索引元组属性迭代,并为 `_bt_binsrch*` 实现页级动态前缀截断。

Mark Dilger 发送了两个版本的补丁,以选择性地在出错时禁用订阅。

Jeff Davis 发送了一个补丁,以修复 start replication identify system。

Thomas Munro 发送了另一个版本的补丁,以使用计时器实现 snapshot_too_old。

Takashi Menjo 提交了一个将 WAL 段文件映射到 PMEM 作为 WAL 缓冲区的补丁的又一次修订。

Amit Kapila 发送了另一个版本的补丁,以实现逻辑复制的行过滤。

Egor Rogov 发送了一个补丁,将范围类型的统计信息包含在 pg_stats 视图中。

Álvaro Herrera 发送了另外两个版本的补丁,以添加一个测试用例,用于废弃带有活动 walenders 的槽。

Greg Sabino Mullane 发送了另一个版本的补丁,以避免不必要地计算页面校验和。

Noah Misch 发送了一个补丁,以移除 XLogFileInit() 跳过 ControlFileLock 的能力。

David Rowley 发送了另一个版本的补丁,添加了一种新的哈希表类型,该类型具有稳定的指针。

Thomas Munro 发送了一个补丁,以适应 LLVM 13 API 的更改。