Joan edukira

Babeskopia, une jakin bateko berreskuratzea eta leheneratze-proba

Egin Quireren babeskopia, leheneratu une jakin batera eta frogatu leheneratze-probarekin.

Ikusi Markdown gisa

Diseinua docs/architecture/23-ops.md ataleko 8. atalean dago. Docker Compose bidezko produktuaren eragiketa-gida da hau. Idatzi duen pertsonak ez den norbaitek jarraitu ahal izateko idatzi da; urrats bat argi ez badago, dokumentu honen akatsa da.

Zer babesten da eta nola

Baliabidea Modua Kokapena
Datu-basea WAL etengabe artxibatzen da, gehienez 60 segundoan behin, lehen abiaraztetik pgwal bolumena
Datu-basea Oinarrizko babeskopiak pg_basebackup erabiliz, lehenespenez egunero (backup-scheduler) pgbackup bolumena
Datu-basea Oinarrizko babeskopien eta WALaren kopia zifratuak, bost minutuan behin (backup-offsite) Zuk izendatutako biltegi bereizia
Fitxategiak files bolumena. Kopiatu ostalariaren babeskopia-tresnarekin edo erabili bertsiodun objektu-biltegiratzea files bolumena
Sekretuak docker/.env, bereziki QUIRE_MASTER_KEY (eta oraindik erabiltzen den QUIRE_MASTER_KEY_RETIRED oro), QUIRE_BACKUP_ENCRYPTION_KEY eta docker/secrets/audit-signing-key.pem Gorde kopia bat ostalari honetatik kanpo
Bilaketa-indizeak, cacheak, bertsio errendatuak Ez dira babeskopiatzen; berreraikitzen dira

Helburuak: hutsegitearen aurreko 60 segundoen barruko berreskuratze-puntua, eta 500 GBko datu-base bat 60 minutuan leheneratzea.

Bi akats ohikoak dira. Fitxategirik gabe leheneratutako datu-baseak orrialde hautsiak sortzen ditu. QUIRE_MASTER_KEY gabe leheneratutako datu-baseak ezin ditu dituen SSO, webhook eta integrazio-kredentzialak deszifratu; gako nagusiaren biraketa konpondu gabeko baliorik gabe amaitu arte (key-rotation.md), hor sartzen dira erretiratutako gakoak ere. Biak babeskopiaren parte dira.

Babeskopiak egitea

Kluster osoaren oinarrizko babeskopia egiteko:

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

Azken QUIRE_BACKUP_KEEP oinarrizko babeskopiak gordetzen ditu (lehenetsia 5), eta zaharrenak behar ez dituen WALa ezabatzen du, artxiboa etengabe haz ez dadin. Antolatu egunero ostalariko cron edo systemd timer erabiliz:

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

Edo utzi pilari programazioa kudeatzen: backup profilak backup-scheduler abiarazten du; horrek oinarrizko babeskopia egiten du QUIRE_BACKUP_INTERVAL_HOURS tartean behin (lehenetsia 24), eta hurrengo atalean azaltzen den backup-offsite ere bai.

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

Ostalaritik kanpoko kopia zifratuak

