PostgreSQL 15即将推出(3)psql的改进

首先

喵~。
這次我們來看看大家喜愛的psql的PostgreSQL 15改進項目。
備註:由於目前只是beta1版本,因此未來可能會有更改。

项目改进摘要

PostgreSQL 15中也包含了许多对psql的改进项。

    • psqlの \copyコマンドの性能向上

 

    • psqlコマンド \getenv の追加

 

    • psqlの\dl/, lo_listの’+’オプションによるオブジェクト権限表示の追加

 

    • \dconfig コマンドの追加

 

    • \weatch コマンドがページャに対応

 

    • クエリ内のダブルハイフンのコメントをサーバに送信するようになった

 

    • ダブルハイフンのコメントマーカーを挿入するようにpsqlのreadline機能を改善

 

    • 複数問い合わせ結果をpsqlが全て表示するようになった

 

    • タブ補完を改良

 

    • psqlのサポートをPostgreSQL 9.2以降が動作するサーバに限定

 

    • psql の \password コマンドを改善する(リリースノート未記載)

 

    psqlの絵文字の幅の計算の問題を改善(リリースノート未記載)

改善项目的详细内容

我们将浏览以下改善项目的详细信息。
为了更好地比较PostgreSQL 14,我们记录了两个版本的行为。

提高 psql 中 \copy 命令的性能

psql提供了一个名为COPY的元命令。
它的作用正如其名称所示,将位于客户端(psql)能够识别的位置的文件/程序解析为可读取的一次性加载COPY命令。

我在本地环境中进行了比较,看看使用COPY命令进行批量加载或转储的速度提高了多少。

用于测量的桌子 yú cè de

定义一个UNLOGGED TABLE以排除WAL写入的影响。

CREATE UNLOGGED TABLE test (id int, num_data numeric, txt_data text);

在这个表中插入1000000条随意的值,如下所示。

INSERT INTO test VALUES (generate_series(1, 1000000), random(), md5(CLOCK_TIMESTAMP()::text));

将加载的表格通过COPY TO命令转储到一个随意的位置。

进行测量

所以,将这个已删除的文件

    • psqlの\copy

SQLコマンドのCOPY
を使って、TRUNCATEして空にしたテーブルにロードしてみる。ロード後にはまたTRUNCATEして空にしておく。
ロード処理の時間はpsqlの\timingをONにしておいて取得する。
これを3回測定して平均値をとってみる。

结局 (jié jú)

Improve performance of psql's yen-copy command.png

当观察到\psql的处理时间时,可以明显发现PostgreSQL 15beta1的速度更快。
另外,就SQL命令COPY而言,在PostgreSQL 15beta1中也稍微有所提升,但差距并不大。
因此可以确定,通过这个结果可以判断\copy自身的性能已经提升了。

可以提供的信息

这个改进是在Commitfest 2021-07中提交的。
对于psql中的\copy from命令,将数据以更大的块发送到服务器。

添加psql命令\getenv的功能

新增了一个名为\getenv的psql命令,用于将运行psql的环境的环境变量设置为psql变量。当启动PostgreSQL 15的psql并显示帮助\?时,帮助信息将显示以下命令。

test-# \?
General
  \copyright             show PostgreSQL usage and distribution terms
(中略)
Operating System
  \cd [DIR]              change the current working directory
  \getenv PSQLVAR ENVVAR fetch environment variable
  \setenv NAME [VALUE]   set or unset environment variable
  \timing [on|off]       toggle timing of commands (currently off)
  \! [COMMAND]           execute command in shell or start interactive shell

这个 \getenv 命令带有两个参数。

    • 最初の引数PSQLVARは任意のpsql変数を指定する。

 

    2番目の引数ENVVARにはpsqlを起動した環境に設定されている環境変数(実装は見ていないけどgetenvシステムコールで取得できるもの?)を指定する。

假设在bash上已设置以下环境变量。

$ export VOICE="にゃーん"
$ echo $VOICE
にゃーん
$

在这个环境中启动psql,并使用\getenv命令来将环境变量的值设置给psql变量voice,如下所示。
所设置的psql变量可在查询内使用。

