PG13并行vacuum

PG13并行vacuum

Vacuum是PG的一个重要功能用于回收表和索引中的死记录。如果没有这个功能,PG就会持续膨胀。本文介绍VACUUM命令中的PARALLEL选项,该选项于PG13引入。

VACUUM处理阶段

首先介绍下vacuum如何工作。无FULL选项的vacuum有5个阶段。例如,一个表有2个索引,工作阶段如下:

1)heap扫描阶段

扫描表,搜集需要回收的记录

2)索引vacuum阶段

一个一个的vacuum索引

3)heap vacuum阶段

Vacuum heap

4)索引清理阶段

一个一个地清理索引

5)heap truncate阶段

    Truncate表的end的空页。

Heap scan阶段、index vacuum阶段和index清理阶段,vacuum使用visibility map跳过处理没有任何delete记录的页。例如btree索引,需要全索引扫描来清理死记录。Vacuum总是单进程一个一个处理索引。Vacuum一个大表需要花费很长时间,对用户来说非常恶心。

PARALLEL选项

为处理单进程vacuum问题,2016年我提出了一个并行vacuum的补丁。经历长时间审阅和修改后,PG13引入PARALLEL选项。通过这个选项,可以并行执行索引vacuum阶段和索引清理阶段。每个索引一个进程,但是自动vacuum中禁止并行vacuum。

不带任何整型参会的PARALLEL选项,根据表的索引个数自动计算并行度:

VACUUM(PARALLEL) tb1;

Leader进程总是处理一个索引,并行worker的最大个数为表索引个数-1,受限于max_parallel_maintenance_workers。目标索引必须大于等于min_parallel_index_scan_size。PARALLEL选项可以通过传入一个非0值指定并行度,有3个worker进程,共有4个并行进程:

VACUUM (PARALLEL 3) tb1;

默认情况开启PARALLEL选项。设置max_parallel_maintenance_workers为0禁止并行vacuum,或者指定PARALLEL 0:

VACUUM (PARALLEL 0) tbl; -- disable parallel vacuum

看下VACUUM VERBOSE输出,可以看到处理索引的进程:

VACUUM (PARALLEL, VERBOSE) tbl;

INFO: vacuuming "public.tbl"

INFO: launched 2 parallel vacuum workers for index vacuuming (planned: 2)

INFO: scanned index "i1" to remove 112834 row versions

DETAIL: CPU: user: 9.80 s, system: 3.76 s, elapsed: 23.20 s

INFO: scanned index "i2" to remove 112834 row versions by parallel vacuum worker

DETAIL: CPU: user: 10.64 s, system: 8.98 s, elapsed: 42.84 s

INFO: scanned index "i3" to remove 112834 row versions by parallel vacuum worker

DETAIL: CPU: user: 10.65 s, system: 8.98 s, elapsed: 43.96 s

INFO: "tbl": removed 112834 row versions in 112834 pages

DETAIL: CPU: user: 1.12 s, system: 2.31 s, elapsed: 22.01 s

INFO: index "i1" now contains 150000000 row versions in 411289 pages

DETAIL: 112834 index row versions were removed.

0 index pages have been deleted, 0 are currently reusable.

CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.

INFO: index "i2" now contains 150000000 row versions in 411289 pages

DETAIL: 112834 index row versions were removed.

0 index pages have been deleted, 0 are currently reusable.

CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.

INFO: index "i3" now contains 150000000 row versions in 411289 pages

DETAIL: 112834 index row versions were removed.

0 index pages have been deleted, 0 are currently reusable.

CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.

INFO: "tbl": found 112834 removable, 112833240 nonremovable row versions in 553105 out of 735295 pages

DETAIL: 0 dead row versions cannot be removed yet, oldest xmin: 430046

There were 444 unused item identifiers.

Skipped 0 pages due to buffer pins, 0 frozen pages.

0 pages are entirely empty.

CPU: user: 18.00 s, system: 8.99 s, elapsed: 91.73 s.

VACUUM

索引访问方法 vs 并行度

Vacuum并不是在所有情况下必行执行索引vacuum阶段和所以清理阶段。如果索引非常小,或者进程能够很快做完vacuum,发起并管理并行进程的消耗会造成开销。依赖于索引访问方法和索引大小,最好不要执行并行。

例如,vacuum一个很大的btree索引,可用并行执行索引vacuum阶段,因为需要执行全索引扫描,然而,如果索引vacuum由于没有死记录等原因没有执行vacuum时,则由一个并行vacuum worker执行索引清理阶段。Btree索引需要采集索引统计信息,这是在索引vacuum阶段执行的。Hash索引不需要在索引清理阶段扫描索引。

开发者为了支持不同类型的vacuum策略,通过设置IndexAmRoutine 的amparallelvacuumoptions域来完成。标签如下:

VACUUM_OPTION_NO_PARALLEL (默认):在上述两个阶段中禁止并行vacuum。

VACUUM_OPTION_PARALLEL_BULKDEL:索引vacuum阶段可以并行

VACUUM_OPTION_PARALLEL_COND_CLEANUP:如果索引vacuum阶段没有执行,索引清理节点可以并行

VACUUM_OPTION_PARALLEL_CLEANUP:及时索引vacuum阶段已经处理了该索引,索引清理阶段也可以并行:


nbtree

Hash

Gin

gist

spgist

brin

bloom

VACUUM_OPTION_PARALLEL_BULKDEL

Y

Y

Y

Y

Y


Y

VACUUM_OPTION_PARALLEL_COND_CLEANUP

Y



Y

Y



VACUUM_OPTION_CLEANUP



Y



Y

Y

性能评估

环境:Core i7 2.6GHz, 16GB RAM, 512GB SSD

表大小6GB,8个3GB的索引,总大小30G,RAM不能放下所有数据。

索引vacuum的时间占总时间的95%。因此并行vacuum阶段可以显著减小执行时间。

原文

https://www.2ndquadrant.com/en/blog/parallelism-comes-to-vacuum/

Masahiko Sawada

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值