Bi bolumenak datu-basearen ostalari berean daude, eta huts egin duen ordenagailuan dagoen babeskopia ez da babeskopia. backup-offsite zerbitzuak oinarrizko babeskopia bakoitza eta artxibatutako WAL segmentu bakoitza biltegi bereizi batera kopiatzen ditu biltegiratze-atazatik, zifratuta; han gordetzen ditu atxikipen-arauen arabera:

  • Zifratzea. AES-256-GCM QUIRE_BACKUP_ENCRYPTION_KEY gakoarekin (edo QUIRE_BACKUP_ENCRYPTION_KEY_FILE aldagaiak izendatutako fitxategiarekin): 32 byte, openssl rand -hex 32 bidez sortuak. Fitxategi bakoitzak bere nonce-a eta autentifikazio-etiketa ditu; beraz, gakorik gabe ezin da kopia irakurri, eta aldaketak hautematen dira. Gorde gakoa QUIRE_MASTER_KEY gakoarekin batera, ostalari honetatik eta babeskopia-biltegiratzetik aparte. Gakorik gabe ez dago leheneratzerik.
  • Kokapena. QUIRE_BACKUP_STORAGE_DRIVER aldagaia s3, azure edo local da (muntatutako urruneko diskoa QUIRE_BACKUP_STORAGE_ROOT helbidean). Ezarpenak fitxategiak biltegiratzekoen berdinak dira, QUIRE_BACKUP_ aurrizkiarekin: QUIRE_BACKUP_S3_ENDPOINT, QUIRE_BACKUP_S3_BUCKET, QUIRE_BACKUP_S3_ACCESS_KEY_ID eta abar. Erabili fitxategienak ez bezalako bucket bat eta, ahal dela, beste kontu bat; ahal bada, eman idazteko baina ez ezabatzeko baimena duten kredentzialak.
  • Atxikipena. Azken QUIRE_BACKUP_OFFSITE_KEEP oinarrizko babeskopiak (lehenespenez QUIRE_BACKUP_KEEP, edo, hori ez badago, 7) eta zaharrenak behar duen WALa; zaharragoak diren multzoak eta segmentuak biltegitik ezabatzen dira.
  • Noiz. QUIRE_BACKUP_SHIP_INTERVAL_SECONDS tartean behin (lehenetsia 300). Bidalketa idempotentea da: gordeta dagoena saltatzen du, eta oinarrizko babeskopia manifestua azkenik idatzi ondoren baino ez da gordetzat jotzen.

Komando bera eskuz exekuta daiteke:

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

Ostalari berri batean leheneratzeko, ekarri multzo bat lehenik; ondoren, jarraitu beheko urratsei, eskuratutako direktorioa pgbackup bolumenaren ordez eta eskuratutako wal-archive direktorioa pgwal bolumenaren ordez erabiliz:

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

Une jakin batera leheneratzea

Erabili hau datuak galdu ondoren: inportazio oker bat, ezabatutako ikastaro bat edo desegin behar duzun kontratu-migrazio bat. Zuzeneko datu-basea ordezkatzen du; beraz, egin beheko proba lehenik.

  1. Aukeratu helburu-ordua, UTCan, kaltea gertatu aurrekoa: 2026-09-24 09:30:00+00. Auditoretza-erregistroak (/admin/audit) une hori erakusten du normalean.
  2. Gelditu idazten duen guztia: docker compose -f docker/compose.yaml stop web content worker scheduler collab
  3. Gorde kaltetutako klusterra leheneratzea egiaztatu arte:
    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. Despaketatu helburu-ordua baino lehenagoko oinarrizko babeskopiarik berriena datu-bolumenean, eta eskatu une jakinera mugatutako leheneratzea:
    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. Berreskuratu: abiarazi Postgres behin leheneratze-ezarpenekin, Compose override bat erabiliz ohiko fitxategia ukitu gabe:
    # 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]
    Override-ak komando osoa ordezkatzen du; beraz, berreskuratzeak behar dituen bi ezarpenak errepikatzen ditu: max_connections nagusiaren balioa bezain handia edo handiagoa (bestela berreskuratzeak “insufficient parameter settings” errorearekin huts egiten du), eta muntatutako pg_hba.conf fitxategia.
    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. Egiaztatu inor sartzen utzi aurretik: auditoretza-katea (docker compose -f docker/compose.yaml run --rm worker bun tooling/audit-verify/run.ts), eta galdutako datuak itzuli direla.
  7. Itzuli ohiko egoerara: docker compose -f docker/compose.yaml up -d. Postgres berriro abiarazten du artxibatzea aktibatuta, eta WALen denbora-lerro berri bat hasten da. Egin berehala oinarrizko babeskopia berria.

quire proiektu-izenak aurrizkia eransten die bolumen guztiei; docker volume ls komandoak izen zehatzak erakusten ditu.

Programatutako egiaztapen-proba

