暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

[译文] PostgreSQL 15来了(三)psql的改进

原创 通讯员 2022-05-31
989

介绍

这一次,我检查了每个人都喜欢的 PostgreSQL 15 改进项目psql
注:调查内容仍为beat 1时的内容,未来可能会有所变化。

改善项目概要

PostgreSQL 15 也psql有各种改进。

  • 改进了 psql 的 \copy 命令的性能
  • 添加 psql 命令\getenv
  • 通过\dl/的'+'选项添加对象权限显示,psql的lo_list
  • 添加\dconfig命令
  • \ weatch 命令支持寻呼机
  • 现在将查询中的双连字符注释发送到服务器
  • 改进了 psql 的 readline 功能以插入双连字符注释标记
  • Psql 现在显示所有多个查询结果
  • 改进的选项卡完成
  • 对运行 PostgreSQL 9.2 或更高版本的服务器的 psql 支持有限
  • 改进 psql 的 \password 命令(发行说明未提及)
  • 改进了 psql 中计算 emoji 宽度的问题(发行说明未提及)

改善项目详情

下面,我们将看看改进项目的细节。
与 PostgreSQL 14 相比,更容易理解的内容描述了两个版本中的行为。

改进了 psql 的 \copy 命令的性能

psql 有copy一个名为的元命令。
顾名思义,它使批量加载COPY命令可以被位于客户端(psql)可识别位置的文件/程序读取。

我比较了在我的环境中使用 \copy 命令进行批量加载和转储的速度。

测量表

定义UNLOGGED TABLE(因为我想消除WAL write的影响)如下。


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
    测量 3 次并取平均值。

结果

提高 psql 的日元复制 command.png 的性能

当然\psql,从处理时间来看,PostgreSQL 15 beta 1 明显更快。
SQL 命令COPY在 PostgreSQL 15 beta1 中也快了一点,但差别不大。
从这个结果\copy可以判断产品本身的性能得到了提高。


添加 psql 命令\getenv

psql\getenv添加了一个 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 变量。
  • 在第二个参数ENVVAR中,指定在psql启动的环境中设置的环境变量(我没有看到实现,但是getenv我可以通过系统调用得到它吗?)。

例如,假设在 bash 上设置了以下环境变量。


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

在此环境中启动 psql 并使用以下\getenv命令voice将环境变量的值设置为psql 变量。
set psql 变量也可以在查询中使用。


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

test=#

作为更实际的用法,在环境变量中设置表名,\getenv然后执行脚本使用,或者\if从环境变量中通过条件分支(等)获取要评估的变量并设置环境变量。将其用于此类目的,例如根据值更改操作。


通过\dl的'+'选项添加对象权限显示,psql的\lo_list

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

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一样的。


添加\dconfig命令

就个人而言,我最喜欢这次的改进项目。
\dconfig该命令是显示服务器变量的 psql 命令。
PostgreSQL 很早以前就有一个命令作为显示服务器变量名和设置值的功能,SHOW和它最大的区别是它做模式匹配。SHOW\dconfig\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显示单个参数值时输入长参数名很麻烦。
但是,参数名称似乎会因为这个而变得越来越好记……w

但是,我个人认为有点神秘的是为什么这个 psql 命令名称\show不是\dconfig.


\ weatch 命令支持寻呼机

psql 有\watch一个叫做命令的函数。这是在参数中指定的每个秒数之前重复执行从 psql 执行的命令,这通常用于使用 SQL 进行临时监视。
该命令过去不支持分页器,但从 PostgreSQL 15 开始,可以通过 PAGER 中指定的命令进行分页控制。

\watch要用分页器的命令来控制命令的结果,在环境变量中设置分页器的命令(例如less)PSQL_WATCH_PAGER并执行状态psql。

例如,在 bash 上设置,export PSQL_WATCH_PAGER="less"启动 psql,然后执行 SELECT 语句,产生 20 行的结果。


$ 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命令分页控制的(:注意提示少)。


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
:

现在将查询中的双连字符注释发送到服务器

--PostgreSQL 查询也可以使用双连字符 () 作为注释。
从双连字符到行尾(换行代码)的所有内容都被视为注释。


SELECT 1 -- 1を返す``

直到 PostgreSQL 14,这个双连字符注释在发送到服务器之前在 psql 中被删除。
从 PostgreSQL 15 开始,双连字符注释字符串也被发送到服务器。

例如,log_statement='all'最多 PostgreSQL 14 when 被设置


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,你必须小心不要在双连字符注释中写出奇怪的注释。年。


