Vakuum je jednou z nejdůležitějších funkcí pro obnovu odstraněných n-tic v tabulkách a indexech. Bez vakua by tabulky a indexy nadále rostly bez omezení. Tento blogový příspěvek popisuje možnost PARALLEL pro příkaz VACUUM, který je nově zaveden do PostgreSQL13.
Fáze zpracování ve vakuu
Než si novou možnost podrobně probereme, zopakujme si podrobnosti o tom, jak vakuum funguje.
Vakuum (bez možnosti FULL) se skládá z pěti fází. Například pro tabulku se dvěma indexy to funguje následovně:
- Fáze skenování haldy
- Naskenujte tabulku shora a sbírejte odpadkové n-tice do paměti.
- Indexová vakuová fáze
- Vysajte oba indexy jeden po druhém.
- Fáze vakua haldy
- Vysajte hromadu (stůl).
- Fáze čištění indexu
- Vyčistěte oba indexy jeden po druhém.
- Fáze zkrácení haldy
- Zkraťte prázdné stránky na konci tabulky.
Ve fázi skenování haldy může vakuum použít mapu viditelnosti k přeskočení zpracování stránek, o kterých je známo, že neobsahují žádný odpad, zatímco ve fázi vakuování indexu i fázi čištění indexu, v závislosti na metodách přístupu k indexu, probíhá skenování celého indexu. je vyžadováno.
Například indexy btree, nejoblíbenější typ indexu, vyžadují skenování celého indexu, aby se odstranily nesmyslné n-tice a provedlo se vyčištění indexu. Protože vakuum je vždy prováděno jediným procesem, indexy jsou zpracovávány jeden po druhém. Delší doba provádění vakua na zvláště velkém stole uživatele často obtěžuje.
PARALLELNÍ možnost
Abych tento problém vyřešil, navrhl jsem opravu pro paralelizaci vakua v roce 2016. Po dlouhém procesu revizí a mnoha reformách byla do PostgreSQL 13 zavedena možnost PARALLEL. S touto možností může vakuum provádět fázi vakuování indexu a fázi čištění indexu pomocí paralelní pracovníci. Paralelní vysavači se spustí před vstupem do fáze indexového vysávání nebo fáze čištění indexu a na konci fáze opustí. Jednotlivý pracovník je přiřazen k indexu. Paralelní vakuum je v autovakuu vždy zakázáno.
Volba PARALLEL bez argumentu celého čísla automaticky vypočítá paralelní stupeň na základě počtu indexů v tabulce.
VACUUM (PARALLEL) tbl;
Protože proces leader zpracovává vždy jeden index, bude maximální počet paralelních pracovníků (počet indexů v tabulce – 1), který je dále omezen na max_parallel_maintenance_workers. Cílový index musí být větší nebo roven min_parallel_index_scan_size.
Možnost PARALLEL nám umožňuje určit paralelní stupeň předáním nenulové celočíselné hodnoty. Následující příklad používá tři pracovníky pro celkem čtyři paralelní procesy.
VACUUM (PARALLEL 3) tbl;
Možnost PARALELNÍ je ve výchozím nastavení povolena; pro zakázání paralelního vakua nastavte max_parallel_maintenance_workers na 0 nebo zadejte PARALLEL 0
.
VACUUM (PARALLEL 0) tbl; -- disable parallel vacuum
Při pohledu na výstup VACUUM VERBOSE můžeme vidět, že pracovník zpracovává index.
Informace vytištěné jako „paralelním pracovníkem“ nahlásí pracovník.
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
Metody přístupu k indexu versus stupeň paralelismu
Vakuum nemusí vždy nutně provádět fázi indexového vakua a fázi čištění indexu paralelně. Pokud je velikost indexu malá nebo pokud je známo, že proces lze dokončit rychle, náklady na spuštění a správu paralelních pracovníků pro paralelizaci místo toho způsobí režii. V závislosti na metodách přístupu k indexu a jeho velikosti je lepší neprovádět tyto fáze pomocí paralelního vakuového pracovního procesu.
Například při vysávání dostatečně velkého indexu btree může fáze indexového vakua indexu provádět paralelní vakuový pracovník, protože vždy vyžaduje skenování celého indexu, zatímco fázi čištění indexu provádí paralelní vakuový pracovník, pokud index vakuum se neprovádí (např. na stole nejsou žádné odpadky). Důvodem je to, že indexy btree vyžadují ve fázi čištění indexu shromažďování statistik indexů, které se také shromažďují během fáze vakuového indexování. Na druhou stranu, hash indexy vždy nevyžadují skenování indexu ve fázi čištění indexu.
Pro podporu různých typů strategií indexového vakuování mohou vývojáři metod přístupu k indexu toto chování specifikovat nastavením příznaků na amparallelvacuumoptions
pole IndexAmRoutine
struktura. Dostupné příznaky jsou následující:
- VACUUM_OPTION_NO_PARALLEL (výchozí)
- paralelní vakuum je v obou fázích zakázáno.
- VACUUM_OPTION_PARALLEL_BULKDEL
- fázi indexového vakua lze provádět paralelně.
- VACUUM_OPTION_PARALLEL_COND_CLEANUP
- fázi čištění indexu lze provádět paralelně, pokud fáze vakuování indexu ještě neproběhla.
- VACUUM_OPTION_PARALLEL_CLEANUP
- fázi čištění indexu lze provádět paralelně, i když fáze vakuování indexu již index zpracovala.
Níže uvedená tabulka ukazuje, jak vestavěný PostgreSQL index AM podporuje paralelní vakuum.
nbtree | hash | gin | podstata | spgist | brin | kvetou | |
VACUUM_OPTION_PARALLEL_BULKDEL | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
VACUUM_OPTION_PARALLEL_COND_CLEANUP | ✓ | ✓ | ✓ | ||||
VACUUM_OPTION_CLEANUP | ✓ | ✓ | ✓ |
Další podrobnosti naleznete v části „src/include/command/vacuum.h“.
Ověření výkonu
Vyhodnotil jsem výkon paralelního vakua na svém notebooku (Core i7 2,6 GHz, 16 GB RAM, 512 GB SSD). Velikost tabulky je 6 GB a má osm 3GB indexů. Celkový poměr je 30 GB, což se nevejde do paměti RAM stroje. Při každém vyhodnocení jsem po vysávání zašpinil několik procent stolu rovnoměrně a následně provedl vysávání při změně paralelního stupně. Níže uvedený graf ukazuje dobu provádění vakua.
Ve všech hodnoceních doba provádění indexového vakua představovala více než 95 % celkové doby provádění. Proto paralelizace fáze indexového vakua pomohla výrazně zkrátit dobu provádění vakua.
Děkuji
Zvláštní poděkování patří Amitovi Kapilovi za oddané recenze, poskytování rad a nasazení této funkce pro PostgreSQL 13. Oceňuji všechny vývojáře, kteří se na této funkci podíleli, za kontrolu, testování a diskusi.