test=# \getenv voice VOICE
test=# SELECT :'voice';
 ?column?
----------
 にゃーん
(1 row)

test=#

作为更实用的用法之一,可以先将表名设置为环境变量,然后使用\getenv命令执行脚本,或者通过条件分支(\if等)从环境变量中获取要评估的变量值,根据环境变量的设置值来改变程序的运行方式,也许可以用于这样的用途。

请提供相关数据

这个改进在Commitfest列表中找不到。
如果搜索ML,找到pgsql-commiters的这封邮件可能是相关的。
pgsql:在psql中添加一个\getenv命令。

使用psql的\dl和\lo_list命令的’+’选项可以添加对象权限的显示

在PostgreSQL 15中,\dl,lo_list是一个显示大对象列表的psql命令。通过添加+选项,可以显示具有对每个大对象访问权限(SELECT/UPDATE)的用户信息。

PostgreSQL 15 –> PostgreSQL 15 版本

postgres=# \dl
         Large objects
  ID   |  Owner   | Description
-------+----------+-------------
 10001 | postgres |
(1 row)

postgres=# \dl+
                     Large objects
  ID   |  Owner   |  Access privileges   | Description
-------+----------+----------------------+-------------
 10001 | postgres | postgres=rw/postgres+|
       |          | user_a=w/postgres   +|
       |          | user_b=r/postgres    |
(1 row)

postgres=# \lo_list
         Large objects
  ID   |  Owner   | Description
-------+----------+-------------
 10001 | postgres |
(1 row)

postgres=# \lo_list+
                     Large objects
  ID   |  Owner   |  Access privileges   | Description
-------+----------+----------------------+-------------
 10001 | postgres | postgres=rw/postgres+|
       |          | user_a=w/postgres   +|
       |          | user_b=r/postgres    |
(1 row)

postgres=#

此外,尽管在PostgreSQL 14的psql中可以使用\dl+命令,但显示的信息与\dl命令相同。

请提供相关资料

这个改进在2021-03的Commitfest中已经提交。
psql: 通过\dl+命令列出大对象权限。

在中国本土用中文重新表述以上内容,只需要一个选项:

添加 “dconfig” 命令。

个人对于这次改进项目最喜欢的是\dconfig命令。它是psql中用于显示服务器变量的命令。虽然早期的PostgreSQL命令SHOW也有显示服务器变量名和设置值的功能,但\dconfig和SHOW的主要区别在于\dconfig可以进行模式匹配。

例如,如果要显示一个名为max_parallel_workers_per_gather的参数(长而且不易记忆),可以使用下面的模式匹配字符提取。

test=# \dconfig max*para*gather
    List of configuration parameters
            Parameter            | Value
---------------------------------+-------
 max_parallel_workers_per_gather | 2
(1 row)

test=#

此外,在SHOW命令中无法使用如上所示的模式匹配。喵喵。

test=# SHOW max*para*gather;
ERROR:  syntax error at or near "*"
LINE 1: SHOW max*para*gather;
                ^

对于我这样记不住参数名的人来说,这真是太方便了。当使用SHOW命令显示个别参数值时,输入长参数名真是麻烦。但是,这样一来,参数名越来越容易忘记了…笑

就个人而言,我觉得有点蹊跷的是,为什么这个psql命令的名称不是\show,而是被命名为\dconfig呢?

参考信息

这个改进项目在Commitfest的列表中没有出现。
搜索hackers-ml,似乎2021-04-07的电子邮件是第一次提到它。
pgsql: psql: 添加\dconfig命令以显示服务器的配置参数。
因此,它可能不在Commitfest 2022-03的列表中。
也许,这个Commitfest 2022-03与这个提交有关。
修复psql的模式处理。

weatch命令支持分页功能。

psql中有一个功能叫做\watch命令。它可以重复执行上一次在psql中执行的命令,并且可以根据指定的秒数进行循环执行,非常适合使用SQL进行临时监视。
这个命令以前不支持分页,但是从PostgreSQL 15开始,可以通过指定的PAGER命令进行分页控制了。

