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

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

发布于 2021-11-15 by PWN
PWN

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

PostgreSQL 14.1、13.5、12.9、11.14、10.19 和 9.6.24 已发布。这是 9.6 系列的最后一个版本,如果您还没有开始,请尽快制定升级计划。

PostgreSQL 产品新闻

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

Odyssey 1.2,一个用于 PostgreSQL 的多线程连接池,已发布。https://github.com/yandex/odyssey/releases

pgbouncer 1.16.1,一个用于 PostgreSQL 的连接池等,已发布

11月 PostgreSQL 工作机会

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

PostgreSQL 相关新闻

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

本周 PostgreSQL 周报由 David Fetter 提供。

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

已应用补丁

David Rowley 提交

Tom Lane 提交

  • 在 SSL 或 GSS 加密握手后拒绝多余数据。服务器在从客户端套接字读取数据时会收集最多一个缓冲区量的数据。当在启动过程中请求 SSL 或 GSS 加密时,在初始请求消息中收到的任何额外数据都会保留在缓冲区中,并且在加密握手完成后会被视为已解密的数据。因此,能够将数据注入 TCP 连接的中间人可以将一些明文数据塞入一个本应受加密保护的数据库会话的开头。这可能会被滥用以发送伪造的 SQL 命令给服务器,尽管这只有在服务器不要求任何身份验证数据时才有效。(但是,依赖 SSL 证书身份验证的服务器可能不会这样做。)为了解决这个问题,如果在加密握手后内部缓冲区不为空,则抛出协议违反错误。感谢 Jacob Champion 报告此问题。安全:CVE-2021-23214 https://git.postgresql.org/pg/commitdiff/28e24125541545483093819efae9bca603441951

  • libpq:在 SSL 或 GSS 加密握手后拒绝多余数据。libpq 在从套接字读取数据时会收集最多一个缓冲区量的数据。当在启动过程中请求 SSL 或 GSS 加密时,在服务器的 yes-or-no 回复中收到的任何额外数据都会保留在缓冲区中,并且在加密握手完成后会被视为已解密的数据。因此,能够将数据注入 TCP 连接的中间人可以将一些明文数据塞入一个本应受加密保护的数据库会话的开头。这很可能被滥用以注入伪造的响应给客户端的最初几个查询,尽管 libpq 行为的其他细节使其比听起来更难实现。另一条攻击路线是窃取客户端的密码,或其他可能在会话早期发送的敏感数据。这已被证明可以对易受 CVE-2021-23214 攻击的服务器进行攻击。为了解决这个问题,如果在加密握手后内部缓冲区不为空,则抛出协议违反错误。感谢 Jacob Champion 报告此问题。安全:CVE-2021-23222 https://git.postgresql.org/pg/commitdiff/160c0258802d10b0600d7671b1bbea55d8e17d45

  • 修复不正确的格式占位符。根据构建农场警告。 https://git.postgresql.org/pg/commitdiff/b0cf5444f9a8d915b2e9b44790025f17a7dc107f

  • 修复 026_overwrite_contrecord.pl 测试中的不稳定性。我们在较慢的构建农场机器上看到了此测试间歇性失败,我认为这可以通过假设 autovacuum 发出了一些额外的 WAL 来解释。禁用 autovacuum 以稳定它。顺便,使用字符串比较而不是数字比较来比较 WAL 文件名。目前无关紧要,但它们是十六进制字符串而不是十进制……讨论:https://postgr.es/m/1372189.1636499287@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/b66767b56b1cd082f3499a7e5a21b480dd004f51

  • 文档:改进逻辑复制 Type 消息的协议规范。protocol.sgml 记录了 Type 消息的布局,但除此之外完全没有提及,未能解释它们是什么,何时发送,或者它们有什么用。在此过程中,对 Relation 消息的描述进行一些文案编辑。顺便,调整 apply_handle_type() 的注释,使其更清楚我们选择在收到 Type 消息时不做任何操作,而不是认为它没有任何用途。根据 Stefen Hillman 的问题。讨论:https://postgr.es/m/CAPgW8pMknK5pup6=T4a_UG=Cz80Rgp=KONqJmTdHfaZb0RvnFg@mail.gmail.com https://git.postgresql.org/pg/commitdiff/c3b33698cf88550b017620f73b94b53029897f39

  • 回退到 unsigned int,而不是 int,用于 socklen_t。这两种假设是好是坏很难说。然而,在我们拥有的构建农场机器中,唯一依赖于回退 socklen_t 定义的是旧的 HPUX,在该平台上 unsigned int 是正确的选择。对 ee3a1a5b6 的小调整。讨论:https://postgr.es/m/1440792.1636558888@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/01ec41a5fe4aa590dde18a2c551432aa1925caea

  • postgres_fdw:在有限情况下抑制常量上的转换。在解析 "remote_var OP constant" 形式的表达式时,我们通常会为常量应用一个转换,以确保远程解析器认为它与我们的类型相同。然而,这样做通常不是必需的,并且如果用户故意将本地列声明为与远程列不同的类型,则会导致问题。一个可能的用例是使用 text 来表示远程枚举类型。对这种列的比较会被发送为 "var = 'foo'::text",这会在远程端因为没有 enum = text 运算符而失败。但如果我们简单地省略显式转换,比较就会按照用户想要的方式进行。在没有重大语义问题风险的情况下,可以通过依赖长期存在的解析器启发式方法来完成,即“如果操作数的一个操作数是未知类型,而另一个具有已知类型,则假设未知操作数也具有该类型”。因此,此补丁仅在以下情况下省略转换:(a) 操作数的输入在本地具有相同的类型;(b) 该常量将被打印为字符串字面量或 NULL,两者都最初被视为未知类型;(c) 非 Const 输入是普通的外部 Var。规则 (c) 保证远程解析器将知道非 Const 输入的类型;此外,它意味着如果这种省略转换确实引起了任何语义上的意外,那只能发生在本地列的类型与远程列的类型不同的情况下。这 anyway 并不保证能正常工作,而此补丁应该代表了这些情况下可用性的净增长。我(tgl)仍然有些不安的一点是,我们在判断非 Const 输入是否为普通 Var 时会忽略隐式的 RelabelType。这使得争论远程应该将 Const 解析为与其 Var 相同类型变得有点棘手,因为那时我们的 Const 与我们的 Var 类型不匹配。然而,如果我们不这样做,那么当用户选择使用 varchar 而不是 text 来表示某个远程列时,这个技巧将无法按预期工作。这似乎很有用,所以暂时这样做。如果出现任何问题,我们可能不得不放弃忽略 RelabelType。Dian Fay,由我进行审查和评论。讨论:https://postgr.es/m/C9LU294V7K4F.34LRRDU449O45@lamia https://git.postgresql.org/pg/commitdiff/f8abb0f5e114d8c309239f0faa277b97f696d829

  • 将 psql 的 \password 命令默认设置为 CURRENT_USER,而不是 PQuser(conn)。文档明确说明 \password 默认作用于“当前用户”。它实际作用于(或尝试作用于)用于登录当前会话的用户名。如果稍后执行了 SET ROLE 或 SET SESSION AUTHENTICATION,则这与当前用户不同。除了潜在的意外因素,当前角色很可能没有权限来设置原始角色的密码。为了解决这个问题,使用 "SELECT CURRENT_USER" 来获取要操作的角色名称。(此语法至少与 7.0 版的服务器兼容。)另外,为了减少混淆,在密码提示中包含将要操作的角色名称。与文档的差异使其成为一个 bug,因此回溯到所有支持的分支。由我提交补丁;感谢 Nathan Bossart 的审查。讨论:https://postgr.es/m/747443.1635536754@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/d6eb5a0c258d3da5471814bcc6ed6498129fee16

