JournalindeksDockup / feltnote
Note / database-backups-you-have-restored

En backup, du aldrig har gendannet, er ikke en backup

Utestede database-backups fejler på forudsigelige måder: tomme dumps, manglende roller, forkerte flags eller en manglende krypteringsnøgle. Lær, hvordan du verificerer en gendannelse, så filen, du gemmer, faktisk virker.

Det værst tænkelige tidspunkt at opdage, at en backup ikke virker, er det øjeblik, du har brug for den. Og alligevel er det præcis det, der sker igen og igen: Backups bliver konfigureret én gang, et grønt flueben står i et dashboard i atten måneder, og derefter resulterer en gendannelse i en tom database.

Test af gendannelse fra en databasebackup er ikke en best practice på samme måde, som de fleste best practices er valgfrie. En backup er en påstand, og indtil du har gendannet en, er det en uprøvet påstand.

Her er, hvordan de fejler, og hvad en reel verifikation skal kontrollere.

De fire måder, en backup kan være ubrugelig på uden at nogen opdager det

1. Den er tom, og ingen har kigget

En pg_dump, der fejler undervejs, kan stadig producere en fil. Et dump, der køres mod det forkerte databasenavn, producerer en gyldig og korrekt tom fil. Begge dele ligner en succes for alt, der kun kontrollerer, om exit-koden er forskellig fra nul, eller om en fil eksisterer.

Den billigste kontrol i verden: Se på størrelsen, og sammenlign den med gårsdagens. En backup på 400 bytes, når gårsdagens var 40 MB, har fortalt dig alt. En backup, der har været 400 bytes i seks måneder, har fortalt dig det hele tiden.

2. Den indeholder data, men ikke det, der hører omkring dem

pg_dump af en enkelt database inkluderer ikke roller og heller ikke andre databaser. Gendan den på en ny server, og tabellerne dukker op, mens alle GRANT-kommandoer refererer til en rolle, der ikke findes. Din app opretter forbindelse og får permission denied på alt.

Extensions følger samme mønster. Hvis dit schema afhænger af pgcrypto eller uuid-ossp, og målet ikke har dem, fejler gendannelsen undervejs, så du ender med nogle tabeller.

3. Flags var forkerte til den gendannelse, du har brug for

pg_dump producerer forskellige ting afhængigt af formatet, og fejlen bliver som regel opdaget under pres:

  • Plain SQL gendannes med psql og kan læses af mennesker. Det kan ikke gendannes selektivt, og det er langsomt for store databaser.
  • Custom format (-Fc) gendannes med pg_restore, understøtter parallelisme og selektiv gendannelse og er det, du vil have til alt af en vis størrelse.

At tage backup i plain format, fordi det stod i tutorialen, og derefter opdage under en incident, at du ikke kan gendanne en enkelt tabel, er en helt særlig og undgåelig form for dårlig dag.

4. Du kan ikke dekryptere den

Hvis backups er krypterede — og det bør de være — er nøglen en del af backup’en. En nøgle, der kun ligger på den maskine, som gik tabt, eller kun i en environment variable for den service, der er nede, er en nøgle, du ikke har, når det gælder.

Sådan ser en reel verifikation ud

Testen er ikke: "Findes filen?" Det er at gendanne den et andet sted og stille den et spørgsmål.

# 1. Restore into a scratch database, not the live one
createdb verify_$(date +%Y%m%d)
pg_restore -d verify_$(date +%Y%m%d) --no-owner --no-privileges latest.dump

# 2. Ask it something only real data can answer
psql -d verify_$(date +%Y%m%d) -c "
  select
    (select count(*) from users)            as users,
    (select count(*) from orders)           as orders,
    (select max(created_at) from orders)    as newest_order;
"

# 3. Drop it
dropdb verify_$(date +%Y%m%d)

