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

PostgreSQL 16:第1部分或CommitFest 2022-07

原创 eternity 2022-08-18
269

八月是PostgreSQL发布周期中的一个特殊月份。PostgreSQL 15甚至还没有正式发布,但第16版的首次提交测试已经举行。

让我们编译服务器,看看那些很酷的新东西!

\dconfig server_version
List of configuration parameters
   Parameter    |  Value
----------------+---------
 server_version | 16devel

显著特征

我想谈谈14个补丁:

  • psql: \pset xheader_width
  • vacuumdb --schema and --exclude-schema options
  • New createuser features added
  • Checkpoint and redo LSN added to LogCheckpointEnd log message
  • pg_prepared_statements.result_types
  • New parameter log_parameter_max_length for auto_explain
  • Subquery alias in FROM clause became optional
  • REINDEX: syntax improvements and more
  • CREATE STATISTICS: statistic name is now optional
  • CREATE TABLE: the STORAGE attribute
  • The user created during cluster initialization now can’t be stripped of superuser privileges
  • TRUNCATE triggers on foreign tables are now supported
  • New argument variation for pg_read_file/pg_read_binary_file
  • Extensible WAL resource managers

psql:\pset xheader_width

提交:a45388d6

当列数据不适合终端屏幕时,扩展输出模式(\x或\pset Expanded)是一个方便的选项。然而,对于某些内容,即使是扩展模式也可能不够。

让我们在72个字符宽的终端中运行一个查询:

\pset expanded on
\pset pager off

SELECT version(),
       length(version()) version_length;
-[ RECORD 1 ]--+--------------------------------------------------------
-------------------------------------------------
version        | PostgreSQL 16devel on x86_64-pc-linux-gnu, compiled by
gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0, 64-bit
version_length | 104

版本值不适合并被包装。那很好。但输出标题的大小与最宽列的大小相同,并被包装。列越宽,标题越长。当显示多个宽记录时,这尤其令人讨厌,因为每个标题在输出中占用多行。(尝试在扩展模式下从pg_proc;运行SELECT*。)

PostgreSQL 16引入了一个新的记录格式化选项来处理这些长头:

\pset xheader_width
Expanded header width is 'full'.

默认选项(完整)是过去版本中常见的行为。其他选择包括:

  • 列—–标题被修剪为第一个输出列的宽度。

  • 页面―–眉被修剪到终端窗口的宽度。

  • nnn–―标题被修剪为第nnn个字符。

\pset xheader_width column
Expanded header width is 'column'.
SELECT version(),
       length(version()) version_length;
-[ RECORD 1 ]--+
version        | PostgreSQL 16devel on x86_64-pc-linux-gnu, compiled by
gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0, 64-bit
version_length | 104

标头不再浪费宝贵的终端空间。

vacuumdb–schema和–exclude schema选项

提交:7781f4e3

vacuumdb获取用于清空指定模式(–schema)和指定模式之外的表(–exclude schema)的新参数。

添加了新的createuser功能

提交:08951a7c

createuser是CREATE ROLE命令的包装器,但功能有限。修补程序添加了新参数以利用以前不可用的功能,即:

  • —对于valid-until子句,有效期为

  • —bypassrls/–对于bypassrls/NOBYPASSRLS属性没有BypassRL

  • —m/–member向创建的角色授予成员资格

  • —a/–admin使用WITH admin OPTION子句向创建的角色授予成员资格

检查点和重做LSN添加到LogCheckpointEnd日志消息

提交:62c46eee

在建立检查点后,WAL将记录检查点的LSN和恢复点的LSM(重做LSN)。

最新检查点的两个LSN存储在控制文件中:

$ pg_controldata | egrep 'Latest.*location'
Latest checkpoint location:         1/1A3DEB20
Latest checkpoint's REDO location:  1/1A3DEAE8

在PostgreSQL 16中,这些记录现在在服务器日志中的检查点完成消息中提到:

2022-08-02 12:15:17.961 MSK[198868]日志:检查点完成:写入0个缓冲区(0.0%);添加0个WAL文件,删除0个,回收0个;写入=0.001秒,同步=0.001s,总计=0.072秒;同步文件=0,最长=0.000秒,平均=0.000s;距离=0 kB,估计=418462 kB;lsn=1/1A3DEB20,重做lsn=2/1A3DEAE8

请注意,在PostgreSQL 15及更高版本中,log_checkpoints参数默认为打开。

pg_prepared_statements.result_types

提交:84ad713c,6ffff0fd

prepared_ statements视图现在有一列result_types.

PREPARE get_booking (text) AS
SELECT * FROM bookings WHERE book_ref = $1;
SELECT * FROM pg_prepared_statements WHERE name = 'get_booking'\gx
-[ RECORD 1 ]---+-----------------------------------------------
name            | get_booking
statement       | PREPARE get_booking (text) AS                 +
                | SELECT * FROM bookings WHERE book_ref = $1;
prepare_time    | 2022-08-02 16:54:14.313221+03
parameter_types | {text}
result_types    | {character,"timestamp with time zone",numeric}
from_sql        | t
generic_plans   | 0
custom_plans    | 0

对于不返回任何内容的准备语句,该列将保持为空。

用于auto_ explain的新参数log_

提交:d4bfe412

新参数auto_ explain.max_ length用于记录查询参数,就像log_parameter_max_length.

LOAD 'auto_explain';
SHOW auto_explain.log_parameter_max_length;
auto_explain.log_parameter_max_length
---------------------------------------
- 1
(1 row)

默认值为-1。这意味着它将完整显示参数值。如果设置为0,则不会显示任何参数值。正值以字节为单位限制输出长度。

让我们在匿名PL/pgSQL块中设置日志并运行参数化查询EXECUTE。

