JDBC 42.3.0 已发布。
pgmetrics 1.12,一个用于 PostgreSQL 指标的命令行工具,已发布。
StackGres 1.0.0,一个用于在 Kubernetes 上运行 PostgreSQL 的平台,已发布。https://stackgres.io/
pgexporter 0.2.0,一个用于 PostgreSQL 的 Prometheus 导出器,已发布
pgAdmin4 6.1,一个用于 PostgreSQL 的 Web 和原生 GUI 控制中心,已发布。
https://archives.postgresql.org/pgsql-jobs/2021-10/
Planet PostgreSQL: https://planet.postgresql.org/
本周的 PostgreSQL 每周新闻由 David Fetter 为您带来
请在太平洋标准时间/太平洋夏令时周日下午 3:00 前将新闻和公告提交至 david@fetter.org。
Michaël Paquier 推送了
修复 psql 新 TAP 测试中的可移植性问题。c0280bc 和 d9ddc50 在 001_basic.pl 中添加的测试直接调用 psql 命令,使其对环境敏感。其中一个问题是这些命令忘记了 -X 选项,导致所有测试在 psql 无法正确解析此文件时失败。TAP 测试应该以隔离的方式运行,不依赖于运行它们的环境。由于 PostgresNode::psql 已经提供了这些新测试所需的所有功能,因此请切换到该功能,而不是在需要与后端交互时调用普通的 psql 命令。该测试经过轻微重构,以便能够在 stdout 和 stderr 的预期模式之后进行检查,从而保持与以前相同的覆盖率。报告人:Peter Geoghegan 讨论:https://postgr.es/m/CAH2-Wzn8ftvcDPwomn+y04JJzbT=TG7TN=QsmSEATUOW-ZuvQQ@mail.gmail.com https://git.postgresql.org/pg/commitdiff/384f1abdb9b0f669279fcd57ba2173eb31724740
在事务中止期间正确重置快照导出状态。在创建复制槽期间,与创建要导出的快照的事务在同一事务中生成的 ERROR 会使后端处于不一致的状态,因为关联的静态导出快照状态未在事务中止时重置,而仅在创建复制槽时 WAL 发送方收到的后续命令时重置。如果此会话尝试再次导出快照(例如在创建复制槽期间),则会导致不一致性失败。请注意,快照导出不能在事务块中发生,因此无需担心子事务中止时重置此状态。此外,这种不一致的状态不太可能显示给用户。例如,可能发生这种情况的一种情况是在构建要导出的初始快照时出现内存不足错误。Dilip 在尝试其他补丁时发现了这个问题,这导致了此代码路径中出现与 HEAD 无关的错误。作者:Dilip Kumar 审核人:Michael Paquier、Zhihong Yu 讨论:https://postgr.es/m/CAFiTN-s0zA1Kj0ozGHwkYkHwa5U0zUE94RSc_g81WrpcETB5=w@mail.gmail.com 回溯至:9.6 https://git.postgresql.org/pg/commitdiff/409f9ca4471331be0f77b665ff3a1836a41de5b3
阻止 ALTER INDEX/TABLE index_name ALTER COLUMN colname SET (options)。此命令在带有列名的索引上运行的语法一直被解析器授权,并且从未记录过。自 911e702 以来,可以像 CREATE INDEX 一样定义 opclass 参数,这实际上破坏了 ALTER INDEX/TABLE 的旧情况,其中可以为索引定义关系级参数 n_distinct 和 n_distinct_inherited(请参阅 76a47c0 及其线程,其中已触及此点,但仍然未使用)。尝试在 v13 中执行此操作会导致索引变得不可用,因为有一个新的专用代码路径来加载 opclass 参数,而不是以前可用的关系级参数。请注意,可以通过手动更新目录来使关系恢复正常。此提交暂时禁用此命令,因为索引的列名没有任何意义,特别是在自动计算名称的索引表达式中。将来正确支持这种情况的一种方法是像 ALTER INDEX .. ALTER COLUMN .. SET STATISTICS 一样使用列号。分区索引已被阻止,但非分区索引尚未阻止。为这两种情况添加了一些测试。ANALYZE 中有一些代码强制在定义参数时将 n_distinct 用于索引表达式,但暂时将其删除,直到/如果有对此的支持(请注意,索引级参数以前在 pg_dump 中也没有支持),因此这只是死代码。报告人:Matthijs van der Vleuten 作者:Nathan Bossart、Michael Paquier 审核人:Vik Fearing、Dilip Kumar 讨论:https://postgr.es/m/17220-15d684c6c2171a83@postgresql.org 回溯至:13 https://git.postgresql.org/pg/commitdiff/fdd88571454e2b00dbe446e8609c6e4294ca89ae
修复使用 OpenSSL 3.0.0 的 MSVC 构建。Visual Studio 的构建脚本无法正确检测到 3.0.0 构建,因为对第二位数字的检查失败。此处根据需要进行了调整,允许完成构建。请注意,文档中提到的 OpenSSL 的 MSI 对于 Win32 和 Win64 而言没有更改任何库名称,这使得此更改非常简单。报告人:htalaco,通过 github 审核人:Daniel Gustafsson 讨论:https://postgr.es/m/YW5XKYkq6k7OtrFq@paquier.xyz 回溯至:9.6 https://git.postgresql.org/pg/commitdiff/41f30ecc29c89285d3eecd435906c4e9cb048be4
修复从模板数据库复制依赖项时 pg_shdepend 的损坏。为新数据库使用具有需要复制的共享依赖项的模板数据库会导致 pg_shdepend 损坏,因为使用槽插入的值的索引号存在差一的计算错误。由 e3931d0 引入的问题。监控其余代码,没有类似的错误。报告人:Sven Klemm 作者:Aleksander Alekseev 审核人:Daniel Gustafsson、Michael Paquier 讨论:https://postgr.es/m/CAJ7c6TP0AowkUgNL6zcAK-s5HYsVHVBRWfu69FRubPpfwZGM9A@mail.gmail.com 回溯至:14 https://git.postgresql.org/pg/commitdiff/98ec35b0bbf6003e89fc06aa140e12fd90bbad47
文档:描述 pg_receivewal 的流式传输起点的计算方法。该文档对于使用 pg_receivewal 命令定义的本地存档目录中找不到任何内容时用于 WAL 流式传输的起始 LSN 的描述不准确,因此请更详细地说明此问题。从同一作者的较大补丁中提取。作者:Ronan Dunklau、Michael Paquier 讨论:https://postgr.es/m/18708360.4lzOvYHigE@aivenronan 回溯至:10 https://git.postgresql.org/pg/commitdiff/1e9475694b0ae2cf1204d01d2ef6ad86f3c7cac8
Heikki Linnakangas 推送了
将多相合并算法替换为简单的平衡 k 路合并。多相合并的优点是可以有效地重用输入磁带作为输出磁带,但这在现代硬件上无关紧要,因为我们可以轻松模拟任意数量的磁带驱动器。在合并期间我们可以/应该使用的输入磁带数量受 work_mem 的限制,但是我们当前未写入的输出磁带仅占用少量内存,因此无需节省它们。这使得需要多个合并过程的排序更快。讨论:https://postgresql.ac.cn/message-id/420a0ec7-602c-d406-1e75-1ef7ddc58d83%40iki.fi 审核人:Peter Geoghegan、Zhihong Yu、John Naylor https://git.postgresql.org/pg/commitdiff/65014000b351d5725eb00d133416ab1b4f8245b1
重构 LogicalTapeSet/LogicalTape 接口。所有磁带函数(如 LogicalTapeRead 和 LogicalTapeWrite)现在都将 LogicalTape 作为参数,而不是 LogicalTapeSet + 磁带编号。您可以在单个 LogicalTapeSet 中创建任意数量的 LogicalTape,并且您无需在创建磁带集时提前决定数量。这使得 nodeAgg.c 中哈希聚合溢出的磁带管理更加简单。讨论:https://postgresql.ac.cn/message-id/420a0ec7-602c-d406-1e75-1ef7ddc58d83%40iki.fi 审核人:Peter Geoghegan、Zhihong Yu、John Naylor https://git.postgresql.org/pg/commitdiff/c4649cce39a41b27db874e75ddd47adaec1b0ea4
修复 elog 中使用的格式修饰符。之前的提交 65014000b3 将传递给 elog 的变量从 int64 更改为 size_t 变量,但忽略了相应地更改格式字符串中的修饰符。每个构建场成员 lapwing 上的故障。 https://git.postgresql.org/pg/commitdiff/0bd65a3905706927cdd6b3158b6457c1c854471b
修复重复的 typedef LogicalTape。让构建场成员 locust 满意。 https://git.postgresql.org/pg/commitdiff/aa3ac6453b28049b3198433b75228271b7612d4a
修复由平衡合并补丁破坏的并行排序。在并行工作程序中跳过了在每次合并迭代时初始化磁带的代码。我在重新设置补丁时将 !WORKER(state) 检查放在了错误的位置。这导致多个构建场成员在“multiple-row-versions”隔离测试中的索引构建中失败。在我的笔记本电脑上,通过在更大的表上构建索引更容易重现,这样您可以更可靠地获得并行排序。 https://git.postgresql.org/pg/commitdiff/fc0f3b4cb0e882a9c5d51c302d4aa3591e4f80fd
Álvaro Herrera 推送了
使附加/分离的表的分区失效。如果未能做到这一点,任何对这些分区的直接插入/更新操作都将无法强制执行正确的约束,即考虑其父表的新分区约束。反向移植到 10。报告人:侯志杰 houzj.fnst@fujitsu.com 作者:Amit Langote amitlangote09@gmail.com 作者:Álvaro Herrera alvherre@alvh.no-ip.org 审核人:Nitin Jadhav nitinjadhavpostgres@gmail.com 审核人:Pavel Borisov pashkin.elfe@gmail.com 讨论:https://postgr.es/m/OS3PR01MB5718DA1C4609A25186D1FBF194089%40OS3PR01MB5718.jpnprd01.prod.outlook.com https://git.postgresql.org/pg/commitdiff/d6f1e16c8fe27100e371a15aeeb498faa680ceed
确保在 ALTER ... RENAME 中使用正确的锁级别。提交 1b5d797cd4f7 旨在放宽用于重命名索引的锁级别,但不经意地允许使用较低的锁级别重命名任何关系,只要命令拼写为 ALTER INDEX。这对于其他关系类型是不可取的,因此如果关系不是索引,则使用更高的锁重试操作。此修复后,ALTER INDEX <sometable> RENAME 将需要独占访问锁,而之前不需要。作者:Nathan Bossart bossartn@amazon.com 作者:Álvaro Herrera alvherre@alvh.no-ip.org 报告人:Onder Kalaci onderk@microsoft.com 讨论:https://postgr.es/m/PH0PR21MB1328189E2821CDEC646F8178D8AE9@PH0PR21MB1328.namprd21.prod.outlook.com https://git.postgresql.org/pg/commitdiff/c2c618ff1137f9ef58827f57e4ec0f97453e454e
防止测试中的排序规则变化。讨论:https://postgr.es/m/YW/MYdSRQZtPFBWR@paquier.xyz https://git.postgresql.org/pg/commitdiff/cd124d205c42a623b68cd155ace94cc376851b78
Daniel Gustafsson 推送
修复 pg_basebackup 和 pg_dump 中的 sscanf 限制。确保字符串解析受目标缓冲区大小的限制。在 pg_basebackup 中,服务器发送的可用值限制为两个字符,因此不存在溢出风险。在 pg_dump 中,缓冲区受 MAXPGPATH 限制,因此必须通过预处理器扩展插入限制,并将缓冲区增加一个以容纳终止符。这里不存在溢出风险,因为在这种情况下,扫描的缓冲区小于目标缓冲区。将 pg_basebackup 修复反向移植到引入它的 11 版本,并将 pg_dump 修复一直反向移植到 9.6 版本。审核人:Tom Lane 讨论:https://postgr.es/m/B14D3D7B-F98C-4E20-9459-C122C67647FB@yesql.se 反向移植范围:11 和 9.6 https://git.postgresql.org/pg/commitdiff/1d7641d51a51aa00dff685022fab6c03be8f8af8
修复 TOC 文件错误消息打印中的错误。如果无法解析 blob TOC 文件,则错误消息无法打印文件名,因为保存该文件名的变量被用于解析的目标缓冲区所遮蔽。当文件名解析失败时,错误将打印一个空字符串:./pg_restore -d foo -F d dump pg_restore: error: invalid line in large object TOC file "": .. ..而不是预期的错误消息:./pg_restore -d foo -F d dump pg_restore: error: invalid line in large object TOC file "dump/blobs.toc": .. 通过重命名这两个变量来修复,因为共享名称太通用,无法存储任一变量并仍然传达该变量的含义。一直反向移植到 9.6 版本。审核人:Tom Lane 讨论:https://postgr.es/m/A2B151F5-B32B-4F2C-BA4A-6870856D9BDE@yesql.se 反向移植范围:9.6 https://git.postgresql.org/pg/commitdiff/998d060f3db79c6918cb4a547695be150833f9a4
重构 sslfiles Makefile 目标以方便使用。用于 TLS 测试的证书和密钥对的 Makefile 处理变得非常难以使用。添加新证书而无需重新生成所有内容过于复杂。此补丁重构了 sslfiles make 目标,使得添加新证书仅需添加一个 .config 文件,将其添加到 Makefile 的顶部,然后运行 make sslfiles。改进:- 除了 CRL 目录外,文件间依赖项应已修复。- 新证书具有基于当前时间的序列号,从而减少冲突的机会。- CA 索引状态是按需创建的,并在 Make 运行结束时自动清理。- *.config
文件现在是自包含的;一个证书需要一个配置文件而不是两个。- 减少了重复,以及一些不需要的代码(和可能的复制粘贴错误)。- 所有配置文件都位于 conf/ 目录下。该目标被移动到其自己的 makefile 中,以避免与全局 make 设置冲突。作者:Jacob Champion pchampion@vmware.com 审核人:Michael Paquier michael@paquier.xyz 讨论:https://postgr.es/m/d15a9838344ba090e09fd866abf913584ea19fb7.camel@vmware.com https://git.postgresql.org/pg/commitdiff/b4c4a00eada3c512e819e9163114a5ad1606bc7e
修复 32 位 Perl 上的 SSL 测试。证书序列号生成在 b4c4a00ea 中更改为使用当前时间戳。因此,测试框架必须使用“openssl x509”查询证书的序列号,该命令以十六进制格式输出序列号。将序列号转换为与 pg_stat_ssl 中的匹配的整数格式需要 64 位 Perl。当测试使用 32 位 Perl 时,这会添加一个检查整数的回退。根据构建场成员 prairiedog 上的失败。讨论:https://postgr.es/m/0D295F43-806D-4B3F-AB98-F941A19E0271@yesql.se https://git.postgresql.org/pg/commitdiff/0c04342b1d3dd5b24f795f94874163be8e21710e
Tom Lane 推送
删除 transformExpressionList() 中的虚假断言。我认为当我添加此断言时(在提交 8f889b108 中),我只考虑了在 INSERT 和 VALUES 的顶层使用 transformExpressionList。但它也被 transformRowExpr() 调用,后者肯定会出现在 UPDATE 目标列表中,因此假设 p_multiassign_exprs 必须为空是不合适的。此外,由于不希望输入包含 ResTargets,因此也没有理由包含 MultiAssignRefs。因此,此代码无需关注 p_multiassign_exprs 的状态,我们应该删除此断言。根据 ocean_li_996 的错误 #17236。它已经错误多年了,因此反向移植到所有受支持的分支。讨论:https://postgr.es/m/17236-3210de9bcba1d7ca@postgresql.org https://git.postgresql.org/pg/commitdiff/697dd1925f418c9f54ee1fd1cefbc613d6504b1f
修复对复合类型域数组的赋值。如果数组元素是域而不是普通复合类型,则类似“UPDATE ... SET fld[n].subfld = whatever”的更新将失败。这是因为 isAssignmentIndirectionExpr() 无法处理在这种情况下将出现在表达式树中的 CoerceToDomain 节点。结果通常是崩溃,即使我们意外地没有崩溃,我们也无法正确保留同一数组元素的其他字段。根据 Onder Kalaci 的报告。反向移植到引入域数组的 v11。讨论:https://postgr.es/m/PH0PR21MB132823A46AA36F0685B7A29AD8BD9@PH0PR21MB1328.namprd21.prod.outlook.com https://git.postgresql.org/pg/commitdiff/3e310d837a9b3de8ad977c0a3e2a769bcdf61cc9
pg_dump:重组 getTables()。与 047329624、ed2c7f65b 和 daa9fe8a5 的思路相同,通过只保留一份在所有服务器版本中相同的查询部分来减少代码重复;并使条件控制最小量的代码。这也摆脱了我们之前在这里拥有的用于完成相同结果的各种不同方法的混乱组合。同时,确保该函数的三个相关部分都以相同的顺序列出字段。这当然只是整洁主义。讨论:https://postgr.es/m/1240992.1634419055@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/4438eb4a495c977d8ac485dd6e544c2b6e077deb
改进 pg_regress.c 的用于发出 psql 命令的基础设施。支持向单个 psql 调用发出多个“-c 命令”开关。这允许将以前需要两次或更多后端启动的一些内容合并到单个会话中。特别是,我们可以在 -c 命令之一中发出 DROP DATABASE,而不会出现“DROP DATABASE cannot run inside a transaction block”。除了减少所需会话的数量外,此补丁还抑制了在 pg_regress 的 DROP DATABASE(或 ROLE)IF NOT EXISTS 调用期间以前生成的“NOTICE: database "foo" does not exist, skipping”的干扰。这使我们更接近在成功的构建/测试期间不看到任何消息的理想状态。这也消除了一些对发出命令长度的硬编码限制。我认为我们没有接近触及这些限制,但消除限制令人欣慰。我编写的补丁,但感谢 Nathan Bossart 发起讨论。讨论:https://postgr.es/m/DCBAE0E4-BD56-482F-8A70-7FD0DC0860BE@amazon.com https://git.postgresql.org/pg/commitdiff/f45dc59a38cab1d2af6baaedb79559fe2e9b3781
文档:澄清 simplehash.h 的一个关键且未记录的方面。我刚刚因为尝试使用 pg_malloc 而不是 pg_malloc0 而被这个问题困扰。通过不留下此 API 细节的未记录,可以节省下一个黑客的一些时间。https://git.postgresql.org/pg/commitdiff/b1ce6c284366ce1dae120f5d10dd59e8804322ee
pg_dump:修复了非全局默认权限的错误转储。非全局默认权限条目应按原样转储,而不是相对于其对象类型的默认 ACL。这通常只会在全局条目中撤销一些默认权限,然后想在非全局条目中再次授予它们时才重要。根据 Boris Korzun 的报告。这是一个旧错误,因此反向移植到所有受支持的分支。Neil Chen,Masahiko Sawada 的测试用例。讨论:https://postgr.es/m/111621616618184@mail.yandex.ru 讨论:https://postgr.es/m/CAA3qoJnr2+1dVJObNtfec=qW4Z0nz=A9+r5bZKoTSy5RDjskMw@mail.gmail.com https://git.postgresql.org/pg/commitdiff/2acc84c6fd299125702c8a8af13820abcc0d4891
修复 simplehash.h 中 sh_error() 的前端版本。该代码不期望 sh_error() 返回,但使此标头可在前端使用的补丁没有得到这个备忘录。在这里,在决定是否调用 sh_error() 的测试中添加 unlikely(),并添加我们的标准版权声明。Andres Freund 指出。反向移植到引入此前端支持的 v13。讨论:https://postgr.es/m/0D54435C-1199-4361-9D74-2FBDCF8EA164@anarazel.de https://git.postgresql.org/pg/commitdiff/974aedcea46dfd0119eea2fbb2eeacd232596f05
在 pg_dump 中,使用 simplehash.h 按 OID 查找可转储对象。创建一个哈希表,该表按 CatalogId(即,目录 OID + 对象 OID)索引可转储对象。使用它来替换以前的 catalogIdMap 数组,以及各种其他单目录索引数组,以及扩展成员资格映射。原则上,对于具有许多对象的数据库,这应该更快,因为查找现在是 O(1) 而不是 O(log N)。但是,似乎这些查找在上下文中几乎可以忽略不计,因此无法衡量整体性能变化。但是,只有一个查找数据结构要维护使代码更简单和更灵活,所以让我们这样做。讨论:https://postgr.es/m/2595220.1634855245@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/92316a4582a5714d4e494aaf90360860e7fec37a
修复 pg_dump 中的少量内存泄漏。我通过在 "valgrind --leak-check=full" 下运行 pg_dump 发现了这些问题。 flagInhIndexes() 和 getIndexes() 中的更改,将之前分配一个仅使用其中一部分元素的数组改为单独分配实际需要的对象。之前的代码浪费了一些内存,但更重要的是,它混淆了 valgrind 的泄漏跟踪。 collectComments() 和 collectSecLabels() 仍然是 valgrind 报告中的主要污点,因为它们为了避免大量的 strdup,没有 PQclear 它们的查询结果。这是一个有争议的权衡,但我在这里不修改它;即将到来的补丁将修改这些函数,足以证明更改这种权衡是合理的。 https://git.postgresql.org/pg/commitdiff/70bef494000e4dbbeca0f0a40347ca1747aea701
Andres Freund 推送
Amit Kapila 推送
Andrew Dunstan 推送
将模块构建目录添加到 TAP 测试的 PATH 中。对于非 MSVC 构建,它是 make 的 $(CURDIR),而对于 MSVC 构建,它是 $topdir/$Config/$module。该目录作为 PATH 中的第二个元素添加,以便安装位置优先,但添加的 PATH 元素优先于 PATH 的其余部分。这样做的原因是允许测试找到未安装的已构建产品,例如 libpq_pipeline 测试驱动程序。 libpq_pipeline 测试被调整以利用这一点。基于 Andres Freund 的建议。回溯修复到版本 14。讨论:https://postgr.es/m/4941f5a5-2d50-1a0e-6701-14c5fefe92d6@dunslane.net https://git.postgresql.org/pg/commitdiff/f4ce6c4d3a30ec3a12c7f64b90a6fc82887ddd7b
将 Perl 测试模块移动到更好的命名空间。我们的 TAP 测试框架中的五个模块都具有顶级命名空间中的名称。这是不明智的,因为即使我们不将它们导出到 CPAN,这些名称也可能会泄漏,例如,如果它们被 RPM 构建过程导出。因此,我们将模块移动到 PostgreSQL::Test 命名空间。在此过程中,PostgresNode 重命名为 Cluster,TestLib 重命名为 Utils。 PostgresVersion 简单地变为 PostgreSQL::Version,以避免可能对它所表示的版本产生混淆。讨论:https://postgr.es/m/aede93a4-7d92-ef26-398f-5094944c2504@dunslane.net 由 Erik Rijkers 和 Michael Paquier 审查 https://git.postgresql.org/pg/commitdiff/b3b4d8e68ae83f432f43f035c7eb481ef93e1583
Noah Misch 推送
避免 RelationBuildDesc() 中影响 CREATE INDEX CONCURRENTLY 的竞争条件。 CIC 和 REINDEX CONCURRENTLY 假设后端看到它们的目录更改不晚于每个后端下一次事务启动。当后端在 CIC 索引上运行 RelationBuildDesc() 的过程中吸收了相关的失效时,这一点未能保持。使用结果索引的查询可能会静默地找不到行。通过使 RelationBuildDesc() 循环直到完成,而不接受相关的失效,修复了未来索引构建的问题。可能需要重新索引以从过去的事件中恢复;REINDEX CONCURRENTLY 就足够了。回溯修复到 9.6(所有受支持的版本)。Noah Misch 和 Andrey Borodin,由 Andres Freund 审查(在早期版本中)。讨论:https://postgr.es/m/20210730022548.GA1940096@gust.leadboat.com https://git.postgresql.org/pg/commitdiff/fdd965d074d46765c295223b119ca437dbcac973
修复最新的预备事务的 CREATE INDEX CONCURRENTLY。提交 8a54e12a38d1545d249f1402f66c8cde2837d97c 的目的是解决这个问题,并且当 PREPARE TRANSACTION 在 CIC 查找锁冲突之前完成时,它就足够了。否则,事情仍然会出错。和以前一样,在启用预备事务的情况下使用过 CIC 的集群中,使用结果索引的查询可能会静默地找不到行。可能需要重新索引以从过去的事件中恢复;REINDEX CONCURRENTLY 就足够了。通过使 CIC 等待任意最新的预备事务以及可能仍会 PREPARE TRANSACTION 的普通事务,修复了未来索引构建的问题。作为其中的一部分,在调用 ProcArrayClearTransaction() 之前,让 PREPARE TRANSACTION 将锁转移到其虚拟 PGPROC。回溯修复到 9.6(所有受支持的版本)。Andrey Borodin,由 Andres Freund 审查(在早期版本中)。讨论:https://postgr.es/m/01824242-AA92-4FE9-9BA7-AEBAFFEA3D0C@yandex-team.ru https://git.postgresql.org/pg/commitdiff/3cd9c3b921977272e6650a5efbeade4203c4bca2