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

PostgreSQL 16 新动态:第 3 部分或 CommitFest 2022-11

原创 小小亮 2023-02-03
774

我们继续关注即将发布的 PostgreSQL 16 的消息。第三届 CommitFest 于 12 月初结束。让我们看看结果。

如果您错过了之前的 CommitFest,请查看我们的评论2022-07、2022-09

以下是我想谈的补丁:

  • meson:一个新的源代码构建系统
  • 文档:事务处理的新篇章
  • psql: \d+ 表示分区表中的外部分区
  • psql:扩展查询协议支持
  • 物化视图上的谓词锁
  • 跟踪索引和表的上次扫描时间
  • pg_buffercache:一个新函数 pg_buffercache_summary
  • walsender 在进程状态中显示数据库名称
  • 减少冻结元组的 WAL 开销
  • 空闲时功耗降低
  • postgres_fdw:COPY 的批处理模式
  • 使 GUC 基础设施现代化
  • 哈希索引构建优化
  • MAINTAIN ― 表维护的新权限
  • SET ROLE:更好的角色变更管理
  • 支持 pg_hba.conf 和 pg_ident.conf 中的文件包含指令
  • pg_hba.conf 中的正则表达式支持

meson:一个新的源代码构建系统

提交e6927270,4c72102e _

早在 9 月份,Meson 支持就以提交的方式首次引入。随后又进行了数十次提交。又有几十人紧随其后。12 月初,提交了描述新构建过程的文档部分。还有一个wiki 页面,其中解释了引入新构建工具的决定背后的原因。原因之一是为了简化为 Windows 系统构建服务器,并最终能够完全停止支持来自 /src/tools/msvc 的 PostgreSQL 自己的构建工具。

新的构建系统将与 autoconf 和 make 一起提供,没有计划取代旧的工具。

但是,我专门使用 Meson 为本文构建了全新的 PostgreSQL 16 测试环境。在 Ubuntu 上,构建过程如下:

$ git clone git://git.postgresql.org/git/postgresql.git
$ cd postgresql
$ meson setup build --prefix=/home/pal/pg16 -Dpgport=5416
$ cd build
$ ninja
$ ninja install
复制

除了安装位置和服务器端口外,我将所有内容都保留为默认值。

剩下的就是初始化集群并启动服务器,无论使用何种构建工具,您都可以按照相同的方式进行操作。

文档:事务处理的新篇章

提交:66bc9d2d

文档中增加了一个新章节:74.事务处理它位于 Internals 部分,简要概述了什么是虚拟和真实交易标识符,它们在 中的显示方式pg_locks,以及子交易和两阶段交易的工作方式。

psql: \d+ 表示分区表中的外部分区

提交:bd95816f

对于分区表,\d+ 命令将用单词标记外部表的部分FOREIGN

\d+ data
复制
                                    Partitioned table "public.data"
  Column   | Type | Collation | Nullable | Default | Storage  | Compression | Stats target | Description
-----------+------+-----------+----------+---------+----------+-------------+--------------+-------------
 data_year | text |           |          |         | extended |             |              |
Partition key: LIST (data_year)
Partitions: data_2020 FOR VALUES IN ('2020'), FOREIGN,
        	data_2021 FOR VALUES IN ('2021'), FOREIGN,
        	data_2022 FOR VALUES IN ('2022')
复制

psql:扩展查询协议支持

提交:5b66de34

直到现在,psql 还没有直接支持扩展查询协议因此,参数化查询只能间接执行,例如使用PREPARE语句。

现在该\bind命令已添加到 psql 以将值绑定到下一个查询的参数。它是这样工作的:

SET log_statement='all';

\bind 42 'Answer: '

SELECT $2||$1;
复制
  ?column?  
------------
Answer: 42
(1 row)
复制
\! tail -2 logfile
复制
2022-12-05 12:58:05.924 MSK [16566] LOG:  execute : SELECT $2||$1;
2022-12-05 12:58:05.924 MSK [16566] DETAIL:  parameters: $1 = '42', $2 = 'Answer: '
复制

仅实现了扩展查询协议的一小部分功能,但该倡议非常受欢迎。

物化视图上的谓词锁

提交:43351557

谓词锁用于确保具有SERIALIZABLE隔离级别的事务的一致性。它们从未被设计为使用REFRESH MATERIALIZED VIEW命令更新物化视图,因为它专门锁定视图以防止任何并发访问异常。

