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

PostgreSQL 周刊新闻 - 2021 年 1 月 3 日

发布于 2021-01-03,作者 PWN
PWN

PostgreSQL 周刊新闻 - 2021 年 1 月 3 日

PostgreSQL 周刊新闻祝大家新年快乐!

PostgreSQL 产品新闻

Database Lab 2.1 发布,这是一个用于快速克隆大型 PostgreSQL 数据库以构建非生产环境的工具:https://postgres.ai/blog/dle-2.1-release/

一月份的 PostgreSQL 工作岗位

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

PostgreSQL 相关新闻

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

本周 PostgreSQL 周报由 David Fetter 提供。

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

已应用补丁

Jeff Davis 推送

Bruce Momjian 已推送

Fujii Masao 提交

  • postgres_fdw: 修复连接泄露。在 postgres_fdw 中,到远程服务器的缓存连接在用户映射或这些连接依赖的远程服务器被删除之前,不会被关闭,直到本地会话退出。这些连接可能会泄露。为了修复这个连接泄露问题,当 pg_foreign_server 或 pg_user_mapping 目录条目发生更改后,此提交会使 postgres_fdw 立即关闭依赖于该条目的连接(如果当前事务尚未开始使用这些连接)。否则,会将这些连接标记为无效,并在当前事务结束时关闭它们,因为在使用过程中无法在事务中间关闭它们。关闭的连接将在必要时在下次有机会时重新建立。向所有支持的分支向后移植。作者:Bharath Rupireddy 审阅者:Zhihong Yu, Zhijie Hou, Fujii Masao 讨论:https://postgr.es/m/CALj2ACVNcGH_6qLY-4_tXz8JLvA+4yeBThRfxMz7Oxbk1aHcpQ@mail.gmail.com https://git.postgresql.org/pg/commitdiff/e3ebcca843a4703938b9f40a4811f43c4b315753

Michaël Paquier 提交

