Mine sisu juurde

Varundamine, ajahetke taastamine ja taastamiskatse

Varunda Quire, taasta see ajahetke seisundisse ja tõesta taastatavust katsega.

Vaata Markdownina

Arhitektuur on kirjeldatud dokumendi docs/architecture/23-ops.md jaotises 8. See on Docker Compose’i toote juhend. Juhend on kirjutatud inimesele, kes seda ise ei koostanud; iga ebaselge samm on puudus dokumendis.

Mis on kaitstud ja kuidas

Vara Kuidas Kus
Andmebaas WAL arhiveeritakse pidevalt, kuni 60-sekundiliste vahedega, esimesest käivitusest alates pgwal köide
Andmebaas Põhi-varukoopiad pg_basebackup-iga, vaikimisi kord päevas (backup-scheduler) pgbackup köide
Andmebaas Põhi-varukoopiate ja WAL-i krüptitud koopiad iga viie minuti järel (backup-offsite) Sinu määratud eraldi hoidla
Failid files-köide. Kopeeri see hosti varundustööriistaga või kasuta versioonitud objektisalvestust files-köide
Saladused docker/.env, eriti QUIRE_MASTER_KEY (ja kasutusel olev QUIRE_MASTER_KEY_RETIRED), QUIRE_BACKUP_ENCRYPTION_KEY ning docker/secrets/audit-signing-key.pem Hoia koopiat hostist eemal
Otsinguindeksid, vahemälud, teisendatud failid Ei varundata; ehitatakse uuesti

Eesmärgid: rikke korral taastamispunkt kuni 60 sekundi kaugusel ning 500 GB andmebaasi taastamine kuni 60 minutiga.

Kaks viga korduvad sageli. Andmebaasi taastamisel ilma failideta kuvatakse katkiseid lehti. Andmebaas, mis taastati ilma QUIRE_MASTER_KEY-ta, ei saa dekrüptida salvestatud SSO, veebikonksu ja integratsiooni mandaate; kuni peavõtme vahetamine on lõpetatud nii, et midagi pole lahendamata (key-rotation.md), kehtib see ka pensionile jäetud võtmete kohta. Varunda mõlemad.

Varundamine

Tee kogu klastrist põhi-varukoopia:

docker compose -f docker/compose.yaml --profile backup run --rm backup

Alles jäetakse uusimad QUIRE_BACKUP_KEEP varukoopiad (vaikimisi 5) ning kustutatakse vanimale enam mittevajalik WAL, et arhiiv piiramatult ei kasvaks. Ajasta hostis igapäevane käivitus croni või systemd taimeriga:

15 2 * * * cd /srv/quire && docker compose -f docker/compose.yaml --profile backup run --rm backup >> /var/log/quire-backup.log 2>&1

Või lase virnal ajastada: backup-profiil käivitab backup-scheduleri, mis teeb põhi-varukoopia iga QUIRE_BACKUP_INTERVAL_HOURS järel (vaikimisi 24) ning järgmises jaotises kirjeldatud backup-offsitei.

docker compose -f docker/compose.yaml --profile backup up -d

Krüptitud koopiad väljaspool hosti

Mõlemad köited asuvad andmebaasiga samas hostis, seega rikkis masina varukoopia pole päris varukoopia. backup-offsite kopeerib iga põhi-varukoopia ja arhiveeritud WAL-i segmendi üle salvestuspordi krüptitult eraldi hoidlasse ning rakendab säilitusreeglit:

  • Krüptimine. AES-256-GCM võtmega QUIRE_BACKUP_ENCRYPTION_KEY või faili QUIRE_BACKUP_ENCRYPTION_KEY_FILE abil: 32 baiti, loodud käsuga openssl rand -hex 32. Igal failil on oma nonce ja autentimismärgend, seega pole koopiat võtmeta võimalik lugeda ning muudatus tuvastatakse. Hoia võtit koos QUIRE_MASTER_KEY-ga sellest hostist ja varundushoidlast eraldi. Võtmeta ei saa taastada.
  • Asukoht. QUIRE_BACKUP_STORAGE_DRIVER on s3, azure või local (ühendatud kaugketas aadressil QUIRE_BACKUP_STORAGE_ROOT). Seaded on samad mis failisalvestusel, kuid eesliitega QUIRE_BACKUP_: QUIRE_BACKUP_S3_ENDPOINT, QUIRE_BACKUP_S3_BUCKET, QUIRE_BACKUP_S3_ACCESS_KEY_ID jne. Kasuta failidest eraldi ämbrit ja võimalusel eraldi kontot; luba kirjutamine, kuid võimalusel keela pakkuja seadetes kustutamine.
  • Säilitamine. Uusimad QUIRE_BACKUP_OFFSITE_KEEP põhi-varukoopiad (vaikimisi QUIRE_BACKUP_KEEP, muidu 7) ja vanimale neist vajalik WAL; vanemad kogumid ja segmendid kustutatakse hoidlast.
  • Millal. Iga QUIRE_BACKUP_SHIP_INTERVAL_SECONDS järel (vaikimisi 300). Edastus on korduskindel: juba salvestatud failid jäetakse vahele ning põhi-varukoopia loetakse talletatuks alles siis, kui manifest on viimaks kirjutatud.