要以分页器命令控制watch命令的结果,需要在环境变量PSQL_WATCH_PAGER中设置分页器命令(例如less),然后执行psql命令时即可使用。

比如,在bash上设置`export PSQL_WATCH_PAGER=”less”`并启动psql,执行一条生成20行结果的SELECT语句。

$ export PSQL_WATCH_PAGER="less"
$ ~/pgsql/pgsql-15b1/bin/psql -p 10015 postgres
psql (15beta1)
Type "help" for help.

postgres=# SELECT generate_series(1,20), clock_timestamp();
 generate_series |        clock_timestamp
-----------------+-------------------------------
               1 | 2022-05-28 15:32:19.803739+09
               2 | 2022-05-28 15:32:19.803751+09
               3 | 2022-05-28 15:32:19.803752+09
(中略)
              13 | 2022-05-28 15:32:19.80376+09
              14 | 2022-05-28 15:32:19.803761+09
--More--

在这种状态下,当执行\watch命令时,\watch命令的输出结果将由less命令进行页面控制(请留意less命令的提示符:)。

postgres=# \watch 1


   Sat 28 May 2022 03:34:35 PM JST (every 1s)

 generate_series |        clock_timestamp
-----------------+-------------------------------
               1 | 2022-05-28 15:34:35.048501+09
               2 | 2022-05-28 15:34:35.048508+09
               3 | 2022-05-28 15:34:35.048509+09
(中略)
              10 | 2022-05-28 15:34:35.048515+09
              11 | 2022-05-28 15:34:35.048516+09
              12 | 2022-05-28 15:34:35.048517+09
:

请提供相关信息

这项改进在Commitfest 2021-07中被提交。
允许为psql的watch命令设置分页器。

现在已经可以将查询中的双连字符注释发送到服务器了。

在PostgreSQL中,可以使用双破折号(–)作为注释符号。双破折号后的内容,直到行末(换行符)都被视为注释。

SELECT 1 -- 1を返す``

从PostgreSQL 14之前,通过双破折号添加的注释在发送给服务器之前会在psql中被删除。
从PostgreSQL 15开始,双破折号添加的注释字符串也会被发送到服务器。

举例来说,当 log_statement=’all’ 被设置时,直到 PostgreSQL 14。

test=# SELECT 'nuko', -- にゃーん
2;
 ?column? | ?column?
----------+----------
 nuko     |        2
(1 row)

test=#

执行此查询时,双破折号注释中的“にゃーん”未记录在服务器日志中。

用简体中文翻译:
在PostgreSQL 14中的服务器日志。

2022-05-28 10:17:42.067 JST [20709] LOG:  statement: SELECT 'nuko',
        2;

然而,从PostgreSQL 15开始,即使在双减号注释中也将记录”にゃーん”到服务器日志中(使用pgaudit等审计扩展功能时也是一样)。

在 PostgreSQL 15 中的服务器日志。

2022-05-28 10:10:49.932 JST [20606] LOG:  statement: SELECT 'nuko', -- にゃーん
        2;

因此,使用PostgreSQL 15及更高版本的psql时,必须注意在双破折号注释中不要写下奇怪的注释。喵~

请提供相关资料

我找不到直接指向此改进项目的Commitfest项目。
尽管这个项目似乎与相关性有关,但我没有深究。
在PSQL交互模式历史记录中正确处理空白/注释行。

改善psql的readline功能,以插入双破折号作为注释标记。

目前无法了解现状和改善的内容。
阅读发行说明可知。

调整psql的readline meta-#,插入一个双连字符的注释标记(Tom Lane)
之前插入了一个无用的井号标记。

尽管在版本说明中写得很清楚,但仅从版本说明中无法确切了解问题是如何解决的。我也无法跟上机器学习的进展。我在执行 PostgreSQL 14.3 和 PostgreSQL 15 beta1 中带有双连字符且跨越多行的查询后,尝试通过 readline 显示命令历史记录,但我不太清楚有什么不同…。

可以提供的相关信息

我认为这项改进可能是在Commitfest 2022-01中提交的。
改进了PSQL交互模式历史记录中对空白/注释行的正确处理。

