PG14新特性--恢复和VACUUM的加速

简介: PG14新特性--恢复和VACUUM的加速

PostgreSQL14加速恢复与VACUUM


我关注的PG14的性能项目其中一个是加速恢复与VACUUM。在微软的PG团队中,我和PG社区其他成员大部分时间一起致力于PG开源项目。在PG14中(2021Q3),我提交了一个patch优化compactify元组函数,减少恢复时CPU的使用。这项性能优化可以使PG14的恢复快2.4倍。

compactify_tuples函数在PG内部使用的地方:

1) 崩溃恢复时

2) 备机回放

3) VACUUM

因此,好消息是,改进compactify_tuples可以提高崩溃恢复性能;减少备机负载,使其更快回放来自主的日志;提高VACUUM性能。

本文中,我们将介绍compactify_tuples函数的改进,该函数过去如何工作,以及PG14改写后为什么更快。


剖析恢复进程突出一个性能问题


PGWAL日志包含指令及数据。描述了对基础数据进行修改。WAL确保数据持久化。当PG重启时,恢复进程将最近执行检查点位置之后的日志全部回放。顺序回放WAL日志,将数据库关闭时未刷写到磁盘的更改回放到数据页中。

在运行UPDATE密集型工作负载后,故意使数据库崩溃,我们对恢复过程进行了一些分析。CPU负载大部分来自“HEAP2 CLEANWAL记录的回放。HEAP2 CLEAN记录通过清除死记录占用空间来整理页内碎片。当页面变满,并需要更多空间时,就会产生HEAP2 CLEAN日志。

一个tuple是表中行的内部表示。一行可能有很多tuple,但任何一个时间点,仅一个tuple有效。老事务可能访问旧版本,以便访问事务开始时的行。UPDATE会产生新版本。创建每个行的多个版本被叫做多版本并发控制(MVCC)。


heap页中清理未使用的空间


为理解HEAP2 CLEANPG中如何工作,需要首先了解下heap页结构。我们看下带有元组碎片的heap页:

 1 由于删除了元组而出现碎片的heap页

我们可以看到,每个页头后面都有一个“items”数组。这些item指向每个元组。PG从页尾开始将元组写入页面,当items数组和元组空间重叠时,页面变满。需要注意,页尾处的元组和item指针的顺序并不是完全反向相反。元组2和3在这里出现了乱序。在页面更新了一些记录并旧的item指针被重用后,元组就会变得乱序。我们还可以看到,图1中的页面有很多未使用的空间。未使用的空间是由于VACUUM删除了元组。HEAP2 CLEAN操作将清除这些未使用的空间。

PG13及更早的版本中,HEAP2 CLEAN操作会将上述内容转换为:

2 PG14之前碎片整理的heap

我们可以看到空白区域小时了,元组紧凑移动到了页尾。注意,元组和原来保持相同顺序。元组23保持交叉顺序。


PG14之前heap页compacification怎么工作


comactify_tuples函数为我们处理页面compact工作。更改前,compactify_tuples函数会对item副本执行排序。这种排序允许元组移动到页尾。本案例中,先移动tuple1,然后tuple3,接着tuple2,最后tuple4。为决定哪个tuple先移动,compactify_tuples使用qsort函数用于比较并排序。以反向偏移顺序对item数组进行排序,允许从页面尾部的元组开始移动。

由于heap页面最多可以版本几百个元组,并且由于update负载中compact的频率导致qsort耗费大量CPU。当然,如果页面仅有几个元组,排序的代价就不高了。

那么是否需要排序?是,也不是。如果以item数组的顺序移动元组,不进行排序,我们可以在稍后的页面中覆盖元组。例如,图2中,如果在移动tuple3前移动tuple2,那么我们将覆盖tuple3

当像这样移动元组时,必须确保先将该位置的元组移动到页尾。因此对于这种本地移动必须进行排序。


怎样使HEAP2 CLEAN更快?


为了在执行HEAP2 CLEAN时,加快页面compact,我们需要写一个自定义qsort函数内联操作符函数。创建一个通用qsort函数会减少一些函数调用代价,但是不管怎么做qsort的复杂度都是O(n log n)。完全摆脱这种函数会更好。

使用qsort仅保证不会覆盖。因此可以将这些元组拷贝到一个临时缓冲区,这样移动元组的顺序就无关紧要了。

PG14compactify_tuples函数完全不需要使用qsort。不用排序,可以使我们以item数组的顺序移动tuple到页尾。临时内存避免了元组在移动前被覆盖的风险,也意味着元组以正确的顺序放回到页面尾处。PG14进行compact后新的heap页为:


3 PG14性能提升后新的compact heap

注意,元组23交换了位置,并且元组现在处于item反向顺序。

