Vakuum er en af de vigtigste funktioner til at genvinde slettede tupler i tabeller og indekser. Uden vakuum ville tabeller og indekser fortsætte med at vokse i størrelse uden grænser. Dette blogindlæg beskriver PARALLEL-indstillingen for VACUUM-kommandoen, som for nylig er introduceret til PostgreSQL13.
Vakuumbehandlingsfaser
Før vi diskuterer den nye mulighed i dybden, lad os gennemgå detaljerne om, hvordan vakuum virker.
Vakuum (uden FULD mulighed) består af fem faser. For en tabel med to indekser fungerer det f.eks. som følger:
- Heap-scanningsfase
- Scan bordet fra toppen og saml affaldstupler i hukommelsen.
- Indeksvakuumfase
- Støvsug begge indekser én efter én.
- Habevakuumfase
- Støvsug dyngen (bordet).
- Indeksoprydningsfase
- Ryd op i begge indekser ét efter ét.
- Heap trunkeringsfase
- Trunker tomme sider i slutningen af tabellen.
I heap-scanningsfasen kan vakuum bruge synlighedskortet til at springe behandlingen over af sider, der er kendt for ikke at have noget skrald, mens der i både indeksvakuumfasen og indeksoprydningsfasen, afhængigt af indeksadgangsmetoder, en hel indeksscanning er påkrævet.
For eksempel kræver btree-indekser, den mest populære indekstype, en hel indeksscanning for at fjerne affaldstupler og foretage indeksoprydning. Da vakuum altid udføres af en enkelt proces, behandles indekserne én efter én. Den længere udførelsestid af vakuum på især et stort bord irriterer ofte brugerne.
PARALLEL Option
For at løse dette problem foreslog jeg en patch til at parallelisere vakuum i 2016. Efter en lang gennemgangsproces og mange reformer er PARALLEL-muligheden blevet introduceret til PostgreSQL 13. Med denne mulighed kan vakuum udføre indeksvakuumfasen og indeksoprydningsfasen med parallelarbejdere. Parallelle vakuumarbejdere starter, før de går ind i enten indeksvakuumfase eller indeksoprydningsfase og afslutter ved slutningen af fasen. En individuel arbejder tildeles et indeks. Parallel vakuum er altid deaktiveret i autovakuum.
Indstillingen PARALLEL uden et heltalsargument vil automatisk beregne parallelgraden baseret på antallet af indekser på tabellen.
VACUUM (PARALLEL) tbl;
Da lederprocessen altid behandler ét indeks, vil det maksimale antal parallelle arbejdere være (antallet af indekser i tabel – 1), hvilket yderligere er begrænset til max_parallel_maintenance_workers. Målindekset skal være større end eller lig med min_parallel_index_scan_size.
Indstillingen PARALLEL giver os mulighed for at angive parallelgraden ved at sende en heltalværdi, der ikke er nul. Følgende eksempel bruger tre arbejdere, for i alt fire processer parallelt.
VACUUM (PARALLEL 3) tbl;
Indstillingen PARALLEL er aktiveret som standard; for at deaktivere parallelt vakuum, sæt max_parallel_maintenance_workers til 0 eller specificer PARALLEL 0
.
VACUUM (PARALLEL 0) tbl; -- disable parallel vacuum
Når vi ser på VACUUM VERBOSE-outputtet, kan vi se, at en arbejder behandler indekset.
Oplysningerne udskrevet som "af parallelarbejder" rapporteres af arbejderen.
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
Indeksadgangsmetoder kontra graden af parallelitet
Vakuum udfører ikke altid nødvendigvis indeksvakuumfasen og indeksoprydningsfasen parallelt. Hvis indeksstørrelsen er lille, eller hvis det er kendt, at processen kan afsluttes hurtigt, forårsager omkostningerne ved at lancere og administrere parallelarbejdere til parallelisering i stedet overhead. Afhængigt af indeksadgangsmetoderne og dets størrelse er det bedre ikke at udføre disse faser ved en parallel vakuumbearbejdningsproces.
For eksempel, ved støvsugning af et tilstrækkeligt stort btree-indeks, kan indeksvakuumfasen af indekset udføres af en parallel vakuumarbejder, fordi det altid kræver en hel indeksscanning, mens indeksoprydningsfasen udføres af en parallelstøvsuger, hvis indekset vakuum udføres ikke (f.eks. er der ikke noget affald på bordet). Dette skyldes, at det, btree-indekser kræver i indeksoprydningsfasen, er at indsamle indeksstatistikken, som også indsamles i indeksvakuumfasen. På den anden side kræver hash-indekser altid ikke en scanning af indekset i indeksoprydningsfasen.
For at understøtte forskellige typer indeksvakuumstrategier kan udviklere af indeksadgangsmetoder specificere denne adfærd ved at sætte flag til amparallelvacuumoptions
feltet i IndexAmRoutine
struktur. De tilgængelige flag er som følger:
- VACUUM_OPTION_NO_PARALLEL (standard)
- parallel vakuum er deaktiveret i begge faser.
- VACUUM_OPTION_PARALLEL_BULKDEL
- indeksvakuumfasen kan udføres parallelt.
- VACUUM_OPTION_PARALLEL_COND_CLEANUP
- indeksoprydningsfasen kan udføres parallelt, hvis indeksvakuumfasen ikke udføres endnu.
- VACUUM_OPTION_PARALLEL_CLEANUP
- indeksoprydningsfasen kan udføres parallelt, selvom indeksvakuumfasen allerede har behandlet indekset.
Tabellen nedenfor viser, hvordan indeks AMs indbyggede PostgreSQL understøtter parallelt vakuum.
nbtree | hash | gin | resumé | spgist | brin | blomstrer | |
VACUUM_OPTION_PARALLEL_BULKDEL | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |
VACUUM_OPTION_PARALLEL_COND_CLEANUP | ✓ | ✓ | ✓ | ||||
VACUUM_OPTION_CLEANUP | ✓ | ✓ | ✓ |
Se 'src/include/command/vacuum.h' for flere detaljer.
Ydeevnebekræftelse
Jeg har evalueret ydeevnen af parallelt vakuum på min bærbare computer (Core i7 2.6GHz, 16GB RAM, 512GB SSD). Bordstørrelsen er 6GB og har otte 3GB indekser. Det samlede forhold er 30 GB, hvilket ikke passer til maskinens RAM. For hver evaluering gjorde jeg adskillige procent af bordet snavset jævnt efter støvsugning, og udførte derefter vakuum, mens jeg ændrede parallelgraden. Grafen nedenfor viser vakuumudførelsestiden.
I alle evalueringer udgjorde eksekveringstiden for indeksvakuumet mere end 95 % af den samlede eksekveringstid. Derfor hjalp parallelisering af indeksvakuumfasen til at reducere vakuumudførelsestiden meget.
Tak
Særlig tak til Amit Kapila for hengiven gennemgang, rådgivning og forpligtelse af denne funktion til PostgreSQL 13. Jeg sætter pris på alle udviklere, der var involveret i denne funktion for gennemgang, test og diskussion.