---
title: "Backup، point-in-time recovery އަދި restore drill"
description: "ޤުއަރޭގެ backup ނަގާ، އެއީ ކުރީގެ ވަގުތަކަށް restore ކޮށް، restore drill އިން ތައިދީކުރާށެވެ."
image: "https://docs.quirelms.com/og.png"
---

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

# Backup، point-in-time recovery އަދި restore drill

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

މިޒައިން `docs/architecture/23-ops.md` ގެ 8 ވަނަ ސެކްޝަނެވެ. މިއީ Docker Compose ޕްރޮޑަކްޓްގެ runbook އެވެ. މި ލިޔުން ލިޔިފައި ނުހުރި މީހަކު އެއް ދަތުރު ކުރެވޭން ލިޔެފައިވެއެވެ؛ އެއް ފިޔަވަޅެއް ދަތިވެގެން ނަމަ މި ޑޮކިއުމަންޓަކީ އެރަރެކެވެ.

## ކޮން ތަކެއްޗެއް ރައްކާވެ، ކިހިނެއް <!--quire:what-is-protected-and-how-->

| Asset | ކިހިނެއް | ކޮންތާކު |
| --- | --- | --- |
| Database | ފުރަތަމަ boot އިން ފެށިގެން WAL އެވަގުތުން archive، އެންމެ 60 ސިކުންތުން ދިގު ނުވާ | `pgwal` volume |
| Database | `pg_basebackup` އިން base backup؛ ޑިފޯލްޓުން ދުވަހަކު (`backup-scheduler`) | `pgbackup` volume |
| Database | base backup އަދި WAL ގެ encrypted copy ކޮންމެ ފަސް މިނިޓަކުން (`backup-offsite`) | ތިބާގެ ވަކި storage |
| Files | `files` volume. ތިބާގެ host backup tool އިން copy ކުރާ، ނުވަތަ version ހުރި object storage ބޭނުންކުރާ | `files` volume |
| Secrets | `docker/.env`، ވަކިން `QUIRE_MASTER_KEY` (އަދި ދެމިތިބޭ `QUIRE_MASTER_KEY_RETIRED`)، `QUIRE_BACKUP_ENCRYPTION_KEY`، އަދި `docker/secrets/audit-signing-key.pem` | މި host ނޫން ތަނަކު ކޮޕީ ބެހެއްޓާށެވެ |
| Search index، cache، rendition | Backup ނުކުރެވޭ؛ އަލުން ހަދެވޭ | |

މަގްޞަދަކީ ފޭލިއަރއިން 60 ސިކުންތުގެ ތެރޭ recovery point އެއް، 500 GB database އެއް 60 މިނިޓުގެ ތެރޭ restore ކުރުން.

ދެ އޯޅުން ޢާންމުވެއެވެ. **ފައިލްތައް ނެތި** ރިސްޓޯރ ކުރި database އެއް ބްރޯކަންވެފައިވާ ޕޭޖް ރެންޑަރކުރެއެވެ. **`QUIRE_MASTER_KEY` ނެތި** restore ކުރި database އިން SSO، webhook އަދި integration credential ތައް ޑިކްރިޕްޓްކުރެވޭނެއް ނޫނެވެ؛ ނުނިމިހުރި master key rotation ނިމޭންދެން ([key-rotation.md](/dv/ops/key-rotation/)) retired key ތައްވެސް އޭގައި ހިމެނެއެވެ. ދެތަކެތިވެސް backup ގެ ބައެކެވެ.

## Backup ނަގުން <!--quire:taking-backups-->

މުޅި cluster ގެ base backup:

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

އެއީ އާއެންމެ އާ `QUIRE_BACKUP_KEEP` base backup (ޑިފޯލްޓުން 5) ބެހެއްޓި، އާއެން ދިގު backup އަށް ނުބޭނުންވާ WAL prune ކުރެއެވެ؛ archive އަކީ ހިމެނޭ ހައްދެއް ނެތި ބޮޑުވެ ނުދާނެއެވެ. Host ގައި cron ނުވަތަ systemd timer އަކުން ކޮންމެދުވަހަކު schedule ކުރާށެވެ:

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