backup-offsite zerbitzuak proba bat ere egiten du QUIRE_BACKUP_DRILL_INTERVAL_HOURS tartean behin (lehenetsia 168, astero), eta berriro, hutsegite baten ondorengo hurrengo txandan. Ostalaritik kanpoko oinarrizko babeskopiarik berriena eta ondorengo WAL segmentu guztiak eskuratzen ditu, eta bakoitza deszifratzen du (gakoak irekitzen dituela eta ezer aldatu ez dela frogatzeko); fitxategiak manifestuarekin alderatzen ditu; artxiboa Postgres datu-direktorioa dela egiaztatzen du; eta babeskopiatik aurrerako WALean hutsunerik ez dagoela ziurtatzen du. Txostena biltegian reports/drill-<time>.json gisa eta zerbitzuaren erregistroan idazten da; huts egindako probak fitxategia edo falta den lehen segmentua adierazten du.

Leheneratze-proba

Inoiz leheneratu ez den babeskopia ez da babeskopia. Probak helburu-ordua baino lehen egindako oinarrizko babeskopia osatu berriena eta WAL artxiboa leheneratzen ditu, zuzeneko datu-basetik ezer partekatzen ez duen Postgres aldi baterako batean, eta emaitza frogatzen du:

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

Helburua UTC da, formatu zehatz horretan. Helburua baino zaharragoa den oinarrizko babeskopia eta ondorengo artxibatutako WALa behar ditu: instalazio berrian, egin oinarrizko babeskopia eta itxaron artxibatutako hurrengo segmentuari (idazketak badaude, minutu bat gehienez), eta aukeratu babeskopiaren ondorengo helburu bat. Probak Docker eta bash besterik ez ditu behar ostalarian.

Urrats bakoitzak probak huts egitea eragiten du:

  1. Berreskuragarritasuna: aldi baterako klusterrak helburuko punturaino erreproduzitzen du eta ireki egiten da.
  2. Osotasuna: taula bakoitzeko errenkada-kopurua zuzeneko datu-basearekiko alderatzen da (tooling/restore-drill). Zuzeneko datu-baseak aurrera egin du helburu-ordutik; beraz, taula batek gehienez 500 errenkadako edo tamainaren hamarren bateko aldea izan dezake, bi noranzkoetan (idazketek atzeratzea eragiten dute, ezabatzeek leheneratutako kopia handiagoa izatea); helburuaren ondoren sortutako partizioa ez da galdutako taula. Handitu tartea instalazio aktiboago batean QUIRE_DRILL_MAX_BEHIND eta QUIRE_DRILL_MAX_DRIFT_RATIO ezarriz. Falta den edo hustutako taula batek huts eginarazten du.
  3. Osotasun kriptografikoa: auditoretza-hash katea leheneratutako kopian baliozkoa dela egiaztatzen da.
  4. Erabilgarritasuna: aplikazio-rolak errenkada-mailako segurtasunaren bidez irakurtzen du.
  5. Iraupena: hasieratik emaitza berdera arteko denbora, QUIRE_DRILL_RTO_SECONDS mugaren barruan (lehenetsia 3600).

Inoiz ez du zuzeneko datu-basean edo haren bolumenetan idazten: babeskopia eta WAL bolumenak irakurtzeko soilik muntatzen dira, eta aldi baterako klusterra amaieran ezabatzen da, arrakasta edo hutsegitea izan.

Ezarri QUIRE_DRILL_REPORT bide bat adierazteko, JSON txostena idatz dadin arrakastaz edo huts eginda, eta exekutatu aldizka Docker ostalaritik:

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

Egin hilero eta bertsio-berritze bakoitzaren aurretik. Huts egindako probak bertsio-berritzea blokeatzen du. Hiruhileko bakoitzean, eskatu gida hau idatzi ez duen norbaiti ordezko ostalari batean une jakin baterako benetako leheneratzea egiteko, dokumentu hau soilik erabilita.

Fitxategiak

Fitxategi lokalak files bolumenean daude. Egin datu-basearekin batera eta une berean haien babeskopia, eta leheneratu biak batera:

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 .

Objektu-biltegiratzea erabiliz gero, aktibatu bucket-eko bertsioak eta gorde bertsio zaharrak 35 egunez; une jakin baterako fitxategi-berreskuratzea bucket-aren ardura izango da.

Nabigazioa

Idatzi bilatzeko…

↑↓ nabigatu↵ hautatuEsc itxi