---
title: "Ehtiyat nüsxə, vaxt nöqtəsinə bərpa və bərpa sınağı"
description: "Quire-in ehtiyat nüsxəsini yaradın, vaxt nöqtəsinə bərpa edin və bərpa sınağı ilə yoxlayın."
image: "https://docs.quirelms.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.quirelms.com/az/llms.txt
> Use this file to discover all available pages before exploring further.

# Ehtiyat nüsxə, vaxt nöqtəsinə bərpa və bərpa sınağı

<span id="backup-point-in-time-recovery-and-the-restore-drill"></span>

Dizayn `docs/architecture/23-ops.md` sənədinin 8-ci bölməsindədir. Bu təlimat Docker Compose məhsulu üçündür. Onu yazmayan şəxsin də addım-addım yerinə yetirməsi nəzərdə tutulur; addım aydın deyilsə, bu sənəddə qüsur var.

## Nə və necə qorunur <!--quire:what-is-protected-and-how-->

| Aktiv | Necə | Harada |
| --- | --- | --- |
| Verilənlər bazası | İlk başladıqdan etibarən davamlı, ən çox hər 60 saniyədən bir WAL arxivlənir | `pgwal` həcmi |
| Verilənlər bazası | `pg_basebackup` ilə əsas ehtiyat nüsxələr, standart olaraq gündəlik (`backup-scheduler`) | `pgbackup` həcmi |
| Verilənlər bazası | Əsas ehtiyat nüsxə və WAL-ın şifrəli surətləri, hər beş dəqiqədən bir (`backup-offsite`) | Göstərdiyiniz ayrı saxlama yeri |
| Fayllar | `files` həcmi. Hostun ehtiyat nüsxə aləti ilə köçürün və ya versiyalı obyekt saxlama işlədin | `files` həcmi |
| Secret-lər | `docker/.env`, xüsusən `QUIRE_MASTER_KEY` (və hələ istifadə olunan istənilən `QUIRE_MASTER_KEY_RETIRED`), `QUIRE_BACKUP_ENCRYPTION_KEY` və `docker/secrets/audit-signing-key.pem` | Surətini bu hostdan kənarda saxlayın |
| Axtarış indeksləri, keşlər, renderlənmiş variantlar | Ehtiyatı çıxarılmır; yenidən qurulur | |

Hədəflər: nasazlıqdan ən çox 60 saniyə əvvələ qədər bərpa nöqtəsi və 500 GB verilənlər bazası üçün 60 dəqiqə ərzində bərpa.

İki səhvə tez-tez yol verilir. Faylları olmadan bərpa edilmiş verilənlər bazası səhifələri pozur. `QUIRE_MASTER_KEY` olmadan bərpa edilmiş baza saxladığı SSO, vebhuk və inteqrasiya etimadnamələrini aça bilmir; heç nə həll olunmamış qalmadan master açar dəyişdirilənədək ([key-rotation.md](/az/ops/key-rotation/)) buraya köhnə açarlar da daxildir. Hər ikisi ehtiyat nüsxəyə daxildir.

## Ehtiyat nüsxələrin yaradılması <!--quire:taking-backups-->

Bütün klasterin əsas ehtiyat nüsxəsi:

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

Ən yeni `QUIRE_BACKUP_KEEP` əsas ehtiyat nüsxəsini (standart 5) saxlayır və ən köhnə nüsxəyə lazım olmayan WAL-ı təmizləyir ki, arxiv sonsuz böyüməsin. Hostda cron və ya systemd timer ilə gündəlik cədvələ salın:

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

Və ya yığının özündə planlaşdırın: `backup` profili əsas ehtiyat nüsxəni hər `backup-scheduler` `QUIRE_BACKUP_INTERVAL_HOURS` müddətində (standart 24 saat) alır, həmçinin növbəti bölmədə təsvir olunan `backup-offsite` xidmətini işlədir.

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

## Hostdan kənar şifrəli surətlər <!--quire:encrypted-off-host-copies-->

Hər iki həcm verilənlər bazası ilə eyni hostdadır; sıradan çıxan maşındakı ehtiyat nüsxə ehtiyat nüsxə sayılmır. `backup-offsite` hər əsas nüsxəni və arxivlənmiş WAL seqmentini saxlama portu vasitəsilə şifrəli şəkildə ayrı saxlama yerinə köçürür, saxlanma qaydasına uyğun orada saxlayır:

