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

掌握PostgreSQL新特性学习笔记一:PostgreSQL 9.6

原创 多米爸比 2021-10-06
1075

国庆前夕PG14新版本发布了,当前主要还再使用PG12,趁着假期温习了一遍9.6到13的新特性,追一下新版本的差距。

PostgreSQL 9.6

数据库管理功能

数据库管理功能中最重要的特性应该是idle_in_transaction_session_timeout

杀掉空闲会话

在PostgreSQL中,会话或事务基本上可以永远存在。在某些情况下这一直是个问题:因为事务一直保持打开状态太长了。根因在于:长事务可能导致清理问题,并引起表膨胀。不受控制的表膨胀自然会导致性能下降和糟糕的用户体验。

从PostgreSQL 9.6开始,可以限制数据库连接在事务内部使用而不执行实际操作的持续时间,下面演示如何使用这一特性:

test=# SET idle_in_transaction_session_timeout TO 2500;
SET
test=# BEGIN;
BEGIN
test=# SELECT 1;
?column?
----------
1
(1 row)
test=# SELECT 1;
FATAL: terminating connection due to idle-in-transaction timeout

上面设置超时时间为2.5秒,一旦事务空闲时间过长,连接就会被服务器自动中断,通过调整此参数可以轻松防止长空闲事务的恶劣影响。

活动连接增加等待事件

pg_stat_activity系统视图显示一个活动连接列表。在之前版本的PostgreSQL中,管理员可以看到一个查询正在等待(waiting字段),然而不能进一步找到等待原因。在9.6版本中发生了变化,增加了两列:

test=# \d pg_stat_activity
View "pg_catalog.pg_stat_activity"
Column | Type | Modifiers
------------------+--------------------------+-----------
...
wait_event_type | text |
wait_event | text |
...

同时也添加了一个新的函数用来查找受阻(blocking)SQL:

test=# SELECT * FROM pg_blocking_pids(4711);
pg_blocking_pids
------------------
{3435}
(1 row)

函数调用后会显示阻塞pid列表。

备注:会话A堵住会话B,我们称会话B为blocked会话,会话A为blocking会话,上面pid为4711的会话为blocked会话。

vacuum进度跟踪

PostgreSQL 9.6版本引入一个新的系统视图来跟踪vacuum进度,下面演示如何使用这一特性:

postgres=# SELECT * FROM pg_stat_progress_vacuum ;
[ RECORD 1 ]+
pid | 29546
datid | 67535
datname | test
relid | 16402
phase | scanning heap
heap_blks_total | 6827
heap_blks_scanned | 77
heap_blks_vacuumed | 0
index_vacuum_count | 0
max_dead_tuples | 154

PostgreSQL提供有关正在进行vacuum处理的详细信息,让我们能够跟踪这一重要操作的进展。

SQL及开发相关

在PostgreSQL 9.5之前,只能搜索单词,文本(phrase)搜索非常困难。PostgreSQL 9.6很好地消除了这一限制,详细使用请参考:https://www.postgresql.org/docs/9.6/textsearch-intro.html

备份恢复及流复制

wal_level与监控

在PostgreSQL中,很多人对wal_level的设置一直很难理解。尤其很难理解archive与hot_standby设置的区别。为了消除这一困惑,便于理解,这两个选项统一成replica。
此外,PostgreSQL 9.6之前只能通过pg_stat_replication视图在主库查询主从状态,现在可以在从库通过pg_stat_wal_receiver视图查询流复制状态。

支持多个同步节点

在PostgreSQL 9.6之前,只能允许有一个同步节点。现在可以使用多个节点,使用一组服务器来确认事务提交,可通过多节点容错来提高系统可靠性。使用这一特性的语法如下:

synchronous_standby_names = '3 (server1, server2, server3, server4)'

另外之前的版本synchronous_commit默认为on,确保事务同步提交到从库。然而该选项并不确保数据立即对用户可见。通过设置synchronous_commit为remote_apply,可以确保在主库数据提交后直接在从库查询数据而不用担心数据不可见。

性能相关的大特性

每个发布的PostgreSQL版本都有大量的性能提升。这里聚焦五个重大的提升,除此以外还有很多小特性。

Relation扩块提升

多年来PostgreSQL扩展表(或者索引)是按单个数据块,逐个扩展。这在单进程写场景是非常合适的。然而在高并发写场景,这是造成竞争和性能不佳的源头。从PostgreSQL 9.6开始,PostgreSQL对表进行扩展时一次性扩展多个数据块。

排序检查点及内核交互

在检查点期间,PostgreSQL将更改写入磁盘时,现在会确保写入比以前更有序。这是通过在发送数据块之前对它们进行排序来完成的。随机写入将显著降低,通过这种方式可以提高大多数环境的吞吐量。

PostgreSQL 9.6还引入了新的内核回写配置选项:当操作系统的缓存较大时,写出缓存可能需要花费很长时间。这在具有数百G内存的系统里情况会特别糟糕,因为可能会发生I/O风暴。当然,在Linux操作系统级别可以使用
/proc/sys/vm/dirty_background_ratio进行修改。然而,只有少量的技术顾问和系统管理员知道如何处理及修改的原因。现在可以通过checkpoint_flush_after,bgwriter_flush_after,backend_flush_after参数来控制刷缓存行为。

FDW改进

Foreign data wrappers(FDW)已经存在多年了。从PostgreSQL 9.6开始,优化器可以更有效地使用外部表。这包括join下推(可以远程执行join)和order下推(可以远程进行排序)。

引入并行查询

PostgreSQL 9.6版本之前查询必须在运行单个CPU上。在OLTP领域,它开始成为分析型应用程序的一个问题,受限于单核CPU的速度。PostgreSQL 9.6引入了并行查询。当然,实现并行查询是一项艰巨的任务,现在可以使用并行顺序扫描特性了,同时也允许使用并行aggregates和并行join。当然还有很多并行特性等待完成,但我们已经看到了一个重大的飞跃。

使用并行特性,有如下两个基本设置参数:

test=# SHOW max_worker_processes;
max_worker_processes
----------------------
8
(1 row)

test=# SHOW max_parallel_workers_per_gather ;
max_parallel_workers_per_gather
---------------------------------
2
(1 row)

第一个参数限制所有可用的worker进程数,第二个参数控制每个gather节点的worker数。

gather节点是9.6新引入的,我们可以在执行计划中看到。它负责统一处理并行子进程的结果集。

增加快照太旧的错误信息

使用Oracle的用户会理解如下错误消息:快照太旧。在Oracle中,此消息表示事务存在过久必须被中止。在PostgreSQL中,事务几乎可以永久运行。长事务仍然可能是一个问题,因此快照太旧错误消息作为一个特性添加到9.6中,允许事务运行一定时间后被强行中止。

这个特性是为了预防表膨胀,同时让用户意识到他们的某些行为对表膨胀的影响。

保持联系

从2019年12月开始写第一篇文章,分享的初心一直在坚持,本人现在组建了一个PG乐知乐享交流群,欢迎关注我文章的小伙伴进群吹牛唠嗑,交流技术,互赞文章。

123.png

如果群二维码失效可以加我微信。

456.png

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

文章被以下合辑收录

评论