ނުވަތަ stack އަކު އެއީ schedule ކުރަންދޭށެވެ: `backup` profile އިން `backup-scheduler` ހިންގައި ކޮންމެ `QUIRE_BACKUP_INTERVAL_HOURS` (ޑިފޯލްޓުން 24) ގަޑިއިރަކު base backup ނަގައި، ދެން `backup-offsite` ހިންގައެވެ.

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

## Host ނޫން ތަނަކަށް encrypted copy <!--quire:encrypted-off-host-copies-->

ދެ volume އެއް database ހުރި host އެއްގައިވެއެވެ؛ ފޭލްވި machine ގައިވާ backup އެއް backup ނޫނެވެ. `backup-offsite` އިން ކޮންމެ base backup އާއި archive ކުރެވިފައިވާ WAL segment އެއް storage port މެދުވެރިކޮށް ވަކި storage އަށް copy ކޮށް، encrypt ކޮށް, retention ދަށުން ބެހެއްޓެވެ:

- **އެންކްރިޕްޝަން.** `QUIRE_BACKUP_ENCRYPTION_KEY` (ނުވަތަ `QUIRE_BACKUP_ENCRYPTION_KEY_FILE` އިން ނަންދޭ file): 32 bytes، `openssl rand -hex 32` އިން. ކޮންމެ file އަކަށް އަމިއްލަ nonce އަދި authentication tag ހުރެއެވެ؛ key ނެތި copy ކިޔެވޭނެއް ނޫނެވެ، ބަދަލުކުރިޔާ ދަންނާނެއެވެ. Key އެއް `QUIRE_MASTER_KEY` އާއެކު މި host އާއި backup storage އިން ވަކި ތަނަކު ބެހެއްޓާށެވެ. Key ނެތްނަމަ restore އެއް ނެތެވެ.
- **ކޮންތާކު.** `QUIRE_BACKUP_STORAGE_DRIVER` އަކީ `s3`، `azure` ނުވަތަ `local` (ލައިވް remote disk `QUIRE_BACKUP_STORAGE_ROOT` ގައި mount ކުރި). Settings އަކީ file storage ގެ settings ކަމަކު `QUIRE_BACKUP_` prefix އާއެކު: `QUIRE_BACKUP_S3_ENDPOINT`، `QUIRE_BACKUP_S3_BUCKET`، `QUIRE_BACKUP_S3_ACCESS_KEY_ID` އަދި އެހެންވެސް. ފައިލްތަކާ ވަކި bucket އެއް، އިތުރަށް ވަކި account އެއް ބޭނުންކުރާށެވެ؛ ޕްރޮވައިޑަރުން ދިނިމައިގައި ލިޔެން ހުއްދަ އެކަމަކު ފޮހުމަށް ނުލިބޭ credential ދޭށެވެ.
- **Retention.** އާއެން އާ `QUIRE_BACKUP_OFFSITE_KEEP` base backup (ޑިފޯލްޓުން `QUIRE_BACKUP_KEEP`، އެއް ނެތްނަމަ 7) އަދި އާއެން ދިގު އެއަށް ޖެހޭ WAL ބެހެއްޓެވެ؛ ކުރީގެ set އަދި segment ތައް storage އިން ފޮހެވެއެވެ.
- **އިރު.** ކޮންމެ `QUIRE_BACKUP_SHIP_INTERVAL_SECONDS` ގަޑިއިރަކު (ޑިފޯލްޓުން 300). Shipping idempotent އެވެ: ކުރިން ސްޓޯރ ކުރި ތަކެތި ދޫކޮށް، manifest ލިޔެފަހު ފަހުން ކޮންމެ base backup އެއްވެސް ސްޓޯރ ކުރެވިއްޖެ ކަމަށް ބެލެއެވެ.

އެއް command ތައް ހަތިރުން ހިންގެއެވެ:

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

އާ host އެއްގައި restore ކުރަން ފުރަތަމަ set ފެތުރާ، ދެން ތިރީގެ ފިޔަވަޅުތައް ފެތުރި directory އަކާއެކު ކުރާށެވެ (`pgbackup` volume ގެ ތަނުގައި) އަދި ފެތުރި `wal-archive` އެއް `pgwal` ގެ ތަނުގައި:

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

