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ú)

当观察到\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等图形界面的客户端接口了呢…。