PostgreSQL 13中改进的(自动)真空

2020-05-12 13:35:11

Vacuum是PostgreSQL中的一个子系统,每个版本都会得到改进。“我检查了过去的五个版本,每个版本都有相当多的Vacuum改进。”顺应潮流,在即将发布的PostgreSQL版本(V13)中,Vacuum有很多改进,本文将对此进行报道。

Vacuum将被允许并行处理索引。这意味着它可以利用多个CPU来执行索引清理。这在内部使用PostgreSQL的后台工作进程基础设施来完成工作。*有一个新的选项PARALLEL来控制VACUUM使用的并行度。用户可以使用这个新选项来指定可用于执行VACUUAL命令的工作进程数,该数目受到(A)表上的索引数和(B)max_PARALLEL_Maintenance_WORKS的最小限制。*VACUUAL命令的并行度在默认情况下是启用的,这意味着即使用户没有使用';不指定PARALLEARY选项,它使用的工作进程数等于正在清空的表上的索引数。我们可以通过使用PARALLEL选项将工作进程数指定为零来禁用真空的并行性。*索引可以并行参与。

并行选项不能与VACUUM命令中的FULL选项一起使用。如果此功能不能通过自动真空使用,用户需要使用VAUAUM命令才能获得此功能提供的好处。

还有许多其他博客[1][2]显示了此功能的好处。“EnterpriseDB最近发布的一篇博客显示,使用7个工作者可以将吸尘器的速度提高约4倍,特别是当关系非常需要吸尘器时,请阅读该博客以获取有关测试的更多信息。

在上面的测试中,即使我们指定了4,也使用了2个并行工作进程,原因是索引的数量是3,并且工作进程的数量不能超过索引,这进一步受到max_parallel_maintenance_worker的限制,正如您可以通过下面的命令看到的那样。

我们在此功能中确保的另一个最重要的事情是,与非并行真空相比,并行不会使用更多的内存或I/O带宽。

允许插入以触发自动真空活动。*此功能对仅插入表非常有用,在这些表中,反环绕真空可能是表收到的第一个真空,这样的运行将需要很长时间。*此功能允许将堆页设置为全可见,从而允许仅索引扫描跳过堆提取,并在需要冻结表时减少必要的工作。*这由两个新的GUC和relc选项控制:autoVacuum_Vacuum_Insert_Threshold和AutoVacuum_。

让我用一个例子的帮助来演示这个功能的好处。用autoVacuum_Vacuum_INSERT_THRESHOLD=-1启动服务器(一个人可以编辑postgresql.conf文件来更改这个参数的值,或者可以使用ALTER SYSTEM命令)。*通过连接psql,我们可以执行下面的命令来查看行为。

几秒钟后,您可以在服务器日志中注意到下面的消息,该消息显示AutoVacuum已经对该表执行了分析。

日志:自动分析表";postgres.public.vac_ins";系统使用情况:CPU:用户:0.03s,系统:0.11s,已用时间:0.15s。

这里,";Heap Fetches:99";显示了上面的查询需要访问heap来获取所需的信息,即使它存在于索引中,并且使用的扫描类型是仅索引扫描。

现在,使用默认值autoVacuum_Vacuum_INSERT_THRESHOLD重新启动服务器,并从psql执行以下命令,查看新功能有何帮助:

几秒钟后,您可以在服务器日志中注意到下面的消息,它指示AutoVacuum已经在表上执行了VACUUM和ANALYSITY。

日志:自动分析表";postgres.public.vac_ins";系统使用情况:CPU:用户:0.01s,系统:0.15s,已用时间:0.21s。

这里,";Heap Fetches:0";显示了上面的查询不需要访问堆来获取所需的信息。我们可以看到,在这种情况下,完成执行的时间大大减少了。

允许(自动)真空在出错的情况下显示有关堆或索引的附加信息。*此功能可以在数据库有一些损坏的情况下帮助用户。例如,如果关系上的一个索引有一些损坏的数据(由于坏的硬件或某些错误),它将让用户知道索引信息,用户可以采取适当的操作,如重新编制索引,或者可能删除并重新创建该特定索引来克服该问题。例如,在堆的情况下,它会让用户知道索引信息,并且用户可以采取适当的操作,如重新编制索引或可能删除并重新创建该特定的索引来克服该问题。在堆的情况下,它显示发生错误的块号,这使得用户和开发人员更容易检测到问题。o在最坏的情况下,如果表中的任何特定块损坏,用户可以删除该特定块的所有行,然后可以使用该表。

接下来,我使用";select*from heap_page_item(GET_RAW_PAGE(';PVAC';,2469));";查找页面中所有行指针的信息,然后将它们从以下查询中删除。

现在,您可以看到块号从2469更改为2468,这意味着真空可以继续。因为在这种情况下,我通过更改代码手动诱导了错误,所以每个块都会发生错误,但实际上是针对某些特定的块,一旦用户可以清除这些块,表就可以重复使用。我不想说这是理想的情况,但至少它允许用户继续操作,并且它可以帮助开发人员缩小错误的范围(如果其中有错误的话)。我不想说这是理想的情况,但至少它会允许用户继续操作,并且它可以帮助开发人员缩小错误的范围(如果其中有错误的话)。我不想说这是理想的情况,但至少它会允许用户继续操作,并且它可以帮助开发人员缩小错误的范围(如果其中有错误的话。

自动真空现在将记录WAL使用率统计信息和其他信息。*WAL使用率包含有关记录总数、整页图像数和总字节数的信息。*缓冲区使用率和WAL使用率统计信息结合在一起,可为我们提供特定自动真空运行时I/O的大致使用率。我举了一个运行信息的例子,它将在下面显示,人们可以参考WAL使用情况来检查关于新添加的统计数据的信息。

元组:已删除100000个,剩余100000个,0个已死但尚未删除,最早的xmin:529xmin。

将真空缓冲区计数器设置为64位宽,以避免缓冲区使用统计信息溢出。*如果没有此功能,在极端情况下,如果存在足以容纳40亿次缓冲区访问的表,则显示的统计信息将毫无意义。请参阅下面的pgsql-hacker提供的缓冲区使用统计信息示例(';Buffer Usage';stats of';Buffer Usage';stats from pgsql-hacker):

添加等待事件以报告基于成本的真空延迟。这将帮助我们监控[自动]真空节流。这是一个很小的功能,但非常重要,因为目前我们无法监控[自动]真空节流,这种情况在用户环境中并不少见。