## އެއް ވަގުތުގައި ހުރި ތަނަށް restore <!--quire:restoring-to-a-point-in-time-->

ޑޭޓާ ގެއްލިއްޔާ މިއީ ބޭނުންކުރާށެވެ: ނުބައި import، ފޮހިލި course، ނުވަތަ އަނބުރާލާންޖެހޭ contract migration. މިއީ live database ބަދަލުކުރެއެވެ؛ ކުރިން ތިރީގެ drill އިން ދަސްކޮށްލާށެވެ.

1. **Target time ހޮވާށެވެ**، UTC ގައި، ގެއްލުން ކުރި ކަމުގެ ކުރިން: `2026-09-24 09:30:00+00`. Audit log (`/admin/audit`) ގައި އެ ވަގުތު ގިނަ ފަހަރު ފެންނާނެއެވެ.
2. **ލިޔާ ހުރި ހުރިހާ ކަންކަން ހުއްޓާށެވެ**: `docker compose -f docker/compose.yaml stop web content worker scheduler collab`.
3. **ގެއްލި ހުރި cluster ރައްކާކުރާށެވެ** restore ތައިދީ ވާންދެން:
   ```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. **Target އިން ކުރިންގެ އާއެން އާ base backup ޑޭޓާ volume އަށް unpack** ކޮށް targeted recovery އެދޭށެވެ:
   ```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. **Recover**: އާ Postgres އެއް recovery settings އާއެކު އެއްފަހަރު start ކުރާށެވެ، normal file ނުބަދަލުކޮށް Compose override އިން:
   ```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 އިން މުޅި command ބަދަލުކޮށް، recovery އަށް ޖެހޭ ދެ setting އަލުންވެސް ހިމެނުން ލާޒިމެވެ: `max_connections` primary ގެ އެއްވަރަށްވުރެ ކުޑަނުވާނެ (ނޫނީ recovery "insufficient parameter settings" އިން abort ވެއެވެ)، އަދި mounted `pg_hba.conf`.
   ```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. **މީހުން ނުވަދެވޭ ކުރިން ޗެކްކުރާށެވެ**: audit chain (`docker compose -f docker/compose.yaml run --rm worker bun tooling/audit-verify/run.ts`)، އަދި ގެއްލި ޑޭޓާ އަނބުރިފައިވާތޯ.
7. **އާންމު ގޮތަށް އަނބުރާށެވެ**: `docker compose -f docker/compose.yaml up -d`. މިއީ archiving އޮންކޮށް Postgres އަނބުރައި start ކޮށް، އާ WAL timeline އެއް ފަށައެވެ. އެވަގުތުން އާ base backup އެއް ނަގާށެވެ.

Project name `quire` އިން volume ތަކަށް prefix ކުރެއެވެ؛ ހަމަ ނަން ބަލާން `docker volume ls` ބަލާށެވެ.

## Schedule ކުރި verification drill <!--quire:the-scheduled-verification-drill-->

`backup-offsite` އިން `QUIRE_BACKUP_DRILL_INTERVAL_HOURS` ގަޑިއިރަކު (ޑިފޯލްޓުން 168، ހަފްތާއަކު) drill ހިންގައެވެ؛ ފޭލްވިއްޔާ ދެންކުރާއިރުވެސް. Off-host storage އިން އާއެންއާ base backup އަދި އެއަށް ފަހު WAL segment ހުރިހާ ނަގައި decrypt ކުރެއެވެ (key އިން އެއް ހުޅުވޭތޯ އަދި ބަދަލެއް ނެތޯ ތައިދީވެއެވެ)، ކޮންމެ file އެއް manifest އާއި compare ކުރެއެވެ، archive އަކީ Postgres data directory އެއްތޯ ޗެކްކުރެއެވެ، backup އިން ފެށިގެން WAL ގައި gap ނެތްކަން ޗެކްކުރެއެވެ. ރިޕޯޓް storage އަށް `reports/drill-<time>.json` އަދި service log އަށް ލިޔެ، drill ފޭލްވިޔާ file ނަން ނުވަތަ ފުރަތަމަ missing segment ބުނެއެވެ.

## Restore drill <!--quire:the-restore-drill-->