新的PG14代码通过预检查进一步优化,看元组是否已将在正确的反向item指针顺序中。如果元组顺序不正确,则不需要使用临时缓冲区。然后仅移动比第一个空白空间更早的元组。其他元组已经在正确位置。现在我们再次将元组以item指针反向顺序放回元组,我们更加频繁地遇到这种预先排序的情况。平均而言,我们金辉移动页面上一半元组。新元组产生新的item指针也会维护这样的顺序。

与元组在页面中的随机顺序相比,让元组以反向顺序还可以帮助某些CPU架构更有效地预取。


现在PG14有多快?


我们的测试用力使用了包含2INT列,填充因子为851000万行数据。考虑元组头,允许在每8KB页面存储最多226个元组。为了生成一些WAL来回放,使用Pgbench,随机执行1200万次更新。1000万行中每行平均有12次更新。然后非正常关闭,重启进行崩溃恢复。在性能提升前,崩溃恢复需要148秒才能重放2.2GBWAL

新版本的compactify_tuples代码进行同样的测试,耗时60.8秒。崩溃恢复的性能提升约2.4倍。

以前在compacity_tuples更改前,具有大量元组的页面进行compact很慢,因为qsort需要很长时间。更改后,不同数量的页面进行compact基本一致。即使每个页有很少元组,这种变化仍然会小幅提升性能。但是,当元组数量巨大时,更加有效。


PG14中的VACUUM性能也有所提升


VACUUM和(autovacuum)在heap页面中删除死元组也使用相同代码。因此加速compactify_tuples也意味着VACUUM性能有很好改进。我们尝试对之前更新的基准测试表执行VACUUM,发现PG14中运行速度比更改前快25%。以前需要4.1秒,现在仅2.9秒。

加速恢复过程还意味着备机更有可能跟上主,并在产生日志后很快回放掉。这意味着可以帮助备不落后主。


因此恢复进程和VACUUM在PG14中更快--而且还有很多工作正在进行中


compacity_tuples在很多情况下确实有助于提高恢复性能。但是恢复过程在IO上遇到瓶颈而不是CPU也很场景。当恢复的数据库大于可用内存时,必须等待从磁盘中读取页然后进行回放。幸运的是,我们还在研究一种方法,让恢复进程将页面预取到内核的页面缓冲中,这样物理IO就可以在后台并发进行,而不是让恢复进程等待。

更多信息可以查看邮件列表的讨论:


https://www.postgresql.org/message-id/CA+hUKGKMQFVpjr106gRhwk6R-nXv0qOcTreZuQzxgpHESAL6dw@mail.gmail.com


原文


https://techcommunity.microsoft.com/t5/azure-database-for-postgresql/speeding-up-recovery-and-vacuum-in-postgres-14/ba-p/2234071

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
关系型数据库 数据库 PostgreSQL
PostgreSQL 11 新特性解读 : Initdb/Pg_resetwal支持修改WAL文件大小
PostgreSQL 11 版本的一个重要调整是支持 initdb 和 pg_resetwal 修改 WAL 文件大小,而 11 版本之前只能在编译安装 PostgreSQL 时设置 WAL 文件大小。
8715 0
|
9月前
|
关系型数据库 数据库
加速PG中vacuum
加速PG中vacuum
82 1
|
9月前
|
监控 关系型数据库 Shell
[翻译]PG15新特性-加速WAL日志归档
[翻译]PG15新特性-加速WAL日志归档
101 0
|
9月前
|
SQL 存储 关系型数据库
[译]Postgres15-新特性-利用pg_walinspect对WAL事件进行debug
[译]Postgres15-新特性-利用pg_walinspect对WAL事件进行debug
98 0
|
关系型数据库 分布式数据库 数据库
【DB吐槽大会】第44期 - PG 同步复制不支持自动升降级
大家好,这里是DB吐槽大会,第44期 - PG 同步复制不支持自动升降级
|
SQL Oracle 关系型数据库
【DB吐槽大会】第39期 - PG 物化视图不支持基于log的增量刷新
大家好,这里是DB吐槽大会,第39期 - PG 物化视图不支持基于log的增量刷新
|
SQL 关系型数据库 数据库
【DB吐槽大会】第20期 - PG pg_upgrade大版本升级不支持增量
大家好,这里是DB吐槽大会,第20期 - PG pg_upgrade大版本升级不支持增量
|
SQL Oracle 关系型数据库
PostgreSQL 物化视图(Oracle同步到PG,PG同步到PG) - by pgsnapshot (plperlu trigger) (支持类似Oracle的mvlog fast complete force刷新)
标签 PostgreSQL , 物化视图 , 增量刷新 , mvlog , Oracle 同步到 PG , PG 同步到 PG 背景 PostgreSQL自身的物化视图没有MVLOG,也就是说,刷新的时候是VIEW定义产生的记录与MV已刷新的记录进行比对,进行增量更新的过程。
3091 0