News zu Post­greS­QL Datenbank

DBA-Pra­xis­­test: Par­al­le­li­sie­rung von Au­to­va­cu­um in Post­greS­QL 19

Bereinigt Au­to­va­cu­um große Tabellen schneller, wenn zu­sätz­li­che Worker die In­dex­ar­beit über­neh­men? Wir haben die Par­al­le­li­sie­rung in Post­greS­QL 19 un­ter­sucht. Das Ergebnis: Die par­al­le­len Worker wurden zu­ver­läs­sig gestartet – ein re­pro­du­zier­ba­rer Ge­schwin­dig­keits­vor­teil blieb unter den gewählten La­bor­be­din­gun­gen jedoch aus.

Au­to­va­cu­um gehört zur laufenden Wartung einer Post­greS­QL-Datenbank. Es sorgt unter anderem dafür, dass Spei­cher­platz nicht mehr be­nö­tig­ter Zei­len­ver­sio­nen wie­der­ver­wen­det werden kann. Solche so­ge­nann­ten Dead Tuples entstehen bei­spiels­wei­se durch Updates und Löschungen.

PostgreSQL

In Post­greS­QL 19 ist es mit Au­to­va­cu­um möglich, bestimmte Arbeiten an Indizes parallel aus­zu­füh­ren. Ob zu­sätz­li­che Worker auch die gesamte Be­rei­ni­gung be­schleu­ni­gen, hängt jedoch von der Tabelle, ihren Indizes und den ver­füg­ba­ren Sys­tem­res­sour­cen ab.

Was wird bei Au­to­va­cu­um parallelisiert?

Die Par­al­le­li­sie­rung betrifft die Index-Vacuum- und Index-Cleanup-Phasen. Sie verteilt nicht sämtliche Arbeiten eines Au­to­va­cu­um-Durch­laufs auf mehrere Prozesse.

Dabei sind zwei Ein­stel­lun­gen zu unterscheiden:

  • autovacuum_max_workers begrenzt die gleich­zei­tig laufenden regulären Au­to­va­cu­um-Worker, die un­ter­schied­li­che Tabellen be­ar­bei­ten können.
  • autovacuum_max_parallel_workers begrenzt die zu­sätz­li­chen par­al­le­len Worker, die ein einzelner Au­to­va­cu­um-Worker für die In­dex­be­ar­bei­tung einsetzen kann. Der do­ku­men­tier­te Stan­dard­wert ist 0; damit ist diese Par­al­le­li­sie­rung deaktiviert.


Über den Ta­bel­len­pa­ra­me­ter autovacuum_parallel_workers lässt sich die Par­al­le­li­tät zu­sätz­lich pro Tabelle begrenzen. Wie viele Worker tat­säch­lich zum Einsatz kommen, hängt unter anderem von ge­eig­ne­ten Indizes und ver­füg­ba­ren Worker-Ka­pa­zi­tä­ten ab. Eine kon­fi­gu­rier­te Ober­gren­ze ga­ran­tiert daher keine ent­spre­chen­de Anzahl ge­star­te­ter Prozesse.

Unser Test­auf­bau: drei Ta­bel­len­klas­sen und drei Parallelitätsstufen

Die Versuche liefen auf einer einzelnen Post­greS­QL-19beta3-Instanz in einer vir­tu­el­len Maschine mit 16 vCPUs und 64 GB RAM. Un­ter­sucht wurden drei Tabellenklassen:

Ta­bel­len­klas­se
Zeilen vor dem Löschen
In­dex­struk­tur
Gelöschte Zeilen (Dead Tuples)
Kleine Tabellen 
10.000 je Tabelle 
Vier Indizes mit jeweils ca. 600 kB 
Ca. 1.428 je Tabelle 
Große Tabelle mit großen Indizes 
10 Millionen 
Vier voll­stän­di­ge Indizes mit jeweils ca. 563 MB 
1.428.571
Große Tabelle mit kleinen Indizes 
10 Millionen 
Vier partielle Indizes mit jeweils ca. 5,7 MB 
1.428.571