但是,当使用CONCURRENTLY参数更新且没有谓词锁时,具有隔离级别的事务SERIALIZABLE可能会出现写偏斜。现在问题解决了。

跟踪索引和表的上次扫描时间

提交:c0374718

除了计算表和索引扫描之外,累积统计系统现在还记录最后一次记录扫描的时间和日期。此数据存储在中的last_seq_scanlast_idx_scan列中pg_stat_all_tables以及中的last_idx_scan列中pg_stat_all_indexes

SELECT seq_scan, last_seq_scan, idx_scan, last_idx_scan
FROM   pg_stat_all_tables
WHERE  relid = 'tickets'::regclass;
复制
 seq_scan |         last_seq_scan         | idx_scan |         last_idx_scan    	 
----------+-------------------------------+----------+-------------------------------
       23 | 2022-12-07 15:17:57.261575+03 |        2 | 2022-12-05 14:59:53.564968+03
(1 row)
复制
SELECT indexrelname, idx_scan, last_idx_scan
FROM pg_stat_all_indexes
WHERE relid = 'tickets'::regclass;
复制
     indexrelname     | idx_scan |         last_idx_scan    	 
----------------------+----------+-------------------------------
 tickets_pkey         |        2 | 2022-12-05 14:59:53.564968+03
 tickets_book_ref_idx |        0 |
(2 rows)
复制

如果没有实施专门的监控系统,它可能有助于分析索引和表的使用情况。

pg_buffercache:一个新函数 pg_buffercache_summary

提交:2589434a

pg_buffercache 扩展现在可以显示聚合的缓冲区缓存数据:

CREATE EXTENSION pg_buffercache;

SELECT * FROM pg_buffercache_summary()\gx
复制
-[ RECORD 1 ]--+------------------
buffers_used   | 2544
buffers_unused | 13840
buffers_dirty  | 38
buffers_pinned | 0
usagecount_avg | 2.183176100628931
复制

我们以前通过聚合视图来获取这些数据pg_buffercache,但新功能不会锁定缓冲区,因此它更便宜并且可以轻松集成到监控系统中。

walsender 在进程状态中显示数据库名称

提交:af205152

walsender是处理复制协议连接的进程。对于物理复制或备份,walsender连接到一个实例,但不连接到特定的数据库。但是,当您创建逻辑复制订阅时,发布者会创建一个逻辑复制槽,并walsender连接到创建发布的数据库。

该补丁在逻辑复制的情况下将数据库的名称添加到walsender进程描述中,这使得监控这些进程更加方便。

16(sub)=# CREATE SUBSCRIPTION sub CONNECTION 'port=5416 user=postgres dbname=demo' PUBLICATION pub;
复制
NOTICE:  created replication slot "sub" on publisher
CREATE SUBSCRIPTION
复制
16(pub)=# \! ps -o pid,command --ppid `head -n 1 /home/pal/pg16/data/postmaster.pid`
复制
	PID COMMAND
  38514 postgres: checkpointer
  38515 postgres: background writer
  38517 postgres: walwriter
  38518 postgres: autovacuum launcher
  38519 postgres: logical replication launcher
  38522 postgres: postgres demo [local] idle
  38662 postgres: walsender postgres demo [local] START_REPLICATION
复制

此处,walsender 进程状态显示演示数据库名称。

减少冻结元组的 WAL 开销

提交:9e540599

Peter Geoghegan正在研究主动元组冻结。目的很明确:为了避免交易柜台回绕,需要提前开始冻结。然而,较早的冻结会导致更大的 WAL 卷并增加相关的开销(WAL 复制和归档)。

在这个补丁中,Peter 提议更紧凑地形成 WAL 冻结记录(大约 5 倍)。

空闲时功耗降低

提交cd4329d9,05a7be93 _

当主服务器空闲时,物理副本上的启动进程仍然每5秒唤醒一次,检查promote_trigger_file中指定的文件是否出现。但是还有其他机制可以提升副本:pg_ctl promote以及pg_promote功能。为了减少此类唤醒的资源消耗,删除了promote_trigger_file参数。

对进程进行了类似的工作walreceiver,每秒唤醒 10 次,检查它是否需要做某事。现在,进程会提前计算下一次启动的时间。