ކުރިން restore ނުކުރި backup އެއް backup ނޫނެވެ. Drill އިން target ގެ ކުރިން ނަގާ ފުރިހަމަ base backup އާއި WAL archive އެއް ލިވް database އާއެކު އެއްވެސް ޝެއާރ ނުކުރާ scratch Postgres އަކަށް restore ކޮށް ނަތީޖާ ތައިދީކުރެއެވެ:

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

Target އަކީ UTC، މި format އެއްގައި ހަމަ ވާންޖެހެއެވެ. އެއަށް ކުރިންގެ base backup އެއް އަދި އެއަށް ފަހު archived WAL ލާޒިމެވެ؛ އާ install އެއްގައި base backup ނަގައި ދެންކުރާ archived segment އައިމަ (write ހުރިއްޔާ އެންމެ މިނިޓެއް) backup ގެ ފަހުން target އެއް ހޮވާށެވެ. Drill އަށް host ގައި Docker އަދި bash އެކަނި ލާޒިމެވެ.

ކޮންމެ step އެއްވެސް drill ފޭލްކުރައެވެ:

1. **Recovery ކުރެވޭ**: scratch cluster target އަށް replay ކޮށް ހުޅުވެއެވެ.
2. **ފުރިހަމަ**: live database އާއި ގުޅުވި ކޮންމެ table ގެ row count (`tooling/restore-drill`). Live database target ފަހުން ކުރަމުން ދާތީ، table އެއްގައި 500 row ނުވަތަ eyaage 10 އިން އެންމެ ބޮޑު މިންވަރުގެ ތަފާތެއް ދެދިމާއަށް ވެދާނެއެވެ (write އިން އެއް ފަހުވެ، deletion އިން restore ގައި އިތުރު އޮތްގޮތަށް)؛ target ފަހުން ހެދި partition އެއް lost table ނޫނެވެ. ބޮޑު install އަށް `QUIRE_DRILL_MAX_BEHIND` އަދި `QUIRE_DRILL_MAX_DRIFT_RATIO` އިން ލިމިޓް ފުޅާ ކުރާށެވެ. ނެތް ނުވަތަ ހުސްވި table އެއް ފޭލްވާނެއެވެ.
3. **ސައްހަކަން**: audit hash chain restored copy ގައި verify ވެއެވެ.
4. **ބޭނުންކުރެވޭ**: application role row-level security މެދުވެރިކޮށް ކިޔައެވެ.
5. **ވަގުތު**: start އިން green އަށް، `QUIRE_DRILL_RTO_SECONDS` (ޑިފޯލްޓުން 3600) ގެ ތެރޭގައި.

Live database ނުވަތަ eyaage volume އަށް ކޮންމެއް ލިޔެން ނޫނެވެ: backup އަދި WAL volume ތައް read-only އަށް mount ކުރެވި، scratch cluster އެއްވެސް ނިމުމުން ފޮހެވެއެވެ، ފާސްވި ނުވަތަ ފޭލްވިޔަސް.

ފާސް ނުވަތަ ފޭލް ވި JSON report އެއް ލިޔުމަށް `QUIRE_DRILL_REPORT` އަށް path އެއް ދީ، Docker host އިން schedule ކުރާށެވެ:

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

މަހަކު އެއް ފަހަރު އަދި upgrade ކޮންމެއްގެ ކުރިން ހިންގާށެވެ. Drill އެއް ފޭލްވިޔާ upgrade ބްލޮކްވެއެވެ. ކުރުން މީހަކު ރިލީޒެއްގައި ދަސް ނުކުރި point-in-time restore އެއް spare host އަކަށް، މި ޑޮކިއުމަންޓް އެކަނި ބޭނުންކޮށް ކުރާށެވެ.

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

Local file ތައް `files` volume ގައިވެއެވެ. Database އާއެކު، އެއްވަގުތު backup ނަގާ، ދެތިން އެކު restore ކުރާށެވެ:

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

Object storage ބޭނުންކުރާނަމަ bucket versioning އޮންކޮށް noncurrent version ތައް 35 ދުވަސް ބެހެއްޓާށެވެ؛ އެއިރު file ތަކަށް point-in-time recovery bucket އިންނެވެ.

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