Tom Lane 提交

  • 修复 plpgsql 内存泄露修复中的笔误。提交 a6b1f5365 的目的是将 CALL 语句的瞬时“target”列表放入函数的语句生命周期上下文中,但我错误地使用了 get_eval_mcontext() 而不是 get_stmt_mcontext()。eval_mcontext 属于“简单表达式”基础设施,它在事务结束时被销毁。实际效果是,如果在过程中调用另一个具有 OUT 或 INOUT 参数的过程,并且被调用的过程执行了 COMMIT,则会导致失败。根据 Peter Eisentraut 的报告。向 v11 向后移植,与之前的补丁相同。讨论:https://postgr.es/m/f075f7be-c654-9aa8-3ffc-e9214622f02a@enterprisedb.com https://git.postgresql.org/pg/commitdiff/ea80d8d9437e80de6506dbfe3765d834653312bf

  • 进一步修复 plpgsql 内存泄露修复中的笔误。还有第二个 get_eval_mcontext() 调用也应该是 get_stmt_mcontext()。这实际上是死代码,因为在切换回原始上下文之前没有发生有趣的分配,但我们应该保持同步以防止未来的潜在错误。讨论:https://postgr.es/m/f075f7be-c654-9aa8-3ffc-e9214622f02a@enterprisedb.com https://git.postgresql.org/pg/commitdiff/5f2e09bcccd771629fb7a2885f8c468ae0f7fb33

  • 在 PQconndefaults() 中暴露 channel_binding 的默认值。如果连接选项有静态默认值,它应该在 PQconninfoOptions 数组中显示。作者:Daniele Varrazzo 讨论:https://postgr.es/m/CA+mi_8Zo8Rgn7p+6ZRY7QdDu+23ukT9AvoHNyPbgKACxwgGhZA@mail.gmail.com https://git.postgresql.org/pg/commitdiff/cf61b0734c61d93c62827fe4e44fa2162a533b8e

  • 修复 libpq 的 GSSAPI 加密支持中的错误。这里修复的关键问题是,如果成功建立了 GSSAPI 加密连接,pqsecure_open_gss() 会清除 conn->allow_ssl_try,这是一种姑且称之为“hacky”的方式,目的是阻止我们之后尝试在已加密的连接上隧道 SSL 加密。这样做的问题是,如果由于身份验证失败而放弃 GSSAPI 连接,那么在下次尝试连接同一服务器时,我们将不会尝试 SSL 加密。这可能导致意外的连接失败,或者在期望加密连接时静默地获得一个非加密连接。幸运的是,只有当客户端和服务器在同一 Kerberos 基础设施中持有有效的票据时,我们才能成功建立 GSSAPI 加密连接,而这种情况相对不常见。尽管如此,这是一个潜在安全隐患的严重错误。为了修复这个问题,不要重置该标志,而是增加一个检查,在决定是否尝试启动 SSL 时,检查 conn->gssenc 是否已为 true。同时,修复 libpq 的 GSSAPI 代码中的一些较小问题:* 在放弃尝试的 GSSAPI 连接时,使用 need_new_connection 语句块,而不是部分重复该代码。其后果相当轻微:据我所知,这只会导致 auth_req_received 或 password_needed 在不应设置时仍然设置,这对安全影响不大。* 修复 pg_GSS_error(),避免重复给出多次的“mprefix”,并注意到 gss_display_status() 的任何失败返回。* 避免 pg_GSS_load_servicename() 中对 NI_MAXHOST 的无谓依赖。根据 Mikael Gustavsson 的报告。向引入此代码的 v12 版本向后移植。讨论:https://postgr.es/m/e5b0b6ed05764324a2f3fe7acfc766d5@smhi.se https://git.postgresql.org/pg/commitdiff/ff6ce9a3a691a96e8e47ed449bc51c5a178e6931

  • 修复后端 GSSAPI 加密支持中的各种问题。GSSAPI 加密检测到的不可恢复错误不能简单地通过 elog(ERROR) 或 elog(FATAL) 报告,因为尝试将错误报告发送给客户端很可能导致无限递归或协议同步丢失。相反,让这段代码执行 SSL 加密代码长期以来所做的事情:将任何此类失败报告到服务器日志(使用 elevel COMMERROR),然后通过返回 errno = ECONNRESET 来假装连接已丢失。在此过程中,修复了关于消息翻译是由 pg_GSS_error() 还是其调用者(后者应该做)的混淆,并使此函数的后端版本更像前端版本。避免在需要时才分配 port->gss 结构;postmaster 肯定不需要分配它。改进了启用 GSS 时的“连接已授权”消息的日志记录。(作为此工作的一部分,我将 dc11f31a1 的代码更改向后移植了。)使 BackendStatusShmemSize() 能够计算 CreateSharedBackendStatus() 将分配的 GSS 相关空间。此遗漏可能导致 max_connections 设置非常高时出现共享内存不足的问题。移除仅 GSS 身份验证可用于 GSS 加密连接的任意、无意义的限制。改进文档;特别是,记录 libpq 现在优先 GSS 加密而不是 SSL 加密(如果两者都可用)。根据 Mikael Gustavsson 的报告。向引入此代码的 v12 版本向后移植。讨论:https://postgr.es/m/e5b0b6ed05764324a2f3fe7acfc766d5@smhi.se https://git.postgresql.org/pg/commitdiff/622ae4621ece72a9f64b5602c74d7aaf373c1631

  • 改进与 pg_hba.conf 不匹配连接相关的日志消息。包含有关 GSS 加密是否已激活的详细信息;由于我们添加了“hostgssenc”类型的 HBA 条目,这是相关信息。Kyotaro Horiguchi 和 Tom Lane。向引入 GSS 加密功能的 v12 版本向后移植。讨论:https://postgr.es/m/e5b0b6ed05764324a2f3fe7acfc766d5@smhi.se https://git.postgresql.org/pg/commitdiff/3995c424984e991b1069a2869af972dc07574c0b

  • 抑制来自多次报告 SIGQUIT 关机的日志噪音。当 postmaster 向其子进程发送 SIGQUIT 时,所有子进程都无需记录该事实;postmaster 已经为此进行了日志记录,因此添加可能几十或几百个子进程日志条目没有任何价值。因此,我们引入一个新的 ereport 级别来指定“警告,但绝不发送到日志”并用于这些消息。在提交 7e784d1dc 之前,这样的更改是不受欢迎的,因为如果有人手动 SIGQUIT 后台进程,我们确实希望记录下来。但现在我们可以相当确定地区分是由 postmaster 发出的信号和非 postmaster 发出的信号。在此期间,还在 ereport() 之前清除 error_context_stack,以防止在信号处理程序上下文中调用错误回调。这应该会降低在尝试通知客户端时陷入僵局的几率。根据 Andres Freund 的建议。讨论:https://postgr.es/m/20201225230331.hru3u6obyy6j53tk@alap3.anarazel.de https://git.postgresql.org/pg/commitdiff/1f9158ba48122fa232db955a2ee324eec1848ba9

  • 文档:修复 PDF 构建中因表格列过宽而产生的警告。向表格 8.27 和 65.1 添加多范围信息使其在 PDF 文档构建时开始出现“超出可用区域”警告。对于 8.27,调整现有的列宽度提示足以解决此问题。对于 65.1,我稍微调整了宽度,但要真正解决它,我不得不在每个逗号后面插入一个空格,以便在那里换行。(这似乎比插入 &zwsp; 实体更容易阅读和维护。)根据 buildfarm。 https://git.postgresql.org/pg/commitdiff/f20dc2c8dd50a5c738d535205d5d44bff82d3f75

  • 修复 krb_server_keyfile GUC 参数的使用。secure_open_gssapi() 无条件地将 krb_server_keyfile 设置为 KRB5_KTNAME,只要它不为空。但是,pg_GSS_recvauth() 仅在 KRB5_KTNAME 尚未设置时才安装它,这导致了一个令人担忧的不一致:理论上,客户端可能会看到不同的服务器主体名称集,这取决于它们是否使用 GSSAPI 加密。始终使用 krb_server_keyfile 似乎是正确的做法,因此让这两个地方都这样做。还修复了 secure_open_gssapi() 缺少对 setenv() 失败的检查——尽管不太可能,但安全关键操作不容许疏忽。还改进了相关的文档。此补丁对 secure_open_gssapi() 的 setenv() 使用没有影响,事实上也导致 pg_GSS_recvauth() 使用它。名义上这违反了项目的可移植性规则,但由于这段代码仅使用 --with-gssapi 构建,因此我无需在向后分支中处理此问题。HEAD 版本将很快发布补丁。向引入 GSSAPI 加密的 v12 版本向后移植。pg_GSS_recvauth() 中有问题的行为可以追溯得更远,但当时没有不一致之处,所以就这样吧。讨论:https://postgr.es/m/2187460.1609263156@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/860fe27ee1e2a4a1c36c2f874c37656533cccce9

  • 使用 setenv() 替代 putenv()。自 2001 年以来,我们一直使用 putenv() 并避免使用 setenv(),理由是后者不可移植且不在 POSIX 中。然而,POSIX 在同一年添加了它,现在情况已经逆转:setenv() 可能比 putenv() 更具可移植性,因为 POSIX 现在将后者视为非核心函数。而且 setenv() 的语义也更清晰。因此,让我们扭转旧的策略。此提交为任何滞后者添加了一个简单的 src/port/ setenv() 实现(我们在构建农场中有一个,但如果有人在实际使用中从未使用过这段代码,我不会感到惊讶)。更重要的是,扩展 win32env.c 以支持 setenv()。然后,用 setenv() 替换 putenv() 的用法,并删除一些 ad-hoc 的 setenv() 替代实现。此外,调整我们的 src/port/ unsetenv() 实现以遵循 POSIX 规范,即它返回一个错误指示符,而不是像古老的 BSD 约定那样返回 void。我认为没有必要让所有调用点都检查错误,但可移植性存根应该符合现实世界的实践。讨论:https://postgr.es/m/2065122.1609212051@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/7ca37fb0406bc2cbbd864a2ffdbdb4479e338c0c

  • 进一步修复 pg_upgrade 跨版本测试。提交 7ca37fb04 从 regress.so 库中移除了 regress_putenv,因此重新加载依赖于它的 SQL 函数将无法工作。修复方式与 52202bb39 类似。根据 buildfarm。 https://git.postgresql.org/pg/commitdiff/091866724cb3ee7251fa56e2517248c4b7796ca8

  • 文档:说明日期/时间类型的比较行为。跨日期/时间数据类型的比较行为实际上没有在任何地方得到解释。如果您认识到其他地方关于数据类型转换的注释的适用性,您可能可以推断出它,但似乎值得明确记录。根据 Dana Burd 的 bug #16797。讨论:https://postgr.es/m/16797-f264b0b980b53b8b@postgresql.org https://git.postgresql.org/pg/commitdiff/319f4d54e82d15d4a0c3f4cc1328c40dba024b5c

  • 文档:改进对 timestamp without tz 的 EXTRACT(EPOCH) 的解释。试图更清楚地说明这里实际发生的计算。根据 Dana Burd 的 bug #16797。讨论:https://postgr.es/m/16797-f264b0b980b53b8b@postgresql.org https://git.postgresql.org/pg/commitdiff/4d3f03f42227bb351c2021a9ccea2fff9c023cfc

