sql >> Database teknologi >  >> RDS >> PostgreSQL

PostgreSQL 13:Lad ikke slots dræbe din primære

En af de interessante funktioner i PostgreSQL siden version 9.4 er evnen til at kontrollere fjernelse af WAL-filer ved hjælp af replikeringspladser. Den mørke side er, at replikationsslots kan få diske til at fylde op med gammel WAL, hvilket dræber hovedproduktionsserveren. I denne artikel forklarer jeg PostgreSQL-replikeringsslots, og hvordan en ny funktion i PostgreSQL 13 hjælper med at forhindre dette problem.

WAL-produktion

Som du ved, er WAL produceret til databaseændringer på en primær server:indsættelser, opdateringer, et cetera . En mere aktiv database vil producere mere WAL - i en meget aktiv server kan der produceres mange gigabyte WAL hvert minut. WAL skrives til filer med navne i stigende numerisk rækkefølge, og filerne har altid samme størrelse (16 MB er standard og typisk). Når dataene i en fil ikke længere er nødvendige, kan den fil genbruges , hvilket betyder at omdøbe den til en højere nummereret position i sekvensen, så den kan udfyldes med nye data senere.

(Der er særlige situationer, såsom en stigning i aktivitet, der fører til oprettelse af yderligere filer; når stigningen senere aftager, fjernes de ekstra filer i stedet for at blive genbrugt.)

Fordi al databaseskriveaktivitet producerer WAL, er det afgørende for diskplads at være tilgængelig. Når disken, der lagrer WAL, er fuld, vil serveren ikke være i stand til at behandle nye transaktioner og kan sætte sig fast, eller endnu værre:den kan vælte fuldstændigt. Så dette er en situation, der skal undgås med alle mulige midler.

Replikeringspladser

Replikering i PostgreSQL fungerer ved at behandle WAL-filer. For at dette skal virke, skal alle WAL-filer være midlertidigt tilgængelige, indtil de er behandlet. Derfor er der behov for en mekanisme til at fortælle hoved-WAL-ledelsen ikke at genbruge eller fjerne filer.

Indtast replikationsslots. Slots er en mekanisme, der indikerer, at dette backup, vi tager, kræver det WAL fil, og kan du ikke slette den endnu; eller denne replika har stadig ikke behandlet det WAL-fil, så kan den stå i fred et stykke tid.

I sig selv optager replikeringspladser meget lidt diskplads. De gemmer bare en lille smule metadata, inklusive en pointer til en position i WAL. Men de WAL-data, den beskytter, er en anden sag:På en meget aktiv server kan de måles i gigabyte eller værre.

WAL-forbrug

At fodre data til en fysisk replika betyder at kopiere WAL-dataene fra dens primære server. På samme måde skal en logisk replika læse WAL-data (og overføre en fortolket version til replikaen). Den WAL-position, der aflæses, er det, som spalten holder styr på. Når replikaen på en eller anden måde har sikret WAL-dataene, kan slottet rykkes frem; dette fortæller WAL-administrationen i den primære, at WAL-filen så er tilgængelig til fjernelse. Dette sker løbende, når replikaen er aktiv, så WAL i den primære server vil bruge den samme mængde diskplads eller måske bare lidt mere. Selv dobbelt så meget eller ti gange så meget kan være acceptabelt, afhængigt af forholdene.

Problemet er, at hvis en replika dør fuldstændigt og ikke kommer sig i en længere periode; eller replikaen er ødelagt, og DBA'en glemmer at fjerne replikationsåbningen; eller pladsen er en glemt rest af et eksperiment; eller endda replikaen bliver fodret over en langsom netværksforbindelse, så vil den reserverede WAL vokse uden grænser. Og det bliver en tikkende bombe.

Begrænsning af pladsstørrelse

For at bekæmpe dette problem havde Kyotaro Horiguchi arbejdet siden februar 2017 i en PostgreSQL-patch for at begrænse størrelsen af ​​WAL reserveret af en slot. Efter en meget lang gennemgang og omarbejdningsproces integrerede jeg det til PostgreSQL 13, hvilket forbedrede styringen af ​​PostgreSQL-farme med høj tilgængelighed.

Hovedprincippet er, at det er bedre at dræbe en replika (ved på en eller anden måde at gøre dens slot ugyldig; mere om det nedenfor) end at dræbe den primære server, der fodrer den replika og tage al produktion ned med den.

Måden det fungerer på er ret ligetil:indstil max_slot_wal_keep_size (dokumentation) i postgresql.conf til den maksimale mængde diskplads i WAL, som replikeringspladser må reservere. Hvis et slot når det punkt, og der opstår et kontrolpunkt, vil det slot blive markeret som ugyldigt, og nogle WAL-filer kan blive slettet. Hvis slot var i aktiv brug af en walsender proces, vil den proces blive signaleret, så den afsluttes. Hvis walsenderen starter igen, vil den opdage, at nødvendige WAL-filer ikke vil være der længere. Replikaen, der bruger denne plads, skal genklones.

Hvis max_slot_wal_keep_size er nul, hvilket er standardværdien, så er der ingen grænse. Jeg anbefaler ikke dette, fordi det fører til fejl, når slots fylder disken.

Overvågning af spilleautomatens sundhed

Nogle overvågningsfunktioner er også inkluderet. To kolonner i pg_replication_slots er relevante. Den mest kritiske er wal_status . Hvis den kolonne er reserved , så peger pladsen på data inden for max_wal_size; hvis den er extended så overskred den max_wal_size , men er stadig beskyttet af enten wal_keep_size eller max_slot_wal_keep_size (inklusive når max_slot_wal_keep_size er nul). Begge tilstande er gode og normale. Men når et slot kommer over grænsen, bliver det først unreserved , hvilket betyder, at den er i overhængende fare, men kan stadig komme sig, hvis den er hurtig nok. Til sidst bliver status lost når WAL-filer er blevet fjernet og ingen gendannelse er mulig.

Den anden kolonne er safe_wal_size :den viser antallet af bytes af WAL, der kan skrives, før denne slot kommer i fare for at få fjernet WAL-filer. Vi foreslår at holde et vågent øje med denne kolonne i dit overvågningssystem og udløse alarmer, når det bliver lavt. Nul eller negativ betyder, at din replika vil være død, så snart et kontrolpunkt opstår:

SELECT slot_name, active, wal_status, safe_wal_size
  FROM pg_catalog.pg_replication_slots;

Vi mener, at denne nye funktion gør vedligeholdelse af replikaer lettere og mere robust; forhåbentlig vil vi ikke se flere katastrofer med produktionen nede på grund af disse problemer.

(En bemærkning:safe_wal_size blev introduceret i 13beta3, så sørg for at konsultere den opdaterede dokumentation, ellers vil du se min_safe_lsn i stedet. Ignorer det.)

Tak

Særlig tak til Kyotaro Horiguchi for arbejdet med at løse dette problem. Adskillige anmeldere kom dybt ind i dette, blandt dem vil jeg gerne takke især Masahiko Sawada, Fujii Masao, Jehan-Guillaume de Rorthais og Amit Kapila (uden bestemt rækkefølge).


  1. Søvnfunktion i ORACLE

  2. Vælg antal rækker i en anden tabel i en Postgres SELECT-sætning

  3. Python List til PostgreSQL Array

  4. Hvordan forbinder man to tabeller på et fremmednøglefelt ved hjælp af django ORM?