Käsitsi käitatakse sama käsku:

docker compose -f docker/compose.yaml run --rm backup-offsite bun apps/worker/src/backups/main.ts ship
docker compose -f docker/compose.yaml run --rm backup-offsite bun apps/worker/src/backups/main.ts verify

Uues hostis taastamiseks too varukoopiate komplekt esmalt tagasi ja järgi allpool olevaid samme; kasuta toodud kataloogi pgbackup-köite ning toodud wal-archive kausta pgwal-köite asemel:

bun apps/worker/src/backups/main.ts fetch base-20260924T021500Z /srv/restore

Taastamine ajahetke seisundisse

Kasuta seda andmekao järel: vigane import, kustutatud kursus või tagasivõtmist vajav andmebaasimuudatus. See asendab aktiivse andmebaasi, seega harjuta esmalt allpool oleva taastamiskatsega.

  1. Vali sihtaeg UTC-s, vahetult enne kahju: 2026-09-24 09:30:00+00. Tavaliselt näitab hetke auditi logi (/admin/audit).
  2. Peata kõik kirjutavad teenused: docker compose -f docker/compose.yaml stop web content worker scheduler collab
  3. Hoia kahjustatud klaster alles, kuni taastamine on kontrollitud:
    docker compose -f docker/compose.yaml stop postgres
    docker run --rm -v quire_postgres18-data:/from -v quire_postgres-damaged:/to alpine cp -a /from/. /to/
  4. Paki sihtajast vanim uusim põhi-varukoopia andmeköitesse lahti ja palu teha sihitud taastamine:
    docker run --rm -v quire_pgbackup:/backups:ro -v quire_postgres18-data:/var/lib/postgresql postgres:18-alpine sh -euc '
      base="$(ls -1d /backups/base-* | sort | tail -n 1)"   # or the one before the target
      rm -rf /var/lib/postgresql/18/docker && mkdir -p /var/lib/postgresql/18/docker
      tar -xzf "$base/base.tar.gz" -C /var/lib/postgresql/18/docker
      touch /var/lib/postgresql/18/docker/recovery.signal
      chown -R postgres:postgres /var/lib/postgresql/18/docker && chmod 700 /var/lib/postgresql/18/docker'
  5. Taasta: käivita Postgres üks kord taasteseadetega, kasutades ülekirjutusfaili, et tavapärane fail jääks muutmata:
    # docker/compose.recover.yaml
    services:
      postgres:
        command: [postgres, -c, "restore_command=cp /var/lib/postgresql/wal-archive/%f %p",
                  -c, "recovery_target_time=2026-09-24 09:30:00+00",
                  -c, recovery_target_action=promote, -c, archive_mode=off,
                  -c, max_connections=200, -c, hba_file=/etc/postgresql/pg_hba.conf]
    Ülekirjutus asendab kogu käsu, nii et taasteks tuleb lisada kaks vajalikku seadet: max_connections peab olema vähemalt esmase väärtus (muidu katkeb taastamine veaga “insufficient parameter settings”) ning määrata tuleb ühendatud pg_hba.conf.
    docker compose -f docker/compose.yaml -f docker/compose.recover.yaml up -d postgres
    docker compose -f docker/compose.yaml logs -f postgres   # wait for "database system is ready"
  6. Kontrolli enne kellegi sisselaskmist auditi ahelat (docker compose -f docker/compose.yaml run --rm worker bun tooling/audit-verify/run.ts) ning veendu, et kadunud andmed on tagasi.
  7. Taastu tavakäiduks: docker compose -f docker/compose.yaml up -d. Postgres käivitub arhiveerimisega uuesti ja algab uus WAL-i ajajoon. Tee kohe värske põhi-varukoopia.