Robert Haas 提交

  • 针对未终止 tar 归档问题的最小修复。提交 23a1c6578c87fca0e361c4f5f9a07df5ae1f9858 改进了 pg_basebackup 解析 tar 归档的能力,但也安排仅在我们进行一些归档内容修改时才解析它们。这是一个问题,因为服务器实际上不会终止 tar 归档。当新的解析逻辑被启用时,pg_basebackup 会正确终止 tar 文件,但当它被跳过时,pg_basebackup 只会写入从服务器获取的内容,这意味着缺少终止符。大多数版本的 tar 都愿意忽略缺少终止符,但 AIX 构建农场中的机器则不然。通过发明一种新的 bbstreamer 来盲目添加一个终止符来修复此问题,并在我们不解析 tar 归档时使用它。讨论:http://postgr.es/m/CA+TgmoZbNzsWwM4BE5Jb_qHncY817DYZwGf+2-7hkMQ27ZwsMQ@mail.gmail.com https://git.postgresql.org/pg/commitdiff/57b5a9646d97a3e8a5b6b6d86b375cc8da6ac85c

  • 让服务器正确终止 tar 归档。PostgreSQL 的早期版本有一个 pg_basebackup 版本,它想要编辑 tar 归档但太笨拙而无法正确解析它们。服务器通过未能添加应该结束 tar 文件的两个零字节块来简化客户端的工作,将其留给客户端处理。但自提交 23a1c6578c87fca0e361c4f5f9a07df5ae1f9858 以来,我们不再需要这个 hack 了,因为 pg_basebackup 现在更智能,即使 tar 文件已正确终止也能解析!因此,更改服务器以始终正确终止 tar 文件。旧版本的 pg_basebackup 无论如何都无法与新服务器通信,因此没有兼容性中断。在 pg_basebackup 端,如果我们正在与旧服务器通信,我们仍然需要添加终止零字节,但在服务器版本为 v15+ 时则不需要。希望将来我们能够移除一些兼容性垃圾,但目前似乎最好保留它。顺便,在 bbstreamer_tar.c 中添加一个文件头注释,以使其更清楚这里发生了什么。讨论:http://postgr.es/m/CA+TgmoZbNzsWwM4BE5Jb_qHncY817DYZwGf+2-7hkMQ27ZwsMQ@mail.gmail.com https://git.postgresql.org/pg/commitdiff/5a1007a5088cd6ddf892f7422ea8dbaef362372f

  • 进一步清理 'ThisTimeLineID'。在 XLogCtlData 中,将结构成员 ThisTimeLineID 重命名为 InsertTimeLineID,并更新注释以清楚地表明它仅在恢复完成后才会被设置。在 StartupXLOG 中,用新的局部变量 replayTLI 和 newTLI 替换局部变量 ThisTimeLineID 和 PrevTimeLineID。在旧方案中,ThisTimeLineID 是回放 TLI,直到我们创建一个新的时间线,然后回放 TLI 存储在 PrevTimeLineID 中。现在,replayTLI 是我们在整个函数中最后回放 WAL 的 TLI,而 newTLI 是其中之一,或者是提升时创建的新时间线。移除声明 recoveryTargetTimeLineGoal 等的注释块上方的误导性注释。它已不再准确,不仅因为变量 ThisTimeLineID 已被移除,而且因为 rmgr 代码不关心 ThisTimeLineID,自从页面头部的 TLI 字段被重新用于存储页面校验和以来就一直如此。在 GetFlushRecPtr 的注释中添加说明,它仅应在正常运行时使用,并添加一个断言来验证这一点。根据 Michael Paquier 的一些想法和我的想法。Michael Paquier 也进行了审查。讨论:http://postgr.es/m/CA+TgmoY1a2d1AnVR3tJcKmGGkhj7GGrwiNwjtKr21dxOuLBzCQ@mail.gmail.com https://git.postgresql.org/pg/commitdiff/a27048cbcb582056bfbf15aa2f898b4a3ec74304

  • 修复 basebackup.c 中断言的思考错误。提交 5a1007a5088cd6ddf892f7422ea8dbaef362372f 试图引入一个断言,即块大小至少是 tar 块大小的两倍,但我算错了。我的错误是离线报告给我的。 https://git.postgresql.org/pg/commitdiff/10eae82b27cebbb9586cda8baf8e3226496891d0

  • 提高 pgarch_readyXlog() 在有大量状态文件时的性能。目前,archive_status 目录会被扫描以获取要归档的每个文件。当存在大量状态文件时(例如,因为 archive_command 已经失败了很长时间),这些目录扫描可能会非常慢。通过此更改,归档器在每次目录扫描期间会记住要归档的几个文件,从而提高速度。为了确保时间线历史文件尽快归档,XLogArchiveNotify() 会在创建其中一个 .ready 文件后立即强制归档器进行新的目录扫描。Nathan Bossart,根据涉及许多人的长期讨论。我不清楚确切是哪些人审查了此特定补丁。讨论:http://postgr.es/m/CA+TgmobhAbs2yabTuTRkJTq_kkC80-+jw=pfpypdOJ7+gAbQbw@mail.gmail.com 讨论:http://postgr.es/m/620F3CE1-0255-4D66-9D87-0EADE866985A@amazon.com https://git.postgresql.org/pg/commitdiff/beb4e9ba1652a04f66ff20261444d06f678c0b2d