- **Şifrələmə.** `QUIRE_BACKUP_ENCRYPTION_KEY` (və ya `QUIRE_BACKUP_ENCRYPTION_KEY_FILE` ilə adı verilən fayl) vasitəsilə AES-256-GCM: `openssl rand -hex 32` ilə yaradılmış 32 bayt. Hər faylın öz nonce-u və autentifikasiya teqi var; açar olmadan surət oxunmur, dəyişiklik edilərsə aşkarlanır. Açarı `QUIRE_MASTER_KEY` ilə bu hostdan və ehtiyat saxlama yerindən ayrı saxlayın. Açar yoxdursa bərpa etmək mümkün deyil.
- **Yer.** `QUIRE_BACKUP_STORAGE_DRIVER` `s3`, `azure` və ya `local` olur (`QUIRE_BACKUP_STORAGE_ROOT` ünvanında qoşulmuş uzaq disk). Parametrlər `QUIRE_BACKUP_` prefiksi olan fayl saxlama parametrləridir: `QUIRE_BACKUP_S3_ENDPOINT`, `QUIRE_BACKUP_S3_BUCKET`, `QUIRE_BACKUP_S3_ACCESS_KEY_ID` və s. Fayllardan fərqli bucket və, mümkün olsa, başqa hesab istifadə edin; provayder icazə verirsə, etimadnamələri yazma səlahiyyətli, silmə səlahiyyətsiz edin.
- **Saxlanma müddəti.** Ən yeni `QUIRE_BACKUP_OFFSITE_KEEP` əsas ehtiyat nüsxələri (standart `QUIRE_BACKUP_KEEP`, əks halda 7) və ən köhnəsinə lazım olan WAL saxlanır; daha köhnə dəstlər və seqmentlər saxlama yerindən silinir.
- **Vaxt.** Hər `QUIRE_BACKUP_SHIP_INTERVAL_SECONDS` müddətində (standart 300 saniyə). Göndərmə idempotentdir: saxlananlar ötürülür, əsas ehtiyat nüsxə isə yalnız manifest ən sonda yazıldıqdan sonra saxlanmış sayılır.

Eyni əmrləri əl ilə işlətmək olar:

```sh
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
```

Yeni hostda bərpa etmək üçün əvvəlcə dəsti geri gətirin, sonra aşağıdakı addımlarda `pgbackup` həcmi əvəzinə gətirilmiş qovluğu, `wal-archive` əvəzinə isə `pgwal` yerinə gətirilmiş qovluğu istifadə edin:

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

## Vaxt nöqtəsinə bərpa <!--quire:restoring-to-a-point-in-time-->

Məlumat itkisi (yanlış idxal, silinmiş kurs, geri qaytarılmalı yığışdırma miqrasiyası) olduqda bunu işlədin. Canlı verilənlər bazasını əvəz etdiyi üçün əvvəlcə aşağıdakı sınaqla məşq edin.

1. **Hədəf vaxtı** zərərdən dərhal əvvəl UTC ilə seçin: `2026-09-24 09:30:00+00`. Audit jurnalı (`/admin/audit`) adətən həmin anı göstərir.
2. **Yazma aparan bütün xidmətləri dayandırın**:
   `docker compose -f docker/compose.yaml stop web content worker scheduler collab`
3. **Bərpanın yoxlanmasına qədər zədələnmiş klasteri saxlayın**:
   ```sh
   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. **Hədəfdən əvvəlki ən yeni əsas ehtiyat nüsxəni** məlumat həcminə açıb, hədəfli bərpa tələb edin:
   ```sh
   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. **Bərpa**: normal fayla toxunmamaq üçün Compose override ilə bərpa parametrlərini bir dəfə Postgres-ə verərək başladın:
   ```yaml
   # 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 tam əmri əvəz etdiyi üçün bərpa üçün lazım olan iki parametri təkrarlayır: `max_connections` əsas serverdən aşağı olmamalıdır (əks halda “insufficient parameter settings” ilə bərpa dayanır) və qoşulmuş `pg_hba.conf` faylı.
   ```sh
   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. **İnsanları buraxmazdan əvvəl yoxlayın**: audit zənciri (`docker compose -f docker/compose.yaml run --rm worker bun tooling/audit-verify/run.ts`) və itmiş məlumatların qayıtdığını təsdiqləyin.
7. **Normal rejimə qayıdın**: `docker compose -f docker/compose.yaml up -d`. Bu, Postgres-i arxivləmə aktiv halda yenidən başladır və yeni WAL zaman xətti başlayır. Dərhal yeni əsas ehtiyat nüsxə yaradın.

`quire` layihə adı hər həcmin əvvəlinə əlavə olunur; dəqiq adları `docker volume ls` göstərir.

## Planlaşdırılmış yoxlama sınağı <!--quire:the-scheduled-verification-drill-->