Alexander Korotkov 提交了

Noah Misch 推送

Amit Kapila 提交

  • 将输出插件 API 扩展到允许解码已准备的事务。这向输出插件 API 添加了六个方法,增加了在准备时流式传输两阶段事务更改的支持。* begin_prepare * filter_prepare * prepare * commit_prepared * rollback_prepared * stream_prepare 大部分是现有方法的简单扩展,语义上的区别在于事务尚未提交,并且可能稍后被中止。到目前为止,两阶段事务已被转换为订阅服务器上的常规事务,并且 GID 没有被转发。没有两阶段命令被传达给订阅服务器。此补丁为逻辑解码插件提供了基础设施,以了解两阶段命令,如 PREPARE TRANSACTION、COMMIT PREPARED 和 ROLLBACK PREPARED 命令以及相应的 GID。它还扩展了“test_decoding”插件,实现了这些新方法。此提交仅添加了这些新 API,即将发布的“允许 ReorderBuffer 在准备时进行解码”的补丁将使用这些 API。作者:Ajin Cherian 和 Amit Kapila,基于 Nikhil Sontakke 和 Stas Kelvich 的先前工作。审阅者:Amit Kapila, Peter Smith, Sawada Masahiko, and Dilip Kumar 讨论:https://postgr.es/m/02DA5F5E-CECE-4D9C-8B4B-418077E2C010@postgrespro.ru https://postgr.es/m/CAMGcDxeqEpWj3fTXwqhSwBdXd2RS9jzwWscO-XbeCfso6ts3+Q@mail.gmail.com https://git.postgresql.org/pg/commitdiff/0aa8a01d04c8fe200b7a106878eebc3d0af9105c

