https://archives.postgresql.org/pgsql-jobs/2021-11/
2022 Nordic PGDay 将于2022年3月22日在芬兰赫尔辛基的希尔顿赫尔辛基斯特兰德酒店举行。论文征集(CfP)将于2021年12月31日截止,请 在此 提交。
Planet PostgreSQL:https://planet.postgresql.org/
本周 PostgreSQL 周报由 David Fetter 提供。
请在太平洋标准时间(PST8PDT)周日晚上3:00之前将新闻和公告发送至 david@fetter.org。
Peter Geoghegan 提交
移除 lazy_scan_heap 并行 VACUUM 的注释块。该注释块不应出现在关于 lazy_scan_heap 执行任务的非常高层次的讨论旁边。在 vacuumlazy.c 的顶部已经有一个类似的、更长的注释块,其中直接提到了 lazy_scan_heap。 https://git.postgresql.org/pg/commitdiff/97f5aef609ce51422934b7dbdba599a7de4dbafd
恢复对标记为 full 的页面的 HOT 考虑。Commit 2fd8685e7f 简化了 heap_update() 中对已修改属性的检查。其中包括了一个微优化,影响了标记为 PD_PAGE_FULL 的页面:为了节省几个周期用于确定 HOT 安全性,甚至不尝试使用 HOT。假设是这次不会成功,因为它上次也不会成功。移除此微优化。它只能节省大部分 heap_update() 调用所消耗的周期,这似乎不值得增加的复杂性。尽管短期内平均节省了一些周期,但对于某些工作负载来说,随着时间的推移,反复应用微优化可能会导致更差的结果。作者:Peter Geoghegan pg@bowt.ie 审阅者:Álvaro Herrera alvherre@alvh.no-ip.org 讨论:https://postgr.es/m/CAH2-WznU1L3+DMPr1F7o2eJBT7=3bAJoY6ZkWABAxNt+-afyTA@mail.gmail.com https://git.postgresql.org/pg/commitdiff/1a6f5a0e876306293fda697e7820b404d5b93693
更新 vacuumlazy.c 的高层次注释。更新 vacuumlazy.c 文件头部的注释(以及 lazy_scan_heap 函数上方的注释),这些注释大部分是在引入 HOT 优化之前编写的,当时 lazy_scan_heap 做的事情少得多,并且在第一次堆扫描时并没有真正进行剪枝。由于 lazy_scan_heap 现在将更多工作外包给了低级函数,因此通过讨论决定每个阶段发生顺序的高层不变量来介绍该函数是有意义的。同时,淡化了我们耗尽 TID 内存的情况,因为推迟讨论这个问题可以更容易地讨论核心问题。最后,移除头部注释中关于并行 VACUUM 的讨论。这些内容并没有太多价值,而且位置不对。 https://git.postgresql.org/pg/commitdiff/12b5ade9023f3ecaddcbc423a22dc284c91c79f6
vacuumlazy.c:优先使用“cleanup lock”一词。“super-exclusive lock”是“cleanup lock”的一个可接受的同义词。即使如此,在同一个文件中来回切换术语会引起混淆。在 vacuumlazy.c 中标准化为“cleanup lock”。根据 Andres Freund 的反馈。 https://git.postgresql.org/pg/commitdiff/276db875d4f9be2911582f367596d444d6986c77
Fujii Masao 提交
Peter Eisentraut 提交
向 fmgr magic block 添加 ABI 额外字段。这允许派生产品有意地使其 fmgr ABI 不兼容,并提供清晰的错误消息。讨论:https://postgresql.ac.cn/message-id/flat/55215fda-db31-a045-d6b7-d6f2d2dc9920%40enterprisedb.com https://git.postgresql.org/pg/commitdiff/d6d1dfcc99e3dd6e70e2a7024924e491bb7a9670
修复格式占位符不正确的问题。同时为底层变量选择更好的类型以使其更加一致。 https://git.postgresql.org/pg/commitdiff/fb5961fd13b1262df280e400645bdf4ed192f058
移除不必要的 Python include。自 Python 2.4 起,包含 <compile.h> 和 <eval.h> 就不是必需的了,因为它们是通过 <Python.h> 包含的。此外,<eval.h> 将在 Python 3.11 中被移除。因此,移除这些 include。审阅者:Tom Lane tgl@sss.pgh.pa.us 讨论:https://postgresql.ac.cn/message-id/flat/84884.1637723223%40sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/99e4d24a9d77e7bb87e15b318e96dc36651a7da2
更新注释。在多个地方需要指出,tuple 描述符不包含 pg_attribute 的可变长度字段。这在添加 attacl 时开始,但此后又添加了更多字段,并且这些注释没有得到一致的更新。重新措辞以使目的更清晰,我们不必不断更新它们。 https://git.postgresql.org/pg/commitdiff/36cb5e7c512bef394c9288786c62ef0eb1e891ba
Álvaro Herrera 提交
在注释中添加缺失的词。由 Zhihong Yu 报告。讨论:https://postgr.es/m/CALNJ-vR6uZivg_XkB1zKjEXeyZDEgoYanFXB-++1kBT9yZQoUw@mail.gmail.com https://git.postgresql.org/pg/commitdiff/67385544ce672a9a53cfd51b39c1ff9048d65585
autovacuum:在几个地方改进措辞。autovacuum 代码中的一些字符串(一个 WARNING 和一些内存上下文名称)是在“worker”没有其他可能含义,只有“autovacuum worker”时编写的,但这早已成为过去。需要更具体地说明。此外,将 elog() 的 WARNING 改为 ereport(),以增加可翻译性。作者:Bharath Rupireddy bharath.rupireddyforpostgres@gmail.com 审阅者:Nathan Bossart bossartn@amazon.com 审阅者:Justin Pryzby pryzby@telsasoft.com 审阅者:Kyotaro Horiguchi horikyota.ntt@gmail.com 审阅者:Dilip Kumar dilipbalaut@gmail.com 审阅者:Masahiko Sawada sawada.mshk@gmail.com 讨论:https://postgr.es/m/CALj2ACX2UHp76dqdoZq92a7v4APFuV5wJQ+AUrb+2HURrKN=NQ@mail.gmail.com https://git.postgresql.org/pg/commitdiff/042412879e35791a65509f2786b4954a273466e5
在 XLogReaderAllocate 中更具体地说明 OOM。几个地方可以受益于添加 errdetail(),这与我们在其他地方已经做的一致;而那些无法承受 errdetail() 的地方可以得到一个更具描述性的主要消息。作者:Bharath Rupireddy bharath.rupireddyforpostgres@gmail.com 审阅者:Daniel Gustafsson daniel@yesql.se 审阅者:Julien Rouhaud rjuju123@gmail.com 讨论:https://postgr.es/m/CALj2ACV+cX1eM03GfcA=ZMLXh5fSn1X1auJLz3yuS1duPSb9QA@mail.gmail.com https://git.postgresql.org/pg/commitdiff/2fed48f48f7f2f7a6d6f6d020f046efe3c249828
修复 OVERWRITTEN_CONTRECORD 中损坏 LSN 的确定。在 commit ff9f111bce24 中,我混淆了页面上第一个记录的 LSN 的不一致定义,当上一个记录恰好在页面边界结束时。正确的 LSN 被调整为跳过 WAL 页面头;我设置 XLogReaderState->overwrittenRecPtr 时未能使用它,因此在 WAL 重放时,VerifyOverwriteContrecord 会拒绝重放继续超过该记录。回溯到 10 版本。9.6 版本也存在此 bug,但已不再维护。讨论:https://postgr.es/m/45597.1637694259@sss.pgh.pa.us https://git.postgresql.org/pg/commitdiff/44bd3ed332d6ad3207f38b3b6deb6083f0baddf5
记录 max_slot_wal_keep_size 的单位。文档说明中未能提及单位,并且缺乏关于可变性的说明。回溯到 13 版本。审阅者:Kyotaro Horiguchi horikyota.ntt@gmail.com 报告者:b1000101@pm.me 讨论:https://postgr.es/m/163760291192.26193.10801700492025355788@wrigleys.postgresql.org https://git.postgresql.org/pg/commitdiff/013bb6c8c0b5b0ac7948d7126685008505b3aa58
校对 vacuuumdb --analyze-in-stages 的文档说明。我犯了一些拼写错误,并且 Nikolai Berkoff 提出了措辞修改建议。讨论:https://postgr.es/m/VMwe7-sGegrQPQ7fJjSCdsEbESKeJFOb6G4DFxxNrf45I7DzHio7sNUH88wWRMnAy5a5G0-FB31dxPM47ldigW6WdiCPncHgqO9bNl6F240=@pm.me https://git.postgresql.org/pg/commitdiff/dd484c97f55be8336fcb41470768c5b8ae347d13
为 be-gssapi-common.h 添加头文件检查保护。将内容用一个测试包裹起来,以检查配置时是否启用了该功能,从而在没有安装 GSSAPI 的系统上抑制头文件检查工具。回溯到 12 版本(文件首次出现)。讨论:https://postgr.es/m/202111161709.u3pbx5lxdimt@alvherre.pgsql https://git.postgresql.org/pg/commitdiff/f744519326e1ce4774d0966f7848601a8327eeaa
Tom Lane 提交
在检查 TAP 测试所需的模块时,探测 $PROVE 而不是 $PERL。通常,“prove”和“perl”来自同一个 Perl 安装,但我们支持它们不来自同一个安装的情况(主要是因为 MSys 的 buildfarm 机器需要这个)。在这种情况下,AX_PROG_PERL_MODULES 是完全错误的,因为它检查的是“perl”拥有的内容。相反,创建一个包含所需模块的小型 TAP 测试脚本,并在“prove”下运行它。此更改后,我们不再需要 ax_prog_perl_modules.m4,因此将其移除。回溯到所有支持的分支,以方便 buildfarm。 (在 v10 中,这还回溯了 commit 264eb03aa 的效果。)Andrew Dunstan 和 Tom Lane,根据 Noah Misch 的观察。讨论:https://postgr.es/m/E1moZHS-0002Cu-Ei@gemulon.postgresql.org https://git.postgresql.org/pg/commitdiff/c4fe3199a6d65212537a59eb0d7e6fad22b9e903
修复 pg_dump --inserts 模式对带有已删除列的生成列。如果一个表包含一个生成列,该列前面有一个已删除的列,则 dumpTableData_insert 没有考虑已删除的列,并在错误的列中发出 DEFAULT 占位符。这导致还原时失败。默认的 COPY 代码路径没有这个 bug,这可能解释了为什么它没有更早被注意到。在修复此问题时,我们可以更智能地处理这种情况:(1)避免不必要地获取生成列的值,(2)如果我们使用 --column-inserts,也从输出中省略生成列。尽管这些模式的性能预计不如 COPY 路径,但我们也可以尽可能高效;这并没有增加太多复杂性。根据 Дмитрий Иванов 的报告。回溯到 v12(生成列在此版本中引入)。讨论:https://postgr.es/m/CAPL5KHrkBniyQt5e1rafm5DdXvbgiiqfEQEJ9GjtVzN71Jj5pA@mail.gmail.com https://git.postgresql.org/pg/commitdiff/0b126c6a4b00972f2f3533e1718bbe297e2851c2
使 perlcritic 保持安静。根据 buildfarm。 https://git.postgresql.org/pg/commitdiff/db3a660c6327a6df81a55c4aa86e6c0837ecd505
调整 pg_dump 中 cast 的优先级排序。当存储的表达式依赖于用户定义的 cast 时,后端会将依赖记录为对 cast 的实现函数——或者,如果没有涉及 cast 函数,只是 RelabelType 或 CoerceViaIO,则不会记录任何依赖。这对于 pg_dump 来说是问题的,因为其倾倒顺序可能不正确,导致还原失败。鉴于之前没有报告,风险并不高,但如果 cast 用于某个视图,而该视图的行类型随后用作其他函数的输入或结果类型,则可以证明这一点。(这会导致视图被提升到 dump 的函数部分,位于 cast 之前。)一个逻辑上万无一失的修复需要将 cast 的 OID 包含在表达式的解析形式中,然后 dependency.c 可以从中提取,之后存储的依赖关系将强制 pg_dump 做正确的事情。这样的更改将是相当大的入侵,肯定无法回溯。此外,由于我们希望使用 cast 语法的表达式等于(equal())通过显式函数调用做同样事情的表达式,因此 cast OID 字段必须具有特殊的忽略比较语义,这会使事情变得混乱。所以,让我们通过一个非常简单的 hack 来修复 pg_dump:更改对象类型的优先级顺序,使 cast 最初排在函数之前,紧随类型之后。这以一种相当直接的方式修复了没有实现函数的 cast 的问题。对于那些有实现函数的,实现函数将在依赖排序步骤中被提升到 cast 之前,因此我们仍然拥有有效的 dump 顺序。(我不确定这是否能提供完全没有问题的保证;但由于这种情况已经存在很多年了,之前没有任何报告,这可能在实践中足够了。)根据 Дмитрий Иванов 的报告。回溯到所有支持的分支。讨论:https://postgr.es/m/CAPL5KHoGa3uvyKp6z6m48LwCnTsK+LRQ_mcA4uKGfqAVSEjV_A@mail.gmail.com https://git.postgresql.org/pg/commitdiff/b55f2b6926556115155930c4b2d006c173f45e65
文档:改进 nextval()/setval() 的文档说明。澄清 nextval 和 setval 的结果在调用事务提交之前不保证持久。有些人似乎从“这些函数永远不会回滚”的陈述中得出相反的结论,因此重新措辞以避免这样说。讨论:https://postgr.es/m/CAKU4AWohO=NfM-4KiZWvdc+z3c1C9FrUBR6xnReFJ6sfy0i=Lw@mail.gmail.com https://git.postgresql.org/pg/commitdiff/4ac452e2285da347c75f5960ae211e183a87b57b
Michaël Paquier 提交
添加用于监视复制槽目录内容的 SQL 函数。此提交添加了一组函数,可以查看与复制槽相关的各种路径的内容:- pg_ls_logicalsnapdir,用于 pg_logical/snapshots/ - pg_ls_logicalmapdir,用于 pg_logical/mappings/ - pg_ls_replslotdir,用于 pg_replslot/
在构建脚本中添加对 Visual Studio 2022 的支持。文档和与 VS 相关的代码路径已更新以保持一致。与 2017 和 2019 版本类似,我们用于确定构建代码路径的 VS 版本和 nmake 版本仍然以自己的方式不一致。回溯到 10 版本,以便 buildfarm 成员能够在所有支持的稳定分支上使用此新版本的 Visual Studio。作者:Hans Buschmann 讨论:https://postgr.es/m/1633101364685.39218@nidsa.net 回溯到:10 https://git.postgresql.org/pg/commitdiff/b2265d305d81b0c1a2cec6c5b66a190a9e69e853
在写入文件头失败时移除无用的 LZ4 系统调用。如果写入 LZ4 文件头时发生错误,LZ4F_compressEnd() 会在 write() 的错误代码路径中被调用,然后调用 LZ4F_freeCompressionContext() 来完成清理。当前代码没有问题,但 LZ4F_compressEnd() 被证明是不必要的,因为此时没有内容需要刷新,所以将其移除。根据 Jeevan Ladhe 和 Robert Haas 的意见。讨论:https://postgr.es/m/CAOgcT0PE33wbD7giAT1OSkNJt=p-vu8huq++qh=ny9O=SCP5aA@mail.gmail.com https://git.postgresql.org/pg/commitdiff/f79962d8264b8d205ce45a8aa11d1b37f9592a81
修复 Windows 上使用标准流时的 fstat() 仿真。win32stat.c 中的 fstat() 仿真导致了与现有内存中调用者相关的两个问题,在使用流作为参数时因 EINVAL 而失败:- psql 的 \copy 在使用流时会崩溃。- pg_recvlogical 在使用 -f - 时会失败。主测试套件中的 copyselect.sql 测试覆盖了第一种情况,并且有针对第二种情况的 TAP 测试。然而,在这两种情况下,由于标准流总是被重定向,自动化测试并没有注意到这些问题,因此需要在 Windows 上使用终端才能重现。此问题已在 bed9075 中引入,问题的根源在于 GetFileInformationByHandle() 不能直接用于流,因此此提交添加了一个额外的代码路径来模拟并返回一组最符合实际情况的统计信息。请注意,重定向的流依赖于可以使用 GetFileInformationByHandle() 查询的句柄,但我们可以依赖 GetFinalPathNameByHandleA() 来检测这种情况。作者:Dmitry Koval、Juan José Santamaría Flecha 讨论:https://postgr.es/m/17288-6b58a91025a8a8a3@postgresql.org 回溯到:14 https://git.postgresql.org/pg/commitdiff/10260c794b211117a56ee2eb2deacf609bcca25f
阻止 ALTER TABLE .. DROP NOT NULL 应用于副本身份索引中的列。直接依赖于索引的副本身份依赖于一组属性,其中一个属性是此索引中定义的所有列都必须标记为 NOT NULL。ALTER TABLE DROP NOT NULL 逻辑上存在一个漏洞,其中有可能移除作为副本身份索引一部分的列的 NOT NULL 属性,因此阻止它以避免将来出现逻辑解码问题。主键的列也进行了相同的检查,因此修复很简单。作者:Tang Haiying、Hou Zhijie 审阅者:Dilip Kumar、Michael Paquier 讨论:https://postgr.es/m/OS0PR01MB6113338C102BEE8B2FFC5BD9FB619@OS0PR01MB6113.jpnprd01.prod.outlook.com 回溯到:10 https://git.postgresql.org/pg/commitdiff/f0d43947a1b0c30f0bf2c117cd78bf95a3161268
David Rowley 提交
允许 Memoize 在二进制比较模式下运行。Memoize 始终使用缓存键类型的哈希相等运算符来确定当前参数集是否与之前缓存的某个集合相同。某些类型(如浮点数),其中 -0.0 和 +0.0 在其二进制表示中不同,但被哈希相等运算符视为相等,可能会导致问题,因为除非连接使用相同的运算符,否则有可能正在使用的连接运算符可以区分这两个值。在这种情况下,我们可能会意外地从缓存中返回不正确的行。为了解决这个问题,我们在此添加了一个二进制模式到 Memoize,允许它通过按位比较而不是使用哈希相等运算符来将当前参数集与先前缓存的值进行比较。此二进制模式始终用于 LATERAL 连接,并且当任何连接运算符不可哈希时,它用于普通连接。报告者:Tom Lane 作者:David Rowley 讨论:https://postgr.es/m/3004308.1632952496@sss.pgh.pa.us 回溯到:14(Memoize 添加的版本) https://git.postgresql.org/pg/commitdiff/e502150f7d0be41e3c8784be007fa871a32d8a7f
当非键参数更改时刷新 Memoize 缓存。Memoize 节点下方的子计划可能包含来自 Memoize 节点上方的参数。如果此参数发生更改,缓存条目可能会因新的参数值而过时。以前 Memoize 错误地没有意识到这一点。我们在此通过在任何不是缓存键一部分的参数更改时刷新缓存来修复此问题。Bug:#17213 报告者:Elvis Pranskevichus 作者:David Rowley 讨论:https://postgr.es/m/17213-988ed34b225a2862@postgresql.org 回溯到:14(Memoize 添加的版本) https://git.postgresql.org/pg/commitdiff/1050048a315790a505465bfcceb26eaf8dbc7e2e
撤销“当非键参数更改时刷新 Memoize 缓存”。此操作撤销 commit 1050048a315790a505465bfcceb26eaf8dbc7e2e。 https://git.postgresql.org/pg/commitdiff/dad20ad4709f602b4827a1ab2b0e715f36c548c3
当非键参数更改时刷新 Memoize 缓存,第二版。Memoize 节点下方的子计划可能包含来自 Memoize 节点上方的参数。如果此参数发生更改,缓存条目可能会因新的参数值而过时。以前 Memoize 错误地没有意识到这一点。我们在此通过在任何不是缓存键一部分的参数更改时刷新缓存来修复此问题。Bug:#17213 报告者:Elvis Pranskevichus 作者:David Rowley 讨论:https://postgr.es/m/17213-988ed34b225a2862@postgresql.org 回溯到:14(Memoize 添加的版本) https://git.postgresql.org/pg/commitdiff/411137a429210e432f923264a8e313a9872910ca
Amit Kapila 提交
SnapBuild* 宏。SnapBuildOnDiskNotChecksummedSize 和 SnapBuildOnDiskChecksummedSize 的宏名在 slot.c 和 snapbuild.c 中相同。此补丁在 slot.c 中将它们重命名为 ReplicationSlotOnDiskNotChecksummedSize 和 ReplicationSlotOnDiskChecksummedSize,与其他宏类似。这使得 slot.c 中的所有宏名看起来一致。作者:Bharath Rupireddy 讨论:https://postgr.es/m/CALj2ACVZo-piDGzBOJRY4ob=_goFR6t9DhZMDMjJWN7LQs34Aw@mail.gmail.com https://git.postgresql.org/pg/commitdiff/875e02c2dff34f1bc9f3832a4f83c34bf300eb9fRobert Haas 提交
修复检测不当时间线切换的边界情况失败。rescanLatestTimeLine() 包含一个保护机制,可以防止切换到从当前时间线在当前恢复点之前分叉的时间线,但如果时间线切换发生在第一个 WAL 记录(必须是检查点记录)被读取之前,该保护机制就不起作用。没有这个补丁,在这种情况下就可能发生不当的时间线切换。这是因为 rescanLatestTimeLine() 依赖于全局变量 EndRecPtr 来了解 WAL 重放的当前位置。然而,此时代码中的 EndRecPtr 存储的是最后一个已重放记录的终点,而不是当前正在重放的记录的起点或终点。因此,在任何记录被重放之前,它是零,这导致健全性检查总是通过。为了解决这个问题,明确地传递正确的时间线。我们想要的 EndRecPtr 值是来自 xlogreader 的值,它将是我们即将尝试读取的记录的起始位置,而不是全局变量,后者是我们成功读取的最后一条记录的结束位置。它们通常是相同的,但在上面描述的边界情况下并非如此。不回溯,因为在 v14 及更早版本的分支中,我们在这里使用了错误 TLI 和错误的 LSN。在 master 中,这由 commit 4a92a1c3d1c361ffb031ed05bf65b801241d7cdd 修复,但它及其先决补丁对于如此小的错误来说过于入侵,无法回溯。作者:我,审阅者:Amul Sul。讨论:http://postgr.es/m/CA+Tgmoao96EuNeSPd+hspRKcsCddu=b1h-QNRuKfY8VmfNQdfg@mail.gmail.com https://git.postgresql.org/pg/commitdiff/e7ea2fa342b008ae97e794b0fa2ee538ddcee3b7
xlog.c:移除全局变量 ReadRecPtr 和 EndRecPtr。在大多数地方,这些变量必然存储着 WAL 重放期间使用的 XLogReaderState 的同名成员的值,因为 ReadRecord() 在 XLogReadRecord() 返回后立即将结构成员的值赋给全局变量。然而,XLogBeginRead() 调整了结构成员但没有调整全局变量,因此在 XLogBeginRead() 之后和 XLogReadRecord() 完成之前,值可能不同。否则,它们必须是相同的。根据我的分析,唯一一个变量被引用但可能与其结构成员值不同的地方是 XLogPageRead 中对 EndRecPtr 的引用。因此,在其他所有使用全局变量的地方,我们可以直接切换到使用结构成员,并移除全局变量。然而,我们也可以,而且事实上应该,在 XLogPageRead() 中这样做,因为在该代码点,全局变量将实际存储我们要读取的记录的开始位置——要么是因为它是最后一个 WAL 记录的结束位置,要么是因为在读取最后一个记录后使用了 XLogBeginRead 来更改读取位置。另一方面,结构成员已经被更新为指向我们刚刚读取的记录的末尾。在其他地方,后者是我们传递给 emode_for_corrupt_record() 的参数,所以我们在这里也应该这样做。此补丁部分可能是一个 bug 修复,但我认为它没有重要的后果,所以不回溯。这里的重点是继续减少 xlog.c 中对全局变量的过度使用。讨论:http://postgr.es/m/CA+Tgmoao96EuNeSPd+hspRKcsCddu=b1h-QNRuKfY8VmfNQdfg@mail.gmail.com https://git.postgresql.org/pg/commitdiff/d2ddfa681db27a138acb63c8defa8cc6fa588922
Heikki Linnakangas 提交
Andres Freund 提交
Daniel Gustafsson 提交
修复 REVOKE ROLE 语句中的 GRANTED BY 支持。Commit 6aaaa76bb 添加了对 GRANT 和 REVOKE 语句中 GRANTED BY 子句的支持,但遗漏了对 REVOKE ROLE 情况下的角色检查。通过检查解析的角色是否与 CURRENT_ROLE/CURRENT_USER 要求匹配来修复,并添加一些测试。回溯到 v14(在此版本中引入了 GRANTED BY 支持)。讨论:https://postgr.es/m/B7F6699A-A984-4943-B9BF-CEB84C003527@yesql.se 回溯到:14 https://git.postgresql.org/pg/commitdiff/b2a459edfe645747744402f23de041e9c0a3cd93
添加 REVOKE ADMIN OPTION 的测试。REVOKE ADMIN OPTION FOR