Projektinimi quire lisatakse iga köite ette; täpseid nimesid näitab docker volume ls.

Ajastatud kontrollkatse

backup-offsite käivitab katse iga QUIRE_BACKUP_DRILL_INTERVAL_HOURS järel (vaikimisi 168 tundi ehk kord nädalas) ning pärast nurjumist kohe järgmisel käivitusel uuesti. See hangib uusima hostivälise põhi-varukoopia ja sellele järgnevad WAL-i segmendid, dekrüptib need (kontrollides, et võti neid avab ja neid pole muudetud), võrdleb faile manifestiga, kontrollib arhiivi kui Postgresi andmekataloogi ning veendub, et varukoopiale järgnev WAL on terviklik. Aruanne salvestatakse hoidlas nimega reports/drill-<time>.json ja teenuse logis; nurjunud katse nimetab faili või esimest puuduvat segmenti.

Taastamiskatse

Varukoopia, mida pole kunagi taastatud, pole tõestatud varukoopia. Katse taastab uusima täieliku sihtajale eelnenud põhi-varukoopia koos WAL-arhiiviga ajutisse Postgresesse, mis ei jaga aktiivsega midagi, ning kontrollib tulemust:

docker/scripts/restore-drill.sh                                  # to ninety minutes ago
docker/scripts/restore-drill.sh --target "2026-09-24 09:30:00+00"

Sihtaeg peab olema täpselt sellises UTC-vormingus. Vajalik on sellest varasem põhi-varukoopia ja sellele järgnev arhiveeritud WAL: uuel paigaldusel tee põhi-varukoopia ja oota enne hilisema sihtaja valimist järgmist arhiveeritud segmenti (kirjutuste korral kõige rohkem minut). Katseks on hostis vaja üksnes Dockerit ja bashi.

Iga samm võib katse nurjata:

  1. Taastatavus: ajutine klaster taasesitab andmed sihtajani ja avaneb.
  2. Täielikkus: iga tabeli ridade arvu võrreldakse aktiivse andmebaasiga (tooling/restore-drill). Aktiivne andmebaas on sihtajast edasi liikunud, seega võib tabelite ridade arv mõlemas suunas erineda suuremal väärtusel kahest: 500 rida või kümnendik tabeli suurusest (kirjutused tekitavad mahajäämust, kustutused jätavad taastatud koopias rohkem ridu); pärast sihtaega loodud sektsioon pole kadunud tabel. Suurema liiklusega paigaldises suurenda lubatud vahet muutujatega QUIRE_DRILL_MAX_BEHIND ja QUIRE_DRILL_MAX_DRIFT_RATIO. Puuduv või tühjaks jäänud tabel tähendab nurjumist.
  3. Terviklus: taastatud koopias kontrollitakse auditi räsiahelat.
  4. Kasutatavus: rakenduseroll saab lugeda rea-taseme turbe kaudu.
  5. Aeg: käivitamisest eduni kuluv aeg jääb QUIRE_DRILL_RTO_SECONDS piiridesse (vaikimisi 3600).

Katse ei kirjuta kunagi aktiivsesse andmebaasi ega selle köidetesse: varukoopia- ja WAL-köited ühendatakse kirjutuskaitstult ning ajutine klaster eemaldatakse lõpus nii edu kui ka nurjumise korral.

Määra QUIRE_DRILL_REPORT aruandefaili asukohaks, et JSON kirjutataks nii edu kui ka nurjumise korral, ning ajasta hosti Dockeris:

30 3 1 * * cd /srv/quire && QUIRE_DRILL_REPORT=/var/log/quire-drill.json docker/scripts/restore-drill.sh >> /var/log/quire-drill.log 2>&1

Käivita seda iga kuu ja enne iga uuendust. Nurjunud katse takistab uuendamist. Kord kvartalis palu inimesel, kes juhendit ei kirjutanud, teha päris ajahetke taastamine varuhostis ainult selle dokumendi põhjal.

Failid

Kohalikud failid paiknevad files-köites. Varunda need andmebaasiga samal ajal ning taasta mõlemad koos:

docker run --rm -v quire_files:/files:ro -v "$PWD":/out alpine tar -czf /out/files-$(date -u +%Y%m%d).tar.gz -C /files .

Objektisalvestuse korral lülita sisse ämbri versioonimine ja säilita vanu versioone 35 päeva; siis haldab failide ajahetke taastamist ämber ise.

Navigeerimine

Otsimiseks kirjuta…

↑↓ liikumine↵ valiEsc sulge