Die par­ti­el­len Indizes erfassten nur jede hun­derts­te Zeile. Die Lösch­men­ge wurde jeweils über das Muster id % 7 = 0 erzeugt.

Getestet wurden drei Einstellungen:

  • P0: keine par­al­le­len Worker
  • P2: maximal zwei parallele Worker
  • P4: maximal vier parallele Worker


Bei den großen Tabellen wurde nach einem vor­be­rei­ten­den `VACUUM (FREEZE, ANALYZE)` die de­fi­nier­te Lösch­men­ge erzeugt. An­schlie­ßend be­rei­nig­te Au­to­va­cu­um die ent­stan­de­nen Dead Tuples. Die Lauf­zei­ten stammen aus den Post­greS­QL-Ab­schluss­logs. Ergänzend wurden CPU- und I/O‑Daten mit `vmstat` und `iostat` erfasst.

Die Er­geb­nis­se: Keine Variante war durch­ge­hend schneller

Test­sze­na­rio
P0
P2
P4
Kleine Tabellen 
Median 0,11 s 
Median 0,06 s 
Ca. 0,07 s je Tabelle 
Große Tabelle mit großen Indizes 
Median 974,30 s 
Median 1.140,31 s 
Median 1.027,73 s 
Große Tabelle mit kleinen, par­ti­el­len Indizes 
Median 979,28 s 
Median 1.005,33 s 
Median 1.033,17 s 

Bei den kleinen Tabellen waren die Vacuum-Lauf­zei­ten sehr kurz. Dadurch hatten WAL-Aufkommen, Check­points, Cache-Zustand und die Mess­auf­lö­sung einen relativ großen Einfluss. Die P4-Reihe wurde mit vier kleinen Tabellen durch­ge­führt und ist deshalb nur ein­ge­schränkt mit den Ein­zel­ta­bel­len­läu­fen vergleichbar.

Bei den großen Tabellen zeigten die `vmstat`- und `iostat`-Daten deutliche Schwan­kun­gen bei I/O‑Wartezeit, Schreib­la­tenz und Ge­rä­te­aus­las­tung. Diese Un­ter­schie­de traten auch innerhalb derselben Kon­fi­gu­ra­ti­on auf und waren teilweise größer als der erwartete Effekt der Par­al­le­li­sie­rung. Bei der großen Tabelle mit par­ti­el­len Indizes lagen bei­spiels­wei­se bereits die P0-Lauf­zei­ten zwischen 816,40 und 1.477,53 Sekunden.

Wurden die par­al­le­len Worker tat­säch­lich eingesetzt?

Die Post­greS­QL-Ab­schluss­logs be­stä­ti­gen, dass die par­al­le­len Worker tat­säch­lich ein­ge­setzt wurden. Bei P2 wurden jeweils zwei Worker gestartet. Bei P4 wurden trotz der Ein­stel­lung von maximal vier Worker jeweils nur drei geplant und gestartet (bedingt durch die Kon­fi­gu­ra­ti­on oder Anzahl der ver­füg­ba­ren Indizes).

Nächster Schritt: Test unter Anwendungslast

In einer zweiten Testphase – welche wir zu gegebener Zeit ebenfalls hier ver­öf­fent­li­chen werden – wollen wir die Par­al­le­li­sie­rung unter rea­lis­ti­sche­ren Be­triebs­be­din­gun­gen un­ter­su­chen. Geplant sind de­di­zier­te oder stark isolierte Systeme und ein par­al­le­ler OLTP-Workload mit INSERT-, UPDATE-, DELETE- und SELECT-Operationen. Dabei sollen mehrere Tabellen mit un­ter­schied­li­chen Än­de­rungs­ra­ten und In­dex­struk­tu­ren gleich­zei­tig be­trach­tet werden.

Die Varianten P0, P2 und P4 sollen au­to­ma­ti­siert, in wech­seln­der Rei­hen­fol­ge und mit mehreren Wie­der­ho­lun­gen getestet werden. Neben der Dauer des Au­to­va­cu­um-Laufs wollen wir auch den Einfluss auf die Anwendung messen: etwa Trans­ak­ti­ons­durch­satz, Ant­wort­zei­ten sowie p95- und p99-Latenzen. Ergänzend erfassen wir Post­greS­QL-interne Werte, WAL-Aufkommen, Check­points und Sys­tem­me­tri­ken wie CPU-Aus­las­tung, I/O‑Wartezeiten und Storage-Latenzen.

