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

PostgreSQL 每周新闻 - 2021 年 9 月 19 日

发布于 2021-09-20,作者:PWN
PWN

PostgreSQL 每周新闻 - 2021 年 9 月 19 日

Pgpool-II 4.2.5,一个用于 PostgreSQL 的连接池和语句复制系统,已发布

Database Lab 2.5,一个用于快速克隆大型 PostgreSQL 数据库以构建非生产环境的工具,已发布

pgexporter 0.1.0,一个用于 PostgreSQL 的 Prometheus exporter,已发布

PostgreSQL 产品新闻

九月 PostgreSQL 工作岗位

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

PostgreSQL 相关新闻

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

本周 PostgreSQL 周报由 David Fetter 提供。

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

已应用补丁

Michaël Paquier 提交

  • 重构 syslogger 管道协议以使用位掩码作为其选项。之前的协议期望匹配字符集来检查发送的消息是否是最后一条,这取决于目标:- 't' 和 'f' 用于跟踪发送到 stderr 的日志的最后一条消息。- 'T' 和 'F' 用于跟踪发送到 csvlog 的日志的最后一条消息。在引入新目标时,这可以扩展更多字符,但使用位掩码更加优雅。此提交更改协议,使用位掩码作为发送到 syslogger 的日志块消息头中的一个字段,目前可用的选项如下:- log_destination 为 stderr。- log_destination 为 csvlog。- 如果消息是消息的最后一块。Sehrope 在引入 JSON 作为 log_destination 选项的补丁集中发现了此问题,但他的补丁增加了协议头的大小。此提交保持与原始大小相同的尺寸,并按需调整协议。感谢 Andrew Dunstan 和 Greg Stark 的讨论。作者:Michael Paquier,Sehrope Sarkuni 讨论:https://postgr.es/m/CAH7T-aqswBM6JWe4pDehi1uOiufqe06DJWaU5=X7dDLyqUExHg@mail.gmail.com https://git.postgresql.org/pg/commitdiff/2d77d835403a20b51e17e59f0343ddc17f431eec

  • 为 csvlog 添加了日志收集器的回归测试。这些测试已添加到 pg_ctl 的现有日志轮换测试中,该测试已对 stderr 进行了测试。为 csvlog 添加了相同的覆盖范围:- 检查 pg_current_logfile()。- 具有预期文件名的日志轮换。- 生成的日志内容。此测试已重构,以最大限度地减少添加新日志格式测试所需的工作量,从而简化了一些即将进行的工作。作者:Michael Paquier,Sehrope Sarkuni 讨论:https://postgr.es/m/CAH7T-aqswBM6JWe4pDehi1uOiufqe06DJWaU5=X7dDLyqUExHg@mail.gmail.com https://git.postgresql.org/pg/commitdiff/72b76f76161c78dd1be42592c4e5b980beef5f26

  • 修复 ECPG 连接逻辑中线程 OOM 的错误处理。当分配存储连接参数关键字和值的结构时发生内存不足失败,会破坏保存的连接集,因为失败时 pthread 互斥锁仍将被持有,并且新连接对象已被列出但已被 free()。与其仅仅解锁互斥锁(这会使连接的静态列表处于不一致状态),不如在开始测试操作之前移动连接参数结构所需的分配。这确保了在此代码路径中连接列表和连接互斥锁始终保持一致。此错误不太可能发生,但它可能以令人意想不到的方式严重破坏 ECPG 客户端,因此需要向后移植到所有版本。报告人:ryancaicse 讨论:https://postgr.es/m/17186-b4cfd8f0eb4d1dee@postgresql.org 向后移植到:9.6 https://git.postgresql.org/pg/commitdiff/fa703b317e9d261ffd34bbf5651ea29aff3ff0f0

  • 删除复制槽权限检查的代码重复。两个函数都命名为 check_permissions(),使用了相同的检查来验证用户是否具有处理复制槽所需的权限。此提交删除了重复,并将执行检查的函数移至 slot.c 以便集中管理。作者:Bharath Rupireddy 评审者:Nathan Bossart,Euler Taveira 讨论:https://postgr.es/m/CALj2ACUPpVw1u7sQocFVWrSs0n10pt_G_4NPZKSxXK6cW1dErw@mail.gmail.com https://git.postgresql.org/pg/commitdiff/026ed8efd6b1d774924937baf3209b676df4531f

  • 更新资源所有者 README 中支持的资源类型。所有支持的类型都直接列在 README 中,但已非常过时。此提交不是在 README 中列出所有支持的类型,而是添加了一个引用,以查阅 resowner.c 中的 ResourceOwnerData 以获取此信息。段落的顺序稍作调整以提高清晰度。作者:Amit Langote 讨论:https://postgr.es/m/CA+HiwqHtfT9z=4H5+F7DOy0OyNHAaVwuRcakt9b2t2uADOaiag@mail.gmail.com https://git.postgresql.org/pg/commitdiff/cae6fc2bc27cdb072693076249ce688f048ca7b7

  • 支持“postgres -C”以及运行时计算的 GUC。直到现在,postgres 的 -C 选项是在一小部分运行时计算的 GUC 初始化之前处理的,这会导致不正确的 GUC 结果,因为 GUC 机制会回退到这些参数的默认值。例如,data_checksums 可能会报告集群“关闭”,因为控制文件尚未加载。或者 wal_segment_size 会显示 16MB 的段大小,即使 initdb --wal-segsize 使用了其他值。更糟糕的是,该命令无法正确报告最近引入的 shared_memory,这需要加载 shared_preload_libraries,因为这些可能需要共享内存块。运行时 GUC 的支持有一个限制,即该操作现在允许在运行中的服务器上进行。一个值得注意的原因是,可加载库的 `_PG_init`() 函数在所有运行时计算的 GUC 都初始化之前被调用,并且不能保证在运行中的服务器上调用是安全的。对于 shared_memory_size,我们希望在不分配内存的情况下知道将使用多少内存,此限制是可以接受的。另一个有帮助的例子是 huge pages,通过引入一个新的 GUC 来评估服务器在启动之前需要的 huge pages 的数量,而无需分配大量内存。此功能受新的 GUC 标志控制,截至此更改,有四个参数被归类为运行时计算:- data_checksums - shared_memory_size - data_directory_mode - wal_segment_size 添加了一些 TAP 测试以提供一些覆盖,在 pg_checksums 的测试中使用 data_checksums。与 Andres Freund,Justin Pryzby,Magnus Hagander 等人讨论的结果。作者:Nathan Bossart 讨论:https://postgr.es/m/F2772387-CE0F-46BF-B5F1-CC55516EB885@amazon.com https://git.postgresql.org/pg/commitdiff/0c39c292077ef3ba987ced0dc6ea1c8f4f1e1f4b

  • 在 Msys 上禁用 postgres -C 的测试。在 Msys 上生成的输出不正确,因为 IPC::Run 处理输出的方式不同:原生 Perl(将 \r\n 转换为 \n)和 Msys Perl(将 \r\n 保留原样),导致此测试失败。目前,仅禁用测试以使 buildfarm 状态保持绿色。我认为长期的正确解决方案是调整 PostgresNode.pm 中的所有 `command_checks_*` 例程,使其像 psql 在使用 Msys 时那样处理输出,即在与 psql 比较之前自动丢弃 \r。根据 jacana 和 fairywren 的报告。感谢 Tom Lane 的提醒。讨论:https://postgr.es/m/1252480.1631829409@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/5adb06732d7fac8171609392ea83f18bc8f285f4

  • 澄清 pg_receivewal 关闭 WAL 段时的一些错误。pg_receivewal 在 WAL 流期间关闭的 WAL 段会根据上下文生成不正确的错误消息,因为引用 WAL 段时使用的文件名忽略了部分文件或使用的压缩方法。在这种情况下,生成的错误消息(关闭、查找或重命名失败)将与物理文件名不匹配。相同的代码路径被 pg_basebackup 使用,但它不使用部分后缀,因此不受影响。7fbe0c8 在 walmethods.c 中引入了一个回调函数,用于获取给定上下文的确切物理文件名,此提交利用它来改进这些错误消息。如果需要,将来可以将其扩展到 pg_basebackup 的更多代码路径。摘录自同一作者的更大补丁。作者:Georgios Kokolatos 讨论:https://postgr.es/m/ZCm1J5vfyQ2E6dYvXz8si39HQ2gwxSZ3IpYaVgYa3lUwY88SLapx9EEnOf5uEwrddhx2twG7zYKjVeuP5MwZXCNPybtsGouDsAD1o2L_I5E=@pm.me https://git.postgresql.org/pg/commitdiff/cddcf7842c31b4d07ca75439f6b4ddacaadbbd0d

  • 改进 pg_receivewal 中的一些检查逻辑。以下内容已改进:

  • 在任何 WAL 流循环之前从源服务器获取系统标识符。这将触发额外的检查,以确保 pg_receivewal 仍连接到具有相同系统 ID 的服务器,并具有正确的时间线。- 将 umask()(用于文件创建模式掩码)和 RetrieveWalSegSize()(用于获取 WAL 段大小)提前到初始流尝试之前。如果连接是与数据库建立的,pg_receivewal 会失败,但这些命令仍会执行,这是一种浪费。现在,在检索段大小之前完成槽的创建和删除。作者:Bharath Rupireddy 评审者:Ronan Dunklau,Michael Paquier 讨论:https://postgr.es/m/CALj2ACX00YYeyBfoi55Cy=NrP-FcfMgiYYx1qRUEib3yjCVoaA@mail.gmail.com https://git.postgresql.org/pg/commitdiff/499c9b1266395c5e4c22bd7b2cbdb7f5a64ea4fa