`backup-offsite` həmçinin hər `QUIRE_BACKUP_DRILL_INTERVAL_HOURS` (standart 168, həftəlik) müddətində və uğursuz sınaqdan sonra növbəti icrada bir daha sınaq keçirir. Hostdan kənardakı ən yeni əsas ehtiyat nüsxəni və ondan sonrakı bütün WAL seqmentlərini gətirir, hər birinin şifrəsini açır (bu, açarın hələ də açdığını və dəyişiklik olmadığını sübut edir), faylları manifestlə müqayisə edir, arxivin Postgres məlumat qovluğu olduğunu və nüsxədən etibarən WAL-da boşluq olmadığını yoxlayır. Hesabat saxlama yerinə `reports/drill-<time>.json` kimi və xidmət jurnalına yazılır; uğursuz sınaq faylı və ya ilk çatışmayan seqmenti bildirir.

## Bərpa sınağı <!--quire:the-restore-drill-->

Heç vaxt bərpa edilməmiş ehtiyat nüsxə ehtiyat nüsxə sayılmır. Sınaq ən yeni tam əsas nüsxəni və WAL arxivini canlı verilənlər bazası ilə heç nə paylaşmayan sınaq Postgres-ə bərpa edir və nəticəni sübut edir:

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

Hədəf dəqiq həmin formatda UTC olmalıdır. Ondan əvvəl əsas ehtiyat nüsxə və ondan sonrakı arxivlənmiş WAL lazımdır: yeni quraşdırmada əsas nüsxəni yaradın, sonra hədəfi nüsxədən sonraya seçməzdən əvvəl növbəti arxiv seqmentini (yazma varsa ən çox bir dəqiqə) gözləyin. Sınaq üçün hostda Docker və bash-dan başqa heç nə lazım deyil.

Bu addımların istənilənində xəta sınağı uğursuz edir:

1. **Bərpa oluna bilmə**: sınaq klasteri hədəf vaxta qədər yazıları oynadıb açılır.
2. **Tamlıq**: canlı verilənlər bazası ilə hər cədvəldə sətir sayının müqayisəsi (`tooling/restore-drill`). Hədəfdən sonra canlı baza dəyişib, buna görə cədvəl hər iki istiqamətdə 500 sətirdən və ölçüsünün onda birindən böyük olanı qədər fərqlənə bilər (yazılar bərpanı geri salır, silinmələrdə isə bərpa daha çox məlumat saxlayır); hədəfdən sonra yaradılmış bölməli cədvəl itmiş sayılmır. Daha yüklü quraşdırmada `QUIRE_DRILL_MAX_BEHIND` və `QUIRE_DRILL_MAX_DRIFT_RATIO` ilə icazəni artırın. Çatışmayan və ya boşalmış cədvəl uğursuz sayılır.
3. **Bütövlük**: bərpa edilmiş surətdə audit heş zənciri yoxlamadan keçir.
4. **İstifadə oluna bilmə**: tətbiq rolu sətir səviyyəli təhlükəsizlik vasitəsilə oxuyur.
5. **Müddət**: başlama ilə uğurlu nəticə arasında `QUIRE_DRILL_RTO_SECONDS` limitinə (standart 3600) uyğun vaxt.

Sınaq canlı verilənlər bazasına və onun həcmlərinə yazmır: ehtiyat və WAL həcmləri yalnız oxuma üçün qoşulur, sınaq klasteri isə uğurdan və ya xətadan sonra silinir.

Uğurlu və ya uğursuz JSON hesabat yazmaq üçün `QUIRE_DRILL_REPORT` parametrinə yol verin və onu Docker hostunda cədvələ salın:

```cron
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
```

Hər ay və hər yeniləmədən əvvəl işlədin. Uğursuz sınaq yeniləməni bloklayır. Rübdə bir dəfə bu təlimatı yazmayan şəxsə yalnız bu sənəddən istifadə edərək ehtiyat hostda həqiqi vaxt nöqtəsinə bərpa etdirdin.

## Fayllar <!--quire:files-->

Lokal fayllar `files` həcmində saxlanır. Verilənlər bazası ilə eyni vaxtda ehtiyatını çıxarın və ikisini birlikdə bərpa edin:

```sh
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 .
```

Obyekt saxlama istifadə edirsinizsə, bucket versiyalaşdırmasını aktiv edin və cari olmayan versiyaları 35 gün saxlayın; faylların vaxt nöqtəsinə bərpasını bundan sonra bucket özü təmin edir.

Source: https://docs.quirelms.com/az/ops/backup-restore/index.mdx
