PostgreSQL 13:并行VACUUM

前几天,阿米特·卡皮拉(Amit Kapila)犯下了泽田雅彦(Mahahiko Sawada)补丁,该补丁可以并行清洁。该表本身仍由一个(引导)进程清除,但是要清理索引,它现在可以启动后台工作进程,每个索引一个。在手动模式下,这可以加快清理具有多个索引的大型表的速度;自动清洁尚未使用此功能。

相关链接:


如您所知,桌子清洁过程包括几个阶段。

首先,对表进行扫描,并在内存中收集到行的不必要(“死”)版本的链接。内存受maintenance_work_mem参数限制,因此所有链接可能一次无法容纳。

然后,对所有索引进行顺序排序(与以前一样),并从中清除指向已找到的无效版本字符串的指针。

然后,将再次扫描表中已查看的部分,并且已从中清除行的无效版本。

如果一次无法处理所有无效版本的字符串,那么将清除内存,并从上次停止的位置再次重复整个过程。

整个方案保持不变,但是现在可以并行清除索引。为此,牵头流程启动了几个工作流程,这些工作流程解析现有索引并进行处理。一个索引仅由一个进程处理。清除所有索引后,工作流程完成,协调员进入下一阶段。

例如,使用ticket_flights demobase flight table上面有一个索引,但是您可以创建更多索引。

demo=# CREATE index on ticket_flights (fare_conditions);
demo=# CREATE index on ticket_flights (amount);

并行处理中仅涉及大小超过min_parallel_index_scan_size参数值的索引我们的指标很适合:

demo=# SHOW min_parallel_index_scan_size;
 min_parallel_index_scan_size 
------------------------------
 512kB
(1 row)
demo=# SELECT pg_size_pretty(pg_relation_size(indexname::regclass))
FROM pg_indexes
WHERE tablename = 'ticket_flights';
 pg_size_pretty 
----------------
 325 MB
 187 MB
 180 MB
(3 rows)

更新一半的行以加载清理工作:

demo=# UPDATE ticket_flights SET amount = amount + 1 WHERE random() > 0.5;
UPDATE 4194262

走。

demo=# VACUUM VERBOSE ticket_flights;
INFO:  vacuuming "bookings.ticket_flights"
INFO:  launched 2 parallel vacuum workers for index vacuuming (planned: 2)
INFO:  scanned index "ticket_flights_fare_conditions_idx" to remove 4194262 row versions by parallel vacuum worker
DETAIL:  CPU: user: 1.84 s, system: 0.41 s, elapsed: 11.82 s
INFO:  scanned index "ticket_flights_amount_idx" to remove 4194262 row versions by parallel vacuum worker
DETAIL:  CPU: user: 2.31 s, system: 0.44 s, elapsed: 12.95 s
INFO:  scanned index "ticket_flights_pkey" to remove 4194262 row versions
...
INFO:  "ticket_flights": found 4194262 removable, 8391852 nonremovable row versions in 104885 out of 104885 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 630
There were 0 unused item identifiers.
Skipped 0 pages due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 9.91 s, system: 4.40 s, elapsed: 121.40 s.
VACUUM

可以看出,领导过程启动了两个工作人员,并采用了一个索引。

可以明确指定工作流程的数量(当然,在任何情况下都不会超过max_parallel_maintenance_workers,而不会超过max_worker_processes)。明确的指示尤其可以用于关闭并发:

demo=# VACUUM (PARALLEL 0, VERBOSE) ticket_flights;

我希望这个主题会得到进一步发展。可以通过多个过程并行扫描该表(这在原始的Savada补丁中,但未包含在最后一个补丁中),每个索引也可以并行清除。还必须教导自动清洁使用并行性。

P. S. , . . - , , .

Source: https://habr.com/ru/post/undefined/


All Articles