postgres_fdw:COPY 的批处理模式

提交:97da4824

在第 14 版中,批量插入记录首次成为可能。批量大小由外部服务器或表级别的 batch_size 参数设置。但是,它仅针对INSERT命令实施。此补丁为该COPY FROM命令添加了对批量粘贴模式的支持。

让我们比较一下不同命令的插入速度。为此,我首先在 postgres 数据库中创建一个空的预订表,我们将向其中插入数据。

postgres=# CREATE TABLE public.bookings (
	book_ref char(6),
	book_date timestamptz,
	total_amount numeric(10,2)
);
复制

在同一集群的演示数据库中,让我们为预订表创建一个外部表。

CREATE EXTENSION postgres_fdw;

CREATE SERVER srv
	FOREIGN DATA WRAPPER postgres_fdw
	OPTIONS (dbname 'postgres', batch_size '1');

CREATE USER MAPPING FOR postgres
	SERVER srv
	OPTIONS (user 'postgres');

CREATE FOREIGN TABLE bookings_remote (
    book_ref char(6),
    book_date timestamptz,
    total_amount numeric(10,2)
) SERVER srv 
    OPTIONS (schema_name 'public', table_name 'bookings');
复制

批量大小在服务器级别设置为 1,这意味着禁用批量模式并且一次发送一条记录。

让我们将演示数据库中的预订表内容转储到一个文件中:

\COPY bookings TO 'bookings.txt'
复制

现在,将文件内容上传到外表并测量时间:

\timing on
\COPY bookings_remote FROM 'bookings.txt'
复制
COPY 2111110
Time: 57327,152 ms (00:57,327)
复制

插入略多于 200 万行的数据花了将近一分钟的时间。将批量大小设置为 100 并重复测试:

TRUNCATE bookings_remote;
ALTER SERVER srv OPTIONS (SET batch_size '100');

\COPY bookings_remote FROM 'bookings.txt'
复制
COPY 2111110
Time: 8780,000 ms (00:08,780)
复制

插入速度提升6倍以上!

奇怪的是,该INSERT命令在批处理模式下运行得更快:

TRUNCATE bookings_remote;
INSERT INTO bookings_remote SELECT * FROM bookings;
复制
INSERT 0 2111110
Time: 6669,504 ms (00:06,670)
复制

所以在COPY命令插入的时候,还有优化的空间!此外,如果能教postgres_fdw你使用批处理模式来修改和删除行,而不仅仅是读取和插入,那就太好了。

使 GUC 基础设施现代化

提交f13b2088、3057465a407b50f2、9c911ec0 _ _ _

这一系列提交优化了存储并加快了对配置参数(包括用户生成的参数)的访问。

优化在 Tom Lane 在开始讨论的信中给出的示例中最为明显:

do $$
    begin
        for i in 1..10000 loop
        perform set_config('foo.bar' || i::text, i::text, false);
    end loop;
end $$;
复制

在我的电脑上,在 PostgreSQL 15 中创建一万个用户参数大约需要 6 秒,应用补丁后,时间缩短到 30 毫秒左右。

哈希索引构建优化

提交:e09d7a12d09dbeb9

在构建哈希索引时,值仅按桶号排序。如果您另外按值排序,则插入后续值会更快。

第一次提交是在 7 月,第二次是在 11 月。到目前为止,哈希索引构建速度提高了 5-15%。

MAINTAIN ― 表维护的新权限

提交:60684dd8

表和物化视图的许多维护操作不受权限限制,通常只对对象所有者和超级用户可用。

PostgreSQL 16 引入了MAINTAIN权限,可以在物化视图和表上授予权限,包括系统视图和表:

GRANT MAINTAIN ON pg_class, pg_attribute, pg_type TO alice;
复制

\dp输出为此权限使用 m 字符

\dp pg_catalog.pg_class
                                     Access privileges
   Schema   |   Name   | Type  |     Access privileges      | Column privileges | Policies
------------+----------+-------+----------------------------+-------------------+----------
 pg_catalog | pg_class | table | postgres=arwdDxtm/postgres+|                   |
            |          |       | =r/postgres               +|                   |
            |          |       | alice=m/postgres           |                   |
复制