改进了 psql 的 readline 功能以插入双连字符注释标记

目前还无法掌握改进的细节。
当您阅读发行说明时

调整 psql 的 readline meta-# 以插入双连字符注释标记 (Tom Lane)
以前插入了无用的磅标记。

但是,从发行说明的描述中并不清楚问题是在何种状态下得到解决的。ML 也赶不上。
我在 PostgreSQL 14.3 和 PostgreSQL 15 beta 1 中运行了一个带有双连字符和多行的查询,然后通过 readline 显示了命令历史记录,但我不明白其中的区别。


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 变量(也是从 PostgreSQL 15 引入的 psql 变量),此函数也可以SHOW_ALL_RESULTS在 PostgreSQL 14 中运行(仅显示最后一个查询)。


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

postgres=#

改进的选项卡完成

psql 易于使用的特性之一是丰富的 SQL 语法制表符补全和数据库对象制表符补全。它使用 readline 功能。
(相反,不支持 readline 的 psql,说实话,非常难用。它是 PostgreSQL for Windows 自带的 psql!)

发行说明只说“改进选项卡完成”,您无法阅读发行说明中的具体改进......
由于没有选择,我将确定与 Commitfest 提交的 psql 的 tab 完成相关的项目。

像这次这样的TAB补充改进的项目如下。

  • 创建申请
  • ALTER TABLE .. 验证约束
  • 输入大写字母(大写字符)时支持TAB补全

创建申请


我在这封电子邮件中尝试了几个案例,但 PostgreSQL 14.3 和 PostgreSQL 15 beta 1 之间的 TAB 完成行为没有区别。
PostgreSQL 14.3 已经回补了吗?

ALTER TABLE .. 验证约束


同样,PostgreSQL 14.3 和 PostgreSQL 15 beta 1 之间的 TAB 完成行为没有区别。
PostgreSQL 14.3 已经回补了吗?

输入大写字母(大写字符)时支持TAB补全


我一直无法跟上讨论电子邮件,但我想知道是否可以将SET// 3 命令的命令名称解释RESETSHOWTAB 完成,无论它是小写还是大写。

但是,PostgreSQL 14.3 和 PostgreSQL 15 beta 1 之间的 TAB 完成行为没有差异(尽管存在差异,因为扩展参数本身增加了 15)。
PostgreSQL 14.3 已经回补了吗?


对运行 PostgreSQL 9.2 或更高版本的服务器的 psql 支持有限

我在 Commitfest 列表中找不到此修复程序。
找ML,好像pgsql-commiters ML的这个内容是适用的。
pgsql:删除对 9.2 之前的服务器版本的 psql 支持。

由于 PostgreSQL 9.1 本身早就 EOL 了,我不认为这会是一个问题,但是当你尝试连接一个太旧的服务器时,PostgreSQL 15 会警告你。

当您实际设置 PostgreSQL 9.1.24 服务器并连接 PostgreSQL 15 beta1 时,Some psql features might not work.会显示诸如此类的警告。
仅显示警告,而不是连接本身被拒绝。


$ /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 命令


我不知道为什么,但它不包含在 PostgreSQL 15 beta 1 发行说明中。

如果这是我的理解(感觉就像我在手边尝试过),

  • 在 PostgreSQL 14 之前,您无法\password在尝试使用 更改密码时中断。CTRL+C
  • 在 PostgreSQL 15 中,\password尝试更改密码时CTRL+C可能会中断 at

我将其解释为,但我想知道是否是这种情况......(ML 讨论尚未被超越......)

改进了psql中计算emoji宽度的问题

我还没有确认改进......
发行说明中没有提到它,但它包含在 Commitfest 提交的项目中。

暂时,我用psql运行了一个包含表情符号的查询(使用Putty日文版+原始补丁版本?对于psqln执行环境),但我找不到PostgreSQL 14.3和PostgreSQL 15 beta 1之间的区别。(两者都稍微不对齐)

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 测试版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 中列出,有些项目已经被 PostgreSQL 14.3 支持?有一些项目,所以这次调查出乎意料地困难……

psql是我在使用 PostgreSQL 时始终关注的实用程序,但我认为每次升级时它仍在不断发展,这真是太神奇了。
这太方便了,以至于我不使用 pgAdmin4 之类的 GUI 客户端界面……


文章来源:https://qiita.com/nuko_yokohama/items/db02d5d5f1e0260b161a

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论