Amit Kapila 提交

Tom Lane 提交

  • 修复 plpgsql 中 EXIT 最外层块的错误。通常,这样使用 EXIT 会导致“函数在没有 RETURN 的情况下执行结束”。但是,如果函数不需要显式 RETURN(例如 DO 块),则不应发生这种情况。它还是发生了,因为 add_dummy_return() 忽略了这种情况。根据 Herwig Goemans 的报告。向后移植到所有支持的分支。讨论:https://postgr.es/m/868ae948-e3ca-c7ec-95a6-83cfc08ef750@gmail.com https://git.postgresql.org/pg/commitdiff/1bf2518dd67be58b207979a66db7bb7c94b93a62

  • 文档:改进 CREATE/ALTER SUBSCRIPTION 的文档。改进了一些选项的描述。修复了语法和标记上的疏忽。Peter Smith 和 Tom Lane 讨论:https://postgr.es/m/CAHut+PtPJDSOxtuMGpO2yDrRPKxcYGL4n7HqJP9HernZE=Cj+g@mail.gmail.com https://git.postgresql.org/pg/commitdiff/1882d6cca161dcf9fa05ecab5abeb1a027a5cfd2

  • 在 PQconnectdb() 成功完成时清除 conn->errorMessage。提交 ffa2e4670 和 52a10224e 导致 libpq 的连接建立函数通常会在成功连接后仍然在连接的 errorMessage 缓冲区中留下一个非空字符串。虽然这是我故意的,但更理智的思考表明这不是个好主意:该字符串会有点令人困惑。此外,这至少破坏了一个应用程序,该应用程序通过检查 errorMessage 来检查连接是否成功,而不是使用记录的 PQstatus()。让我们在成功退出时清除缓冲区,恢复 v14 之前的行为。讨论:https://postgr.es/m/4170264.1620321747@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/138531f1bbc333745bd8422371c07e7e108d5528

  • 修复 planner 错误,涉及多个 AlternativeSubPlan 副本。我们可能可以将 AlternativeSubPlan 表达式节点复制到多个地方,例如多个分区子节点。然后,我们可能在每个地方选择不同的替代方案作为最优方案。提交 41efb8340 未能考虑这种情况,因此它删除“未使用”子计划的尝试可能会删除仍在使用中的子计划。通过延迟删除逻辑直到我们检查完给定查询级别的所有 AlternativeSubPlans 来修复。 (这确实假设 AlternativeSubPlans 不会复制到其他查询级别,但可预见的将来这没问题;参见 qual_is_pushdown_safe。)根据 Rajkumar Raghuwanshi 的报告。向后移植到 v14,错误逻辑源于此。讨论:https://postgr.es/m/CAKcux6==O3NNZC3bZ2prRYv3cjm3_Zw1GfzmOjEVqYN4jub2+Q@mail.gmail.com https://git.postgresql.org/pg/commitdiff/e8638d78a2cb94efba11a5dfbf3e7cd746d0af3e

  • 在 CommitTransaction期间发送 NOTIFY 信号。以前,我们在 ProcessCompletedNotifies 中发送出站 NOTIFY 消息的信号,该函数还负责将相关消息发送给连接的客户端。因此,它必须在主循环处理完成后运行,就在变为 idle 之前。这种安排有两个大的缺点:* 既然过程允许命令内 COMMIT,那么在 COMMIT 时立即将 NOTIFY 发送到其他会话会很有用(尽管出于线路协议稳定性原因,我们仍然不应在命令结束前转发给客户端)。* 后台进程(如复制工作进程)根本不会发送 NOTIFY,因为它们从不执行客户端通信循环。我们收到了允许在复制工作进程中运行的触发器发送 NOTIFY 的请求,所以这是一个问题。为了解决这些问题,将出站 NOTIFY 信号的传输移至 AtCommit_Notify,在那里它将在 CommitTransaction 期间发生。还将其可能调用的 asyncQueueAdvanceTail 移至此处,以确保如果我们发送了许多 NOTIFY 但无人监听,我们不会使 async SLRU 膨胀。我们还可以删除 asyncQueueReadAllNotifications 的调用,从而允许 ProcessCompletedNotifies 完全消失。这是因为 commit 790026972 在 PostgresMain() 的 ProcessCompletedNotifies 调用旁边添加了 ProcessNotifyInterrupt 的调用,它本身会调用 asyncQueueReadAllNotifications,这意味着在入站通知信号与出站通知同时出现时,我们会无用地在两个事务中进行两次这样的调用。我们只需要设置 notifyInterruptPending 来确保 ProcessNotifyInterrupt 运行,然后就完成了。现有的文档建议自定义后台工作进程应调用 ProcessCompletedNotifies 以发送 NOTIFY 消息。为了避免向后分支中的 ABI break,将其减少为一个空例程而不是完全删除。删除将在 v15 中进行。尽管上述问题已经存在一段时间,但我不太愿意向后移植到比 v13 更早的版本。12 和 13 之间的相邻代码进行了相当多的更改。至少我们还需要向后移植 51004c717,并且还需要进行大量其他调整,因此收益/风险比看起来不吸引人。根据 Michael Powers 的 bug #15293(以及其他人的类似抱怨)。Artur Zakirov 和 Tom Lane 讨论:https://postgr.es/m/153243441449.1404.2274116228506175596@wrigleys.postgresql.org https://git.postgresql.org/pg/commitdiff/2e4eae87d02fef51c42c2028b65d85b9e051f9eb

  • 改进 pg_import_system_collations() 的日志消息。pg_import_system_collations() 在报告它未创建 pg_collation 条目的区域设置("locale -a" 输出的名称)方面有点不一致。在我看来,我们应该为每个被拒绝的区域设置打印一条合适的提示消息,除非它匹配一个预先存在的 pg_collation 条目。(不过,所有这些都处于 DEBUG1 日志级别,以免在 initdb 期间产生噪音。)添加了对先前未记录的两种情况的消息:即未识别的编码和仅限客户端的编码。重新措辞了现有消息以具有一致的样式。Anton Voloshin 和 Tom Lane 讨论:https://postgr.es/m/429d64ee-188d-3ce1-106a-53a8b45c4fce@postgrespro.ru https://git.postgresql.org/pg/commitdiff/69e31d05b0a33f55aa5d9540917540f5fccb93a7

  • 不允许在后台进程中 LISTEN。可以在某些后台进程中执行用户定义的 SQL;例如,逻辑复制工作进程可以触发触发器。这打开了有人尝试在 such context 中执行 LISTEN 的可能性。但由于只有常规后端进程会调用 ProcessNotifyInterrupt,因此实际上不会收到任何消息,从而注册的监听器会阻止消息队列被清理。最终 NOTIFY 将停止工作,这是不好的。也许有一天会有人发明一种基础设施来使在后台进程中监听真正有用。在此之前,禁止这样做。向后移植到 v13,我们在其中引入了 MyBackendType 变量。没有这个变量的实现检查会困难得多,而且似乎不值得麻烦。讨论:https://postgr.es/m/153243441449.1404.2274116228506175596@wrigleys.postgresql.org https://git.postgresql.org/pg/commitdiff/1316be28664f1834ac091113217537101331bdf3

  • 删除 rangetable 大小的任意 64K 或左右的限制。到目前为止,查询的 rangetable 大小受到 INNER_VAR 等常量的限制,这些常量不能等于任何实际的 rangetable 索引。65000 肯定足够任何人使用,并且它仍然比我们可以实际处理的连接数大几个数量级。但是,我们需要为每个由查询处理(或可能处理)的子分区分配一个 rangetable 条目。拥有几千个分区的查询越来越现实,因此即使还没有到那个时候,限制成为问题的日子也在不远了。因此,让我们提高限制。此补丁不是简单地增加 INNER_VAR 等的值,而是采取将其设为小的负值的方法,这样 rangetables 理论上可以达到 INT_MAX 的长度。补丁的大部分内容是改变 Var.varno 和一些相关的变量从“Index”(无符号整数)到普通的“int”。这基本上是装饰性的,实际影响很小,除了帮助调试器很好地打印其值。因此,我只费力更改了可能实际看到 INNER_VAR 等的地方,而解析器和大部分规划器不包含这些。我们必须小心处理那些对 varnos 进行小于/大于比较的地方,但除了 IS_SPECIAL_VARNO 宏本身之外,这样的地方非常少。一个显著的副作用是,虽然以前可以将 INNER_VAR 等添加到 Bitmapset,但现在会出错。我不认为将这些假 varnos 包含在真实 varnos 的位图集中会有任何错误的可能性,所以我认为这都是有益的。虽然这会影响 outfuncs/readfuncs,但我认为不需要 catversion 升级,因为存储的规则永远不会包含具有这些假 varnos 的 Var。Andrey Lepikhov 和 Tom Lane,在 Peter Eisentraut 的建议之后 讨论:https://postgr.es/m/43c7f2f5-1e27-27aa-8c65-c91859d15190@postgrespro.ru https://git.postgresql.org/pg/commitdiff/e3ec3c00d85bd2844ffddee83df2bd67c4f8297f

  • 修复 EXPLAIN 以处理 SEARCH BREADTH FIRST 查询。SEARCH BREADTH FIRST 的重写转换会生成一个 FieldSelect,该 FieldSelect 作用于类型为 RECORD 的 Var,其中 Var 引用递归联合的工作表输出。EXPLAIN VERBOSE 未能处理这种情况,因为它只期望此类 Var 出现在 CteScans 中,而不是 WorkTableScans 中。修复此问题,并添加一些测试用例来练习 EXPLAIN 在 SEARCH 和 CYCLE 查询上的使用。原则上,这个疏忽是一个旧错误,但似乎在没有 SEARCH BREADTH FIRST 的情况下无法达到这种情况,因为解析器在尝试手动创建此类引用时会失败。所以今天我只会修补 HEAD/v14。也许有一天我们会发现此补丁的代码部分需要进一步向后移植。根据 Atsushi Torikoshi 的报告。讨论:https://postgr.es/m/5bafa66ad529e11860339565c9e7c166@oss.nttdata.com https://git.postgresql.org/pg/commitdiff/3f50b82639637c9908afa2087de7588450aa866b

  • 修复 pull_varnos 以处理转换后的 PlaceHolderVars。提交 55dc86eca 更改了 pull_varnos 以(如果可能)使用 PlaceHolderVar 的关联 ph_eval_at。但我遗漏了一个细微之处:我们可能正在查看子 appendrel 的 qual 或 tlist 中的 PHV,在这种情况下,我们需要计算一个 ph_eval_at 值,该值已像 PHV 本身一样被转换(参见 adjust_appendrel_attrs)。幸运的是,PlaceHolderInfo 中有足够的信息来执行此类转换,而无需额外的外部数据,因此我们不需要对 planner API 进行另一轮丑化。这有点复杂,但由于这是一个很难触及的边界情况,我对在这里增加周期性不怎么担心。根据 Jaime Casanova 的报告。向后移植到 v12,与之前的提交相同。讨论:https://postgr.es/m/20210915230959.GB17635@ahch-to https://git.postgresql.org/pg/commitdiff/a21049fd3f64518c8a7227cf07c56f2543241db2

  • 文档:修复拼写错误。“PGcon”应为“PGconn”。D. Frey 注意到。讨论:https://postgr.es/m/163191739352.4680.16994248583642672629@wrigleys.postgresql.org https://git.postgresql.org/pg/commitdiff/d5eeb51bc053d75f647136026de522d6ee3bf725

Andres Freund 提交

Peter Eisentraut 提交

Daniel Gustafsson 提交

Fujii Masao 提交

Peter Geoghegan 提交

  • pageinspect:使页面删除的 elog 消息不那么啰嗦。提交 e5d8a999 添加了 elog 来报告已删除 nbtree 页面上存储的事务 ID 的值,该提交教会了页面删除存储完整的 64 位 XID。在进一步反思时,它似乎非常啰嗦,因此将其 elevel 从 NOTICE 降低到 DEBUG2。作者:Peter Geoghegan pg@bowt.ie 向后移植:14-,与 nbtree XID 增强功能相同。 https://git.postgresql.org/pg/commitdiff/d7897abf9e0071946e9e4e8efd2d4463607c04de