VACUUM och ANALYSE är de två viktigaste PostgreSQL-databasunderhållsoperationerna.
Ett vakuum används för att återvinna utrymme som upptas av "döda tuplar" i en tabell. En död tuppel skapas när en post antingen raderas eller uppdateras (en radering följt av en infogning). PostgreSQL tar inte fysiskt bort den gamla raden från tabellen utan sätter en "markör" på den så att frågor inte returnerar den raden. När en vakuumprocess körs markeras utrymmet som upptas av dessa döda tuplar som kan återanvändas av andra tuplar.
En "analys"-operation gör vad dess namn säger - den analyserar innehållet i en databas tabeller och samlar in statistik om fördelningen av värden i varje kolumn i varje tabell. PostgreSQL frågemotor använder denna statistik för att hitta den bästa frågeplanen. När rader infogas, raderas och uppdateras i en databas ändras också kolumnstatistiken. ANALYSE – antingen körs manuellt av DBA eller automatiskt av PostgreSQL efter ett autovakuum – säkerställer att statistiken är uppdaterad.
Även om de låter relativt enkla, är bakom kulisserna, dammsugning och analys två komplexa processer. Lyckligtvis behöver DBA:er inte oroa sig mycket för sina interna funktioner. Men de är ofta förvirrade när det gäller att köra dessa processer manuellt eller ställa in de optimala värdena för konfigurationsparametrarna.
I den här artikeln kommer vi att dela med oss av några bästa metoder för VAKUUM och ANALYSER.
Tips 1:Kör inte manuell VAKUUM eller ANALYSE utan anledning
PostgreSQL-dammsugning (autovakuum eller manuell vakuum) minimerar bordsuppblåsningar och förhindrar transaktions-ID-omslutning. Autovacuum återställer inte det diskutrymme som tagits upp av döda tuplar. Kör dock en VACUUM FULL kommando kommer att göra det. VACUUM FULL har dock sin prestandaimplikation. Målbordet är uteslutande låst under operationen, vilket förhindrar jämna avläsningar på bordet. Processen gör också en fullständig kopia av tabellen, vilket kräver extra diskutrymme när den körs. Vi rekommenderar att du inte kör VACUUM FULL såvida det inte finns en mycket hög andel uppblåsthet och frågorna lider hårt. Vi rekommenderar också att du använder perioder med lägst databasaktivitet för det.
Det är också en bästa praxis att inte köra manuella dammsugare för ofta på hela databasen; måldatabasen skulle redan kunna dammsugas optimalt av autovakuumprocessen. Som ett resultat kan en manuell dammsugare inte ta bort några döda tuplar utan orsaka onödiga I/O-belastningar eller CPU-spikar. Vid behov bör manuella dammsugare endast köras tabell för tabell när det finns ett behov av det, som låga förhållanden mellan levande rader och döda rader, eller stora luckor mellan autodammsugare. Dessutom bör manuella dammsugare köras när användaraktiviteten är minimal.
Autovacuum håller också en tabells datadistributionsstatistik uppdaterad (det bygger inte om dem). När den körs manuellt visas ANALYS kommandot bygger faktiskt om denna statistik istället för att uppdatera den. Återigen, att återuppbygga statistik när den redan är optimalt uppdaterad av ett vanligt autovakuum kan orsaka onödigt tryck på systemresurserna.
Tiden när du måste köra ANALYSE manuellt är omedelbart efter bulkladdning av data till måltabellen. Ett stort antal (även några hundra) nya rader i en befintlig tabell kommer att avsevärt skeva dess kolumndatadistribution. De nya raderna gör att all befintlig kolumnstatistik blir inaktuell. När frågeoptimeraren använder sådan statistik kan frågeprestanda vara riktigt långsam. I dessa fall är det ett bättre alternativ att köra kommandot ANALYSE omedelbart efter en dataladdning för att helt återskapa statistiken än att vänta på att autovakuumet sätter igång.
Tips 2:Finjustera Autovacuum Threshold
Det är viktigt att kontrollera eller ställa in autovakuumet och analysera konfigurationsparametrar i postgresql.conf fil eller i individuella tabellegenskaper för att hitta en balans mellan autovakuum och prestandaförstärkning.
PostgreSQL använder två konfigurationsparametrar för att bestämma när ett autovakuum ska startas:
- autovacuum_vacuum_threshold :detta har ett standardvärde på 50
- autovacuum_vacuum_scale_factor :detta har ett standardvärde på 0,2
Tillsammans säger dessa parametrar till PostgreSQL att starta ett autovakuum när antalet döda rader i en tabell överstiger antalet rader i den tabellen multiplicerat med skalfaktorn plus vakuumtröskeln. Med andra ord kommer PostgreSQL att starta autovakuum på ett bord när:
pg_stat_user_tables.n_dead_tup > (pg_class.reltuples x autovacuum_vacuum_scale_factor) + autovacuum_vacuum_threshold
För små till medelstora bord kan detta vara tillräckligt. Till exempel, en tabell med 10 000 rader måste antalet döda rader vara över 2 050 ((10 000 x 0,2) + 50) innan ett autovakuum börjar.
Inte alla tabeller i en databas upplever samma takt av datamodifiering. Vanligtvis kommer ett fåtal stora tabeller att uppleva frekventa datamodifieringar, och som ett resultat kommer det att ha ett högre antal döda rader. Standardvärdena kanske inte fungerar för sådana tabeller. Till exempel, med standardvärdena, kommer en tabell med 1 miljon rader att behöva ha mer än 200 050 döda rader innan ett autovakuum startar ((1 000 000 x 0,2) + 50). Detta kan innebära längre mellanrum mellan autovakuum, allt längre autovakuumtider och ännu värre, autovakuum körs inte alls om aktiva transaktioner på bordet låser det.
Därför bör målet vara att ställa in dessa trösklar till optimala värden så att autovakuum kan ske med jämna mellanrum och inte tar lång tid (och påverkar användarsessioner) samtidigt som antalet döda rader hålls relativt lågt.
Ett tillvägagångssätt är att använda den ena eller andra parametern. Så om vi ställer in autovacuum_vacuum_scale_factor till 0 och istället ställer in autovacuum_vacuum_threshold till exempelvis 5 000, kommer en tabell att autodammsugas när dess antal döda rader är fler än 5 000.
Tips 3:Finjustera tröskeln för automatisk analys
I likhet med autovakuum använder autoanalyze också två parametrar som bestämmer när autovacuum också ska utlösa en autoanalys:
- autovacuum_analyze_threshold :detta har ett standardvärde på 50
- autovacuum_analyze_scale_factor :detta har ett standardvärde på 0.1
Precis som autovacuum kan parametern autovacuum_analyze_threshold ställas in på ett värde som dikterar antalet infogade, raderade eller uppdaterade tuplar i en tabell innan en autoanalys startar. Vi rekommenderar att du ställer in denna parameter separat på tabeller med stora och höga transaktioner. Tabellkonfigurationen kommer att åsidosätta postgresql.conf-värdena.
Kodavsnittet nedan visar SQL-syntaxen för att ändra inställningen autovacuum_analyze_threshold för en tabell.
ALTER TABLE <table_name> SET (autovacuum_analyze_threshold = <threshold rows>)
Tips 4:Finjustera Autovacuum Workers
En annan parameter som ofta förbises av DBA är autovacuum_max_workers , som har ett standardvärde på 3. Autovakuum är inte en enda process, utan ett antal individuella vakuumtrådar som löper parallellt. Anledningen till att ange flera arbetare är för att säkerställa att dammsugning av stora tabeller inte fördröjer att dammsuga mindre tabeller och användarsessioner. Parametern autovacuum_max_workers säger till PostgreSQL att spinna upp antalet autovacuum-arbetartrådar för att göra rensningen.
En vanlig praxis för PostgreSQL DBAs är att öka antalet maximala arbetartrådar i hopp om att det kommer att påskynda autovakuum. Detta fungerar inte eftersom alla trådar delar samma autovacuum_vacuum_cost_limit , som har ett standardvärde på 200. Varje autovakuumgänga tilldelas en kostnadsgräns med den här formeln som visas nedan:
individual thread’s cost_limit = autovacuum_vacuum_cost_limit / autovacuum_max_workers
Kostnaden för arbete som utförs av en autovakuumgänga beräknas med hjälp av tre parametrar:
- vacuum_cost_page_hit :detta har ett standardvärde på 1
- vacuum_cost_page_miss :detta har ett standardvärde på 10
- vacuum_cost_page_dirty :detta har ett standardvärde på 20
Vad dessa parametrar betyder är detta:
- När en vakuumtråd hittar datasidan som den ska rengöra i den delade bufferten är kostnaden 1.
- Om datasidan inte finns i den delade bufferten, utan i OS-cachen, blir kostnaden 10.
- Om sidan måste markeras som smutsig eftersom vakuumtråden måste ta bort döda rader blir kostnaden 20.
Ett ökat antal arbetartrådar kommer att sänka kostnadsgränsen för varje tråd. Eftersom varje tråd tilldelas en lägre kostnadsgräns kommer den att gå i vila oftare eftersom kostnadströskeln lätt nås, vilket i slutändan gör att hela vakuumprocessen går långsamt. Vi rekommenderar att du ökar autovacuum_vacuum_cost_limit till ett högre värde, till exempel 2000, och sedan justerar det maximala antalet arbetartrådar.
Ett bättre sätt är att justera dessa parametrar för individuella tabeller endast när det behövs. Till exempel, om autovakuumet för en stor transaktionstabell tar för lång tid, kan tabellen tillfälligt konfigureras för att använda sin egen vakuumkostnadsgräns och kostnadsfördröjningar. Kostnadsgränsen och fördröjningen åsidosätter de systemomfattande värdena som ställts in i postgresql.conf.
Kodavsnittet nedan visar hur man konfigurerar individuella tabeller.
ALTER TABLE <table_name> SET (autovacuum_vacuum_cost_limit = <large_value>) ALTER TABLE <table_name> SET (autovacuum_vacuum_cost_delay = <lower_cost_delay>)
Att använda den första parametern kommer att säkerställa att autovakuumtråden som tilldelats bordet kommer att utföra mer arbete innan du går i viloläge. Sänker autovacuum_vacuum_cost_delay kommer också att innebära att tråden sover kortare tid.
Sluta tankar
Som du kan se är det enkelt att ändra konfigurationsparametrar för vakuum och analys, men det kräver noggrann observation först. Varje databas är olika vad gäller storlek, trafikmönster och transaktionshastighet. Vi rekommenderar att DBA:er börjar med att samla tillräckligt med information om sin databas innan de ändrar parametrarna eller rullar ut en manuell vakuum-/analysregim. Sådan information kan vara:
- Antal rader i varje tabell
- Antal döda tuplar i varje tabell
- Tidpunkten för det sista vakuumet för varje bord
- Tidpunkten för senaste analys för varje tabell
- Hastigheten för datainsättning/uppdatering/radering i varje tabell
- Den tid som autovakuum tar för varje bord
- Varningar om att bord inte dammsugs
- Aktuell prestanda för de flesta kritiska frågor och tabellerna de får åtkomst till
- Utförande av samma frågor efter en manuell vakuum/analys
Härifrån kan DBA:er välja några "pilot"-tabeller för att börja optimera. De kan börja ändra vakuum-/analysegenskaperna för tabellerna och kontrollera prestandan. PostgreSQL är en smart databasmotor – DBA:er kommer ofta att tycka att det förmodligen är bäst att låta PostgreSQL dammsuga och analysera istället för att göra det manuellt.