Skip to content

備份與災備

這是什麼 Argus 的所有狀態(user、project、plan、issue、rollout、task_run、audit_log、setting…)都在 metastore Postgres 裡。備份 metastore = 備份整個 Argus

Argus binary 本身無狀態(除 --data 內嵌 PG 模式外),server 機器掛掉重建即可。

一句話策略

項目建議
備份對象metastore Postgres(含 audit log 表)
方式PG pg_dump(邏輯)+ 連續 WAL(時間點還原)
保留期日備份 30 天 / 月備份 12 個月(依法遵調整)
演練頻率每季一次完整還原演練

備份方式

方式 A:托管服務(推薦)

如果 metastore 跑在 AWS RDS / GCP Cloud SQL / Azure DB / 阿里雲 RDS:

  • 開啟自動備份(每日全備 + 連續 WAL)
  • Retention ≥ 30 天
  • 開啟 cross-region snapshot copy(災備)
  • 開啟 deletion protection

托管服務的備份比自架穩定得多。能用就用。

方式 B:自架 pg_dump

bash
# /etc/cron.daily/argus-backup
#!/bin/bash
set -euo pipefail

BACKUP_DIR=/srv/backup/argus
mkdir -p "$BACKUP_DIR"

DATE=$(date -u +%Y%m%dT%H%M%SZ)
OUT="$BACKUP_DIR/argusdev-$DATE.dump"

PGPASSWORD="$ARGUS_PG_PASSWORD" pg_dump \
  --host=metastore.internal \
  --username=argusdev \
  --dbname=argusdev \
  --format=custom \
  --compress=9 \
  --no-owner \
  --no-privileges \
  --file="$OUT"

# Verify
PGPASSWORD="$ARGUS_PG_PASSWORD" pg_restore --list "$OUT" > "$OUT.toc"

# Encrypt(建議)
gpg --batch --yes --encrypt --recipient ops@corp \
  -o "$OUT.gpg" "$OUT"
rm "$OUT"

# Upload off-site
aws s3 cp "$OUT.gpg" "s3://corp-argus-backup/daily/" --sse=AES256

# Retention(本地)
find "$BACKUP_DIR" -name "*.gpg" -mtime +7 -delete

關鍵:

  • 加密後再上傳異地(含 audit log = 含敏感資訊)
  • 異地副本(不同 region / 不同 cloud)
  • Retention 本地短、異地長
  • 備份完跑 pg_restore --list 驗證檔案完整

方式 C:WAL 連續備份(時間點還原)

對於 RPO 要求嚴格(< 1 小時)的環境:

bash
# PG 設定(postgresql.conf)
wal_level = replica
archive_mode = on
archive_command = 'aws s3 cp %p s3://corp-argus-wal/%f --sse=AES256'
archive_timeout = 600         # 強制每 10 分鐘 archive 一次

加上每日基底備份,即可還原到任意時間點(PITR)。

還原

場景 1:metastore 整個掛掉

預估時間:30 分鐘 – 2 小時(依資料量)。

  1. 凍結:把 Argus server 關掉,避免新寫入產生於不完整 metastore:

    bash
    docker compose stop argus           # 或 kubectl scale deploy/argus --replicas=0
  2. 建新 PG(同版本,相同字元集):

    bash
    psql -U postgres <<SQL
    CREATE USER argusdev WITH PASSWORD '<same as before or rotated>';
    CREATE DATABASE argusdev OWNER argusdev ENCODING 'UTF8' LC_COLLATE 'C' LC_CTYPE 'C' TEMPLATE template0;
    SQL
  3. 還原

    bash
    # 從加密備份還原
    gpg --decrypt argusdev-20260524T021500Z.dump.gpg > restore.dump
    PGPASSWORD="$ARGUS_PG_PASSWORD" pg_restore \
      --host=metastore.internal \
      --username=argusdev \
      --dbname=argusdev \
      --no-owner \
      --no-privileges \
      restore.dump
    rm restore.dump
  4. 驗證

    sql
    SELECT count(*) FROM principal;
    SELECT count(*) FROM project;
    SELECT count(*) FROM plan;
    SELECT count(*) FROM issue;
    SELECT count(*) FROM task_run;
    SELECT max(ts) FROM audit_log;     -- 確認備份新鮮度
  5. 重啟 Argus,跑 smoke test(驗證)。

場景 2:誤刪 / 誤改個別資料

⚠️ 通常從備份還原整個 metastore(成本太大)。改採以下方法:

  1. 把備份還原到獨立的暫存 PG instance
  2. 從暫存 instance 抽出需要的 rows
  3. 用 SQL 寫進當前 metastore(手動審核每筆

任何 metastore 手動 DML 都要兩人對審 + 寫進事件單。

場景 3:時間點還原(PITR)

需 WAL 連續備份。流程依託管服務或自架方式不同:

  • RDS:在 console 選「Restore to point in time」
  • Cloud SQL:「Clone instance at point in time」
  • 自架:用 recovery_target_time 設定還原

詳細指令依 PG 版本:PostgreSQL Documentation — Continuous Archiving and PITR

災備拓樸

RPORTO推薦
< 1h< 4h同 region 多 AZ 主備 + 異地每日備份
< 15min< 1h跨 region streaming replication + WAL 異地
< 5min< 30min跨 region 主從同步 + 自動 failover

不要為了過度低的 RPO/RTO 把架構搞太複雜。Argus 不是線上交易系統,4 小時 RTO 對絕大多數公司夠用。

演練 SOP

每季一次

  • [ ] 從昨日備份還原到隔離環境
  • [ ] 紀錄還原耗時(找瓶頸)
  • [ ] 用備份指紋(SELECT count(*) FROM audit_log WHERE ts > ...)驗證 RPO
  • [ ] 跑 smoke test(煙霧測試 SOP
  • [ ] 對比 dump 與 source 的 row count
  • [ ] 把結果寫進演練記錄

如果某季沒演練 → 視同備份未驗證

不要做的事

反模式為什麼
只在本地放備份一次火災 / 區域故障全沒
備份不加密metastore 含 audit log + IdP 設定 + IAM policy
從未演練還原你不知道備份其實壞掉
把備份保留期設太短法遵稽核期間可能要回溯數月前狀態
還原時直接覆寫生產 metastore一旦發現備份是壞的就回不去了 — 永遠先還原到隔離環境

相關

Argus — 公司內部資料庫變更審計平台