Peter Geoghegan 提交

  • 修复索引删除 latestRemovedXid 错误。用于在 REDO 例程中生成恢复冲突的 latest removed XID 的逻辑存在细微错误。它未能跟踪 HOT 链的链接,因此在某些情况下未能考虑所有相关的堆元组头。为修复此问题,扩展了处理 LP_REDIRECT 行指针的循环,也处理 HOT 链。新版本的循环大致基于 heap_prune_chain() 中的类似循环。此错误的潜在影响可能非常有限,因为 horizon 代码必然会处理被 LP_DEAD 设置的索引元组指向的堆元组。设置 LP_DEAD 索引元组(例如,在 kill_prior_tuple 机制中)的过程与被指向堆元组的的机会性修剪高度相关。此外,生成恢复冲突的问题通常发生在索引元组 LP_DEAD 位最初设置一段时间之后,与堆修剪不同,堆修剪在修剪操作时生成 latestRemovedXid(堆修剪没有延迟的“可能页面拆分”样式处理,会延迟产生冲突)。仅向 Postgres 12 向后移植,这是该逻辑在原始执行期间运行的第一个版本(遵循提交 558a9165e08)。索引 latestRemovedXid 机制自十多年前(提交 a760893d)出现以来一直存在相同的错误,但现在权衡利弊,向所有支持的版本向后移植似乎是一个糟糕的主意。鉴于没有来自生产环境的投诉,在恢复期间运行新的改进代码似乎有风险。作者:Peter Geoghegan pg@bowt.ie 讨论:https://postgr.es/m/CAH2-Wz=Eib393+HHcERK_9MtgNS7Ew1HY=RDC_g6GL46zM5C6Q@mail.gmail.com 向后移植:12- https://git.postgresql.org/pg/commitdiff/422881744997417944634a7f84af7a66a608de9a

  • 持有缓冲区锁时获取堆页面最大偏移量。进一步思考后,似乎在获取页面上的缓冲区锁后调用 PageGetMaxOffsetNumber() 更好。这实际上应该无关紧要,但这样做更干净。跟进提交 42288174。向后移植:12-,与提交 42288174 相同。 https://git.postgresql.org/pg/commitdiff/32d6287d2eef6b6a4dde07e0513f3e4f321792ad