psql现在可以显示所有多个查询结果。

在 PostgreSQL 14 之前,如果从 psql 执行多个查询,只会显示最后一个查询的结果。
这里所说的”多个查询”一开始有点难以理解,但似乎是指由 \; 分隔的多个查询,类似于以下形式:
SELECT 1; SELECT 2; SELECT 3;

如果在PostgreSQL 14中运行以上查询,只会显示最后一个SELECT 3的结果。

test=# SELECT 1 \; SELECT 2 \; SELECT 3;
 ?column?
----------
        3
(1 row)

test=#

在PostgreSQL 15中,现在查询结果将显示如下。

postgres=# SELECT 1 \; SELECT 2 \; SELECT 3;
 ?column?
----------
        1
(1 row)

 ?column?
----------
        2
(1 row)

 ?column?
----------
        3
(1 row)

postgres=#

此外,通过禁用psql变量SHOW_ALL_RESULTS(这个变量也是从PostgreSQL 15引入的)可以将此功能还原为PostgreSQL 14的行为(仅显示最后一个查询)。

postgres=# \set SHOW_ALL_RESULTS off
postgres=# SELECT 1 \; SELECT 2 \; SELECT 3;
 ?column?
----------
        3
(1 row)

postgres=#

请提供相关资料

这个改进在Commitfest 2022-03中被提交。
psql – 添加SHOW_ALL_RESULTS选项

改良Tab补全

作为psql的一个易于使用的特点之一,可以提到它具有SQL语法的标签补全和数据库对象的标签补全功能。这是通过使用readline功能实现的。
(相反地,没有对readline提供支持的psql实际上非常难用。这是指附带在Windows版PostgreSQL中的psql!)

在发布说明中,只写了“改进了选项卡补完”,无法从发布说明中得知具体的改进内容…因此,我们只能在Commitfest中列出与psql选项卡补完相关的项目。

以下是本次类似TAB补全改进的项目。

    • CREATE PULICATION

 

    • ALTER TABLE .. VALIDATE CONSTRAINT

 

    大文字(upper charcter)入力時のTAB補完に対応

创造出版物

以下是与Commitfest(Commitfest 2021-07)相关的Commitfest项目:
为CREATE PUBLICATION命令提供psql标签自动完成功能。

我尝试了这封邮件中提到的几个案例,但在PostgreSQL 14.3和PostgreSQL 15 beta1中,TAB补全的行为没有差异。
是不是PostgreSQL 14.3已经进行了后补修复?

验证约束的表格结构。

对应的Commitfest项目(Commitfest 2022-01)如下。
psql:在ALTER TABLE .. VALIDATE CONSTRAINT的表格自动补全中排除有效的约束条件。

这也是PostgreSQL 14.3和PostgreSQL 15 beta1之间的TAB补全行为没有区别。
这可能意味着PostgreSQL 14.3已经进行了补丁处理?

支持对于输入大写字母时的TAB补全功能。

对应的Commitfest项目(Commitfest 2022-01)如下。
在psql中支持对大写字符输入的选项卡补全功能。

我没有完全理解议论邮件,但是SET/RESET/SHOW这三个命令的命令名称无论是小写还是大写,都可以通过TAB补全,这样解释可以吗?

只是,PostgreSQL 14.3和PostgreSQL 15 beta1在TAB补全行为上没有差异(尽管在参数展开方面,15版本的参数数量增加了,所以存在一些差别)。PostgreSQL 14.3已经进行了回补修复?

参阅资料

这个改进在以下的Commitfest活动中提交并得到了接受。

    • psql tab auto-complete for CREATE PUBLICATION

 

    • psql: exclude valid constraints in tab-complete for ALTER TABLE .. VALIDATE CONSTRAINT

 

    Support tab completion for upper character inputs in psql

仅支持运行PostgreSQL 9.2及更高版本的服务器的psql。

这个修正在Commitfest的列表中找不到。
在邮件列表中搜索,似乎这个问题适用于pgsql-commiters邮件列表中的内容。
pgsql:删除对9.2之前服务器版本的psql支持。