Trin 2 er hele pointen. En gendannelse, der gennemføres uden fejl, fortæller dig stadig intet om, hvorvidt dataene faktisk er der. Det gør antal rækker og et tjek af, hvor aktuelle dataene er.

Tre ting, der er værd at verificere:

  • Antallet af rækker ligger i den rigtige størrelsesorden. Ikke præcist — data ændrer sig — men en tabel, der havde 200.000 rækker og nu har 12, er en fejl.
  • Den nyeste post er aktuel. Hvis den seneste ordre i din "nightly"-backup er fra marts, stoppede dit backup-job i marts.
  • Appen kan faktisk oprette forbindelse. Peg en staging-instans på den gendannede database, og indlæs én side.

Gør det efter en plan, ikke efter en resolution

En realistisk frekvens er månedligt og automatiseret, med resultatet et sted, hvor du lægger mærke til det. En kalenderpåmindelse om at "teste backups" er en påmindelse, du bare udskyder.

Det, der får det til at fungere i praksis, er at gøre fejlen tydelig: Hvis verifikationsforespørgslen returnerer færre rækker end en bestemt tærskel, skal det sende en alert til nogen på samme måde som en produktionsfejl. Et backupsystem, der fejler lydløst, kan ikke skelnes fra intet backupsystem — lige indtil det bliver vigtigt.

Sådan håndterer Dockup det

Tre beslutninger, som hver især er rettet mod en bestemt fejl ovenfor.

Backups gemmes et andet sted. En backup på den samme disk som databasen er ikke en backup — det er en kopi, der forsvinder sammen med disken. Dockup streamer database-backups direkte til object storage, efterhånden som de bliver produceret, så filen aldrig afhænger af den host, der oprettede den.

De er krypterede, og nøglen ligger ikke på maskinen. Backups krypteres med AES-256-GCM, mens de streames. Det relevante i forbindelse med recovery er, at nøglen opbevares af platformen i stedet for at ligge i environment for den service, der bliver taget backup af.

En backup, der ikke producerede noget, registreres ikke som en backup. Det er den beslutning, der direkte håndterer fejlen med den tomme fil: Hvis dumpet afsluttes med en exit-kode forskellig fra nul eller producerer nul bytes, slettes uploaden, og backup’en registreres som mislykket. Du ender ikke med en liste af grønne poster, hvor én af dem er en fil på 400 bytes.

dockup db backup my-project/main-db --json     # take one now
dockup db backups my-project/main-db --json    # list them with sizes

Størrelserne i den liste er det billigste health check, du har. Hold øje med udviklingen.

Det ubehagelige spørgsmål

Hvis din produktionsdatabase blev ødelagt i løbet af de næste ti minutter, hvor lang tid ville det tage dig at have den tilbage, og hvor meget ville du have mistet?

Hvis du ikke kan svare på begge tal, har du ikke en backupstrategi — du har backupfiler. Forskellen ligger udelukkende i, om nogen nogensinde har gennemført en gendannelse.

Ofte stillede spørgsmål

Hvor ofte bør jeg teste en gendannelse? Månedligt er et fornuftigt udgangspunkt, automatiseret frem for manuelt. Det vigtige er, at en fejl bliver tydelig, ikke at frekvensen er høj.

Hvorfor blev min gendannelse gennemført, men uden data? Som regel blev dumpet taget mod den forkerte database, eller også fejlede det undervejs, mens filen stadig blev skrevet. Sammenlign backupstørrelser over tid — et tomt dump er tydeligt i en størrelsesudvikling og usynligt i en statuskolonne.

Bør backups være krypterede? Ja, og nøglen skal ligge et sted, der overlever, at du mister maskinen. En krypteret backup, hvis nøgle lå på den mistede server, kan ikke gendannes.

Er et snapshot det samme som en backup? Nej. Et volume-snapshot fanger disken, inklusive den tilstand databasen var i på det pågældende tidspunkt. Et logisk dump er konsistent by design. De fleste teams vil have begge dele til forskellige fejlscenarier.