待处理补丁

Noah Misch 提交了一个补丁,用于合并 roles_is_member_of() 中相似的算法。

Vigneshwaran C 在现有补丁的基础上提交了一个补丁,用于并行化 COPY 的一部分,该部分将查找行边界的任务委托给工作进程。

Bharath Rupireddy 提交了一个补丁,用于实现 REFRESH MATERIALIZED VIEW 的 EXPLAIN [ANALYZE]。

Masahiko Sawada 提交了另一个版本的补丁,用于添加新的 FDW API 来支持 2PC,引入全局事务管理器,并在 PostgreSQL FDW 中实现这些 FDW API。

Peter Geoghegan 提交了另一个版本的补丁,用于进行 btvacuumstrategy() 的自底向上索引删除更改。

Bharath Rupireddy 提交了另外两个版本的补丁,用于使 CTAS 能够使用并行插入。

Luc Vlaming 提交了两个版本的补丁,用于惰性生成 JIT IR 代码,这个问题出现在为分区表生成大量 JIT IR 代码但实际上从未执行 IR 的情况下,因为这些分区被修剪了。

Thomas Munro 提交了另一个版本的补丁,用于使 Full 和 Right JOIN 的执行能够使用并行哈希。

Andrey Borodin 提交了另一个版本的补丁,用于将 LZ4 添加为 WALL FPI 的可能压缩方案。

David Rowley 提交了另外两个版本的补丁,用于减少在 Windows 上构建 contrib 模块的特殊情况数量。

Noah Misch 提交了一个补丁,用于转储 public schema 的所有权和安全标签。

Paul Martinez 提交了一个补丁,用于简化 user.c 中的权限检查逻辑。

Bharath Rupireddy 提交了另一个版本的补丁,用于允许在 REFRESH MATERIALIZED VIEW 的计划中启用并行模式。

Thomas Munro 提交了另一个版本的补丁,用于在共享内存中跟踪关系大小,此功能由新的 GUC smgr_shared_relation 控制,它限制了新引入的 SMgrSharedRelation 对象池的数量,并为 smgrnblocks() 提供了一个无锁的快速路径。

Peter Smith 提交了另一个版本的补丁,用于允许 table-sync 工作进程使用多个事务。