此特权授予哪些操作?这些包括执行命令ANALYZEVACUUM(包括VACUUM FULLCLUSTERREINDEXREFRESH MATERIALIZED VIEWLOCK TABLE

此外,还添加了一个预定义的 pg_maintain 角色。此角色的成员资格授予MAINTAIN对数据库中所有关系的特权。这允许您将维护特权授予无权在数据库中执行 DDL 和 DML 操作的常规角色。

最初的补丁建议为VACUUM和增加两个权限ANALYZE,但最终社区决定使用MAINTAIN具有更广泛维护能力的权限。

SET ROLE:更好的角色变更管理

提交:3d14e171

此补丁继续努力构建更强大的角色和权限管理系统。上一篇文章谈到了授予角色成员资格继承特权

新补丁引入了使用SET ROLE命令切换到另一个角色。假设我们决定将alice角色包含在pg_read_all_data启用特权继承的情况下:

postgres=# GRANT pg_read_all_data TO alice WITH INHERIT TRUE;
复制

alice角色现在可以使用pg_read_all_data特权。但是没有什么可以停止alice切换角色pg_read_all_data并开始代表它创建对象:

postgres=# \c - alice
复制
You are now connected to database "postgres" as user "alice".
复制
alice=> CREATE TABLE t (id int);
复制
CREATE TABLE
复制
alice=> \dt t
复制
            List of relations
 Schema | Name | Type  |      Owner       
--------+------+-------+------------------
 public | t    | table | pg_read_all_data
复制

其实是有的。要创建对象,pg_read_all_data角色必须CREATE在某些模式中具有特权,例如在public并且从 PostgreSQL 15 开始,伪角色public不再有这个权限。至于上面的例子,我必须提前运行以下命令:

postgres=# GRANT CREATE ON SCHEMA public TO public;
复制

然而,在某些情况下可能不希望切换到另一个角色。如果我们提供角色的成员资格INHERIT TRUE,那么为什么要切换呢?在新版本中,这可以通过相同的GRANT命令来禁止:

postgres=# GRANT pg_read_all_data TO alice WITH INHERIT TRUE, SET FALSE;
复制

Alice 现在可以使用pg_read_all_data权限,但无法切换到它。

alice=> SET ROLE pg_read_all_data;
复制
ERROR:  permission denied to set role "pg_read_all_data"
复制

切换到角色的能力存储在表格的set_option列中,在pg_auth_members旁边inherit_optionadmin_option

SELECT roleid::regrole, member::regrole, grantor::regrole,
       admin_option, inherit_option, set_option
FROM pg_auth_members
WHERE member = 'alice'::regrole\gx
复制
-[ RECORD 1 ]--+-----------------
roleid         | pg_read_all_data
member         | alice
grantor        | postgres
admin_option   | f
inherit_option | t
set_option     | f
复制

支持 pg_hba.conf 和 pg_ident.conf 中的文件包含指令

提交:a54b658c

配置文件 pg_hba.conf 和 pg_ident.conf 以及 postgresql.conf 现在支持包含其他文件的指令:includeinclude_if_existsinclude_dir.

包含文件名和规则/地图编号的列已添加到pg_hba_file_rulespg_ident_file_mappings

SELECT * FROM pg_hba_file_rules
WHERE file_name LIKE '%hba_ident_test.conf' \gx
复制
-[ RECORD 1 ]---------------------------------
rule_number | 1
file_name   | /home/pal/pg/hba_ident_test.conf
line_number | 1
type        | local
database.   | {all}
user_name   | {alice}
address     |
netmask     |
auth_method | peer
options     | {map=m1}
error       |
复制
SELECT * FROM pg_ident_file_mappings
WHERE file_name LIKE '%ident_test.conf' \gx
复制
-[ RECORD 1 ]-----------------------------
map_number  | 1
file_name   | /home/pal/pg/ident_test.conf
line_number | 1
map_name.   | m1
sys_name.   | student
pg_username | alice
error       |
复制

pg_hba.conf 中的正则表达式支持

提交:8fea8683a9039713fc579e11

pg_hba.conf 支持用户名和数据库名的正则表达式。如果这些字段中的任何一个以斜杠 (/) 开头,则该值被视为正则表达式。

 

这就是现在的全部。期待一月 CommitFest的结果!


原文标题:PostgreSQL 16: part 3 or CommitFest 2022-11

原文作者:Pavel Luzanov

原文链接:https://postgrespro.com/blog/pgsql/5969929

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

评论