SET auto_explain.log_min_duration = 0;
SET auto_explain.log_nested_statements = 'on';
SET auto_explain.log_level = 'NOTICE';
DO $$BEGIN EXECUTE 'SELECT $1' USING 42; END;$$;
NOTICE:  duration: 0.003 ms  plan:
Query Text: SELECT $1
Query Parameters: $1 = '42'
Result  (cost=0.00..0.01 rows=1 width=4)
DO

请注意,新添加的查询参数字符串列出了从查询文本运行查询时使用的参数。

FROM子句中的子查询别名变为可选

提交:bcedd8f5

SQL标准要求FROM子句中的任何子查询都具有别名:

15=# SELECT * FROM (SELECT 42 AS a);
ERROR:  subquery in FROM must have an alias
LINE 1: SELECT * FROM (SELECT 42 AS a);
^
HINT:  For example, FROM (SELECT ...) [AS] foo.
This complicates migration from other DBMS that don't strongly demand an alias here.

PostgreSQL 16 makes these aliases optional.

16=# SELECT * FROM (SELECT 42 AS a);
a
----
42
(1 row)

REINDEX:语法改进等

提交:2cbc3c17

REINDEX数据库和REINDEX系统变体要求指定数据库。但是,唯一有效的选项是当前数据库,这使得该选项是多余的。此修补程序使指定数据库成为可选。

此外,REINDEX DATABASE命令现在只重新索引用户生成的索引,并跳过系统目录表索引。您仍然可以通过运行REINDEX数据库和REINDEX系统来重建所有数据库索引。

此修补程序满足了在整个数据库中只重新索引用户生成的索引的需求。此外,在并发模式下重建系统索引是完全不可能的,并且在高负载环境中可能会导致死锁。

创建统计信息:统计信息名称现在是可选的

提交:624aa2a1

扩展统计数据是独立的数据库对象,因此需要名称。但是为什么不让PostgreSQL在没有用户参与的情况下处理命名呢?我们已经通过索引和完整性约束做到了这一点。

完成和完成:

CREATE STATISTICS ON departure_airport, arrival_airport FROM flights;
\d flights
...
Statistics objects:
"bookings.flights_departure_airport_arrival_airport_stat" ON departur

创建表:存储属性

提交:784cedda

假设我们想在数据库中存储图像。让我们创建一个表:

CREATE TABLE images (filename text, data bytea);
ALTER TABLE images ALTER COLUMN data SET STORAGE external;

在第二个命令中,我们将TOAST存储策略更改为external以禁止数据压缩。毕竟,图像文件已经被压缩了。

问题是,为什么这是一个单独的命令,而不是立即将所需的策略指定为createtable命令的一部分?答案很简单。在PostgreSQL 16之前,CREATE TABLE不允许为列指定存储属性。现在它做到了:

CREATE TABLE images (filename text, data bytea STORAGE external);

现在不能剥夺群集初始化期间创建的用户的超级用户权限

提交:e530be2c

在PostgreSQL 16之前,在集群初始化期间创建的超级用户(pg_authid.oid=10)可以从自己那里获取超级用户属性:

15=# ALTER ROLE postgres NOSUPERUSER;

(如果没有其他超级用户,则必须以单用户模式重新启动服务器以恢复该属性。)

PostgreSQL 16使超级用户不可能在发生意外时丢失属性:

16=# ALTER ROLE postgres NOSUPERUSER;
ERROR:  permission denied: bootstrap user must be superuser

顺便说一下,即使在以前的版本中,也不可能删除在集群初始化期间创建的超级用户:

CREATE ROLE root LOGIN SUPERUSER;
\c - root
DROP ROLE postgres;
ERROR:  cannot drop role postgres because it is required by the d

简而言之,您需要初始超级用户,服务器才能正常运行,您不应该删除它或剥夺其超级用户权限。为了获得额外的安全性,您可以考虑将其设置为组角色,并从中剥离登录属性。

现在支持外部表上的TRUNCATE触发器

提交:3b00a944

一些外部数据包装器支持TRUNCATE命令。此修补程序增加了为此类包装器的外部表创建TRUNCATE触发器的能力。

file/pg_read_binary_file的新变元

提交:2831293

read_ file和类似的pg_read_binary_file函数的规范如下:

pg_read_file ( filename text [, offset bigint, length bigint [, missing_ok boolean ]] ) → text

假设要读取整个文件,不需要指定偏移量和长度参数。但是,不能将missing_ok=true设置为忽略文件缺失。

PostgreSQL 16添加了一个重载函数变量,产生了一个新规范:

pg_read_file ( filename text [, offset bigint, length bigint ] [, missing_ok boolean ] ) → text

现在,您可以指定文件名并忽略文件缺失。

可扩展资源管理器

提交:5c279a6d

请欢迎我的同事Egor Rogov上台,他将解释此补丁的亮点。

表和索引访问方法的开发人员面临的问题之一是无法生成特定类型的日志记录。通用WAL记录有一种机制,它将新旧页面状态之间的“差异”记录到WAL中(例如,rum扩展使用了这种机制),但效率不高,不支持逻辑复制。

在PostgreSQL 16中,扩展将能够创建自己的资源管理器,从而以自己的格式创建日志条目。硬币的另一面是,故障后恢复实例依赖于第三方扩展。

从用户的角度来看,该补丁不会改变任何事情,但它是朝着新访问方法的出现迈出的另一重要步骤。

现在就这些。让我们期待9月份的CommitFest,当然还有PostgreSQL 15的正式发布。

原文标题:PostgreSQL 16:part 1 or CommitFest 2022-07
原文作者:Pavel Luzanov
原文链接:https://postgrespro.com/blog/pgsql/5969676

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

评论