Andrey V. Lepikhov 提交了另一个版本的补丁,用于通过向 FDW API 添加三个新例程:BeginForeignCopy、EndForeignCopy 和 ExecForeignCopy,以及将相同的功能添加到 PostgreSQL FDW,从而加快了具有外部分区的表的 COPY 速度。

Andrey Borodin 提交了另一个版本的补丁,用于重组 pglz 压缩代码,通过将宏函数转换为常规函数以提高可读性,使用具有 uint16 索引的更紧凑的哈希表而不是指针,避免在哈希表中出现 prev 指针,并使用 4 字节比较而不是 1 字节比较来进行搜索,从而提高效率。

Justin Pryzby 提交了另一个版本的补丁,用于实现 CREATE TABLE (LIKE .. INCLUDING ACCESS METHOD)。

Luc Vlaming 提交了另一个版本的补丁,用于实现部分 UNION ALL,从而改进了并行子查询成本估算。

Rui Zhao 提交了另一个版本的补丁,用于重构 RelationIdGetRelation 之后调用 RelationClose 的方式。

Peter Eisentraut 提交了另一个版本的补丁,用于从过程实现动态结果集。

David Fetter 提交了两个版本的补丁,用于将 popcount 暴露给 SQL。

Joe Wildish 提交了另一个版本的补丁,用于允许在 FOR EACH STATEMENT 触发器的 WHEN 表达式中编写查询。

David Fetter 提交了另一个版本的补丁,用于使 pg_hba.conf 参数能够从 initdb 设置。

Greg Sabino Mullane 提交了另一个版本的补丁,用于使 psql 的 \df 能够根据输入类型帮助选择函数。

David Fetter 和 Krasiyan Andreev 交换了补丁,用于实现窗口函数的 NULL 处理。

Dmitry Dolgov 提交了另外三个版本的补丁,用于将通用的类型下标基础设施用于 JSONB。

David Fetter 提交了一个 WIP 补丁,用于记录 hooks 系统。

Michael Banck 提交了一个补丁,用于添加一个新的 PGC_ADMINSET guc 上下文和 pg_change_role_settings 默认角色,在“superuser”和“user”之间为 GUC 上下文创建了一个空间。

Álvaro Herrera 提交了另一个版本的补丁,用于实现 MERGE。

Peter Geoghegan 提交了另一个版本的补丁,用于传递一个“逻辑上未更改的索引”提示,并使用它来实现自底向上索引删除。

Soumyadeep Chakraborty 提交了另一个版本的补丁,用于向表 AM API 添加一个接受列投影列表的例程。

Bruce Momjian 和 Michaël Paquier 交换了补丁,将其他十六进制函数移到源代码树的公共位置。

Etsuro Fujita 提交了另外两个版本的补丁,用于在 postgres_fdw 节点上实现异步追加。

David Fetter 提交了另一个版本的补丁,用于实现 TIDs 的范围扫描。

Pavel Stěhule 提交了另一个版本的补丁,用于减少 PL/pgSQL 在非原子模式下 CALL 语句的执行开销。

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

Josef Šimánek 提交了另一个版本的补丁,用于添加一个 pg_stat_progress_copy 视图,其中包含 COPY 进度报告。

Pavel Stěhule 提交了一个补丁,用于使窗口函数可以在 PL 中编写,因为它们目前仅限于 C。

Luc Vlaming 提交了一个补丁,用于提高堆表的批量加载效率,通过为每个后端分配一个独立的、本地于该后端的块集,并减少了锁定分区缓冲区所花费的时间,方法是调整逻辑,使每组 128 个块使用相同的缓冲区分区,然后添加一个自定义函数来专门为扩展获取缓冲区块,同时保留之前的分区锁,从而减少了我们在 futexes 上花费的时间。

Michael Banck 提交了一个补丁,将 --data-checksums 移到 initdb 的 --help 输出中的通用选项。

Thomas Munro 提交了一个 pgbench 补丁,用于为缺少 pthread barrier 的平台添加 pthread barrier 模拟。