Amit Kapila 提交

Fujii Masao 提交

Michaël Paquier 提交

  • 为保持一致性,将一些注释术语更改为“ProcSignal”。procsignal.c 中的周围术语更倾向于使用“ProcSignal”而不是“procsignal”。作者:Bharath Rupireddy 讨论:https://postgr.es/m/CALj2ACX99ghPmm1M_O4r4g+YsXFjCn=qF7PeDXntLwMpht_Gdg@mail.gmail.com https://git.postgresql.org/pg/commitdiff/4cd046c203bbca2955182f78eabc06e831ffdbb1

  • 改进 XLogReadRecord() 某些调用者的错误消息。与逻辑解码相关的几个代码路径(WAL 发送器、槽位推进等)使用 XLogReadRecord(),并在 walreader.c 的失败处生成错误消息。所有这些消息都没有上下文,使得即使不应该发生这些错误,也很难判断错误来源。XLogReadRecord() 的所有其他调用者都已经这样做了。审阅者:Kyotaro Horiguchi 讨论:https://postgr.es/m/YYnTH6OyOwQcAdkw@paquier.xyz https://git.postgresql.org/pg/commitdiff/c9c401a5e13accc4a3a775e3feeabdc5940c9178

  • 清理 PL/Perl 使用 clang-12~ 编译时产生的警告。clang-12 引入了 -Wcompound-token-split-by-macro,由于其与上游 Perl 的交互,导致编译 PL/Perl 时产生大量警告。此提交在 ./configure 时向 CFLAGS 添加了一个 -Wno,如果编译器支持该标志,则可以抑制所有这些警告。上游 Perl 已修复此问题,但要将其传播到构建农场还需要一些时间,并且我们注意到有些动物在使用额外的 -Werror 来帮助检测不正确的占位符(参见 b0cf544)时会很有用,dango-mushi 就是其中之一。审阅者:Tom Lane 讨论:https://postgr.es/m/YYr3qYa/R3Gw+Sbg@paquier.xyz 回溯补丁版本:10 https://git.postgresql.org/pg/commitdiff/9ff47ea414c4e6ace347fc4e59866e38b9bbceaf

  • 修复 unicode 字符串规范化中的缓冲区溢出(空输入)。PostgreSQL 13 及更高版本直接受此影响,通过 SQL 函数 normalize(),当使用空字符串进行输入并使用 NFC 和 NFKC 重组字符串时,会导致该函数调用写入超出其分配空间一个字节。旧版本(v10~v12)不受此问题直接影响,因为唯一使用规范化的代码路径是 SCRAM 身份验证中的 SASLprep,它禁止空字符串的情况,但我们还是使代码在那里更健壮,以便覆盖任何外部调用此函数的调用者。解决此问题的方法很简单,添加一个快速退出路径,如果发现分解后的字符串为空。这只会发生在空字符串的情况下,因为在其最低级别,如果一个码点在分解表中没有条目或分解大小为 0,它将被分解为自身。在 v13~ 中添加了一些测试来覆盖此问题。请注意,自从此功能作为 2991ac5 引入以来,对于所有允许的操作(NFC、NFD、NFKC 和 NFKD),空字符串一直被视为已规范化(语法 "IS NF[K]{C,D} NORMALIZED",通过 SQL 函数 is_normalized())。此行为保持不变,但在 v13~ 中添加了一些测试以进行后续检查。我还检查了 src/common/unicode/ 中的 "make normalization-check"(在 13~ 版本中有效,在旧的稳定分支中独立于此提交而失败)。发布说明应仅为 v13~ 提及此提交。报告者:Matthijs van der Vleuten 讨论:https://postgr.es/m/17277-0c527a373794e802@postgresql.org 回溯补丁版本:10 https://git.postgresql.org/pg/commitdiff/098c134556664d37b78ae87853a82f4a9d23a2c8

  • 修复查询 pg_stat_slru 时内存溢出。pgstatfuncs.c 中的 pg_stat_get_slru() 在完成扫描其条目时,会指向 PgStat_SLRUStats 数组末尾的一个元素。这没有直接后果,因为没有从额外的内存区域读取数据,但静态分析器会正确地抱怨。所以让我们保持清洁。顺便,这在系统视图预留区域添加了一个回归测试。报告者:Alexander Kozhemyakin,通过 AddressSanitizer 作者:Kyotaro Horiguchi 讨论:https://postgr.es/m/17280-37da556e86032070@postgresql.org 回溯补丁版本:13 https://git.postgresql.org/pg/commitdiff/a45ed975c58fde7303eeae488b313bf0314383f7

Peter Eisentraut 提交

Jeff Davis 推送

Álvaro Herrera 提交

Peter Geoghegan 提交

Noah Misch 推送

Andrew Dunstan 推送

Daniel Gustafsson 提交