只需要一种选择: 由于PostgreSQL 9.1早已到达终止生命周期,所以可能不会有太多情况导致困扰。不过,从PostgreSQL 15开始,如果尝试连接到过时的服务器版本,将会收到警告。

实际上,在搭建PostgreSQL 9.1.24服务器并与PostgreSQL 15 beta1进行连接时,会出现一些psql功能可能无法正常工作的警告。

但是请注意,仅会显示警告而不会拒绝连接。

$ /home/ec2-user/pgsql/pgsql-9.1/bin/pg_ctl -D /tmp/pg091 -l logfile start
server starting
[ec2-user@ip-10-0-1-10 postgresql-9.1.24]$ ~/pgsql/pgsql-15b1/bin/psql -p 10091 postgres
psql (15beta1, server 9.1.24)
WARNING: psql major version 15, server major version 9.1.
         Some psql features might not work.
Type "help" for help.

postgres=# SELECT version();
                                                    version
----------------------------------------------------------------------------------------------------------------
 PostgreSQL 9.1.24 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 7.3.1 20180712 (Red Hat 7.3.1-13), 64-bit
(1 row)

postgres=#

改善 psql 中的 \password 命令

这个改进在Commitfest 2021-11中已经被提交。
改进psql的\password命令。
虽然原因不明,但在PostgreSQL 15 beta1的发布说明中没有提到这个项目。

根据我的理解(在实践中试过的感觉),

    • PostgreSQL 14までは、\passwordでパスワード変更を試みている最中には、CTRL+Cでの中断はできない。

 

    PostgreSQL 15では、\passwordでパスワード変更を試みている最中に、CTRL+Cでの中断が可能になった

我对此的解释是,但不知道是否正确……(我无法跟上机器学习的讨论……)

改善了psql中用于计算表情符号宽度的问题

我还没有确认这项改进内容……
虽然在发布说明中没有提到,但在Commitfest中提交的项目中包含了这项内容。

暫時先試著在psql上執行包含表情符號的查詢(使用Putty日文版+自製補丁版執行環境), 但我無法察覺到PostgreSQL 14.3和PostgreSQL 15 beta1之間的差異。(兩者都稍微有些偏差)

“PostgreSQL 14.3” 可以被改写为 “PostgreSQL 14.3 版本”。

$ ~/pgsql/pgsql-15b1/bin/psql -U postgres -p 10014 test -e -f emoji.sql
CREATE TEMP TABLE hoge (n text, i text, v text);
CREATE TABLE
INSERT INTO hoge VALUES
('elephant', '?', 'paon'),
('cat', '?', 'nya-n'),
('dolphin', '?', 'kyu-')
;
INSERT 0 3
SELECT * FROM hoge;
    n     | i  |   v
----------+----+-------
 elephant | ? | paon
 cat      | ? | nya-n
 dolphin  | ? | kyu-
(3 rows)

PostgreSQL 15 beta1 15贝塔1版

$ ~/pgsql/pgsql-15b1/bin/psql -U postgres -p 10015 test -e -f emoji.sql
CREATE TEMP TABLE hoge (n text, i text, v text);
CREATE TABLE
INSERT INTO hoge VALUES
('elephant', '?', 'paon'),
('cat', '?', 'nya-n'),
('dolphin', '?', 'kyu-')
;
INSERT 0 3
SELECT * FROM hoge;
    n     | i  |   v
----------+----+-------
 elephant | ? | paon
 cat      | ? | nya-n
 dolphin  | ? | kyu-
(3 rows)

提供参考的信息

这个改进已经在 Commitfest 2021-09 中提交并合并。
在 psql 中计算表情符号的宽度出了问题。

最后

由于发布说明中未提及的项目、未在Commitfest中列出的改进项目以及已在PostgreSQL 14.3中解决的项目存在,这次调查出人意料地困难。

我一直都在使用psql这个工具来操作PostgreSQL,令人惊讶的是它仍在不断进化,每次升级版本时我都会感叹不已。
它太方便了,以至于我不再使用pgAdmin4等图形界面的客户端接口了呢…。

bannerAds