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

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

原创 小小亮 2023-01-03
325

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

以下是我想谈的补丁:

meson:来自源代码提交的新构建
提交: e6927270,4c72102e

现在可以使用新的构建系统 - 介子从源代码构建服务器。第一次提交发生在九月份。数十人紧随其后。在 12 月初,出现了一个提交,在文档中添加了一个部分来描述新的构建过程。wiki中还有一个页面,除其他内容外,还说明了这一决定背后的原因。而其中一个重要的原因是在 Windows 下构建服务器的简化以及将来拒绝支持位于 src/tools/msvc 目录中的本机工具。

除了 autoconf 和 make 之外,还出现了一个新的构建系统。我们不是在谈论废除经过验证的旧工具。

但就本文而言,最新的第 16 版服务器是由 meson 组装的。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.Transaction processing。一小章位于“内部设备”部分。它简要概述了虚拟和真实事务 ID、它们到 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 <unnamed>: 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_scan 和 last_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 进程,进程状态补充了数据库的名称。

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进程的状态中显示了数据库名称demo。

减少行冻结记录
提交的 WAL 大小: 9e540599

Peter Gagan正在研究主动行冻结。工作目的很明确——为了避免事务计数器循环出现问题,需要提前开始冻结行。然而,较早的冻结会生成更多的 WAL 并增加相关的开销(复制、WAL 归档)。

在这个补丁中,Peter 提出了一种更紧凑(~5x)的方法来构建与行冻结相关的 WAL 记录。

降低服务器空闲时的功耗

提交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,即 批处理模式被禁用,记录被一张一张地传输。

让我们将 bookings演示数据库表的内容上传到一个文件:

\COPY bookings TO 'bookings.txt'

现在我们将文件的内容加载到第三方表中,并启用时间测量:

\timing on
\COPY bookings_remote FROM 'bookings.txt'



COPY 2111110
Time: 57327,152 ms (00:57,327)

插入两百万行多一点花了将近一分钟的时间。将数据包大小设置为 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)

所以插入优化的可能性还没有用尽。此外,最好教 postgres_fdw 使用批处理模式来修改和删除行,而不仅仅是读取和插入。

现代化基础设施使用配置参数
提交: 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 $$;

在我的电脑上,在版本 15 中创建 10,000 个自定义参数需要大约 6 秒,应用补丁后,时间减少到大约 30 毫秒。

优化哈希索引
生成 提交: e09d7a12d09dbeb9

创建哈希索引时,值仅按篮子的数量排序。如果额外按值排序,那么后续值的插入速度会更快。

第一次提交是在 7 月,第二次是在 11 月。总的来说,哈希索引的创建速度提高了 5-15%。

MAINTAIN - 新的
提交表维护权限: 60684dd8

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

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

这个特权有什么好处?这些包括命令的执行:ANALYZE、VACUUM(包括 VACUUM FULL)、CLUSTER、REINDEX、REFRESH MATERIALIZED VIEW 和 LOCK 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 角色必须对某些模式(例如 public)具有 CREATE 特权。而且从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"

切换到角色的能力存储在 pg_auth_members 表的 set_option 列中,在 inherit_option 和 admin_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 现在支持 include、include_if_exists、include_dir 指令来包含其他文件。

pg_hba_file_rules 和 pg_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 文件中为用户名和数据库名称指定正则表达式。如果这些字段中的任何一个以正斜杠 (/) 开头,则该值被视为正则表达式。

原文标题:PostgreSQL 16: Часть 3 или Коммитфест 2022-11
原文作者:pluzanov
原文链接:https://postgrespro.com/blog/pgsql/5969929

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

评论