So soll eine be­last­ba­re Ent­schei­dungs­hil­fe entstehen: Unter welchen Res­sour­cen- und Last­be­din­gun­gen lohnt sich die Par­al­le­li­sie­rung – und wann kon­kur­rie­ren die zu­sätz­li­chen Worker vor allem um dieselben Ressourcen?

Unsere Ein­ord­nung und Fazit des Tests

Der Test bestätigt, dass Post­greS­QL 19 parallele Worker für die Index-Vacuum-Arbeiten einsetzt. Einen re­pro­du­zier­ba­ren Zeit­ge­winn konnten wir in diesem La­bor­auf­bau jedoch nicht messen. Bei den sehr kurzen Läufen mit kleinen Tabellen war der Effekt kaum iso­lier­bar. Bei den großen Tabellen lagen die Mediane nahe bei­ein­an­der. Stel­len­wei­se führten parallele Worker aufgrund von I/O‑Konkurrenz (*Resource Con­ten­ti­on*) sogar zu leichten Laufzeitverlängerungen.

Das ist kein Beleg dafür, dass par­al­le­les Au­to­va­cu­um grund­sätz­lich keinen Vorteil bringt. Die Er­geb­nis­se gelten für eine einzelne virtuelle Maschine, einen iso­lier­ten Test ohne An­wen­dungs­last und die hier ver­wen­de­ten Tabellen und Indizes. Sie lassen sich daher nicht ohne Weiteres auf pro­duk­ti­ve Post­greS­QL-Systeme über­tra­gen. Auch Parameter wie maintenance_work_mem und der ver­füg­ba­re Spei­cher­durch­satz können be­ein­flus­sen, ob zu­sätz­li­che Worker ihre Arbeit tat­säch­lich schneller erledigen.

Nachtrag: Post­greS­QL 19 RC1 – Bugfixes für par­al­le­les Autovacuum

Nach unserem Re­dak­ti­ons­schluss wurde Post­greS­QL 19 RC1 ver­öf­fent­licht. Der Release Candidate enthält mehrere Feh­ler­kor­rek­tu­ren für das neue Feature Parallel Au­to­va­cu­um (autovacuum_max_parallel_workers).

Die wich­tigs­ten Ver­bes­se­run­gen im Überblick:

  • Sta­bi­li­tät:
    Behebung eines möglichen Absturzes, wenn für parallele Worker kein Dynamic Shared Memory be­reit­ge­stellt werden konnte.
  • Res­sour­cen­steue­rung:
    Än­de­run­gen an den VACUUM-Cost-Pa­ra­me­tern werden nun auch während laufender par­al­le­ler Ver­ar­bei­tung zu­ver­läs­sig an die Worker weitergegeben.
  • Mo­ni­to­ring:
    Korrektur der War­te­zei­ten­er­fas­sung (pg_stat_progress_vacuum.delay_time) sowie der I/O‑Zeitmessung in den Autovacuum-Logs.
  • GIN-Indizes:
    Korrektur der Be­rei­ni­gung der GIN Pending List, um unnötig lange Ver­ar­bei­tung bei gleich­zei­tig laufenden Inserts zu vermeiden.


Fazit:

Die Kor­rek­tu­ren ver­bes­sern ins­be­son­de­re die Sta­bi­li­tät, Res­sour­cen­steue­rung und Be­ob­acht­bar­keit des par­al­le­len Autovacuums.

Hinweis:
Eine Änderung von autovacuum_max_parallel_workers be­ein­flusst weiterhin nur neu ge­star­te­te VACUUM-Vorgänge, nicht bereits laufende Worker.

Hier findest du weitere Infos aus der Welt von Post­greS­QL aus unserem News & Insights Bereich.

icon-arrow_right_medium-violet-blue.svg

Share this article

Facebook 
Twitter 
LinkedIn 
XING 
WhatsApp 
Email