Appearance
bbdataarchive 保留政策 SOP
何時用這份文件 你是 DBA / SRE,要設計或執行
bbdataarchivesidecar DB 的清理流程。Argus 的 PriorBackup 機制把每次 DML 影響的 row 寫進這個 sidecar,沒有內建 retention,DBA 沒做沒人會做。不熟 PriorBackup 是什麼?先讀 變更回滾與資料復原。
為什麼要管它
| 風險 | 後果 |
|---|---|
| 不清 → 無限長大 | 占爆 instance disk;嚴重時影響 prod 業務 DB |
| 不清 → 累積敏感資料 | 業務表內 PII(email / 身分證號 ...)也被原樣複製進 backup table,沒有 masking |
| 不清 → 違反 GDPR / 個資法的「資料保留時限」 | 被刪除權請求 / 法務查詢時,bbdataarchive 內的 row 被當成「另一份保留紀錄」處理 |
| 過度激進清 → 失去倒帶能力 | 太短的 retention(例如 24h)→ 真的需要倒帶時 backup 已不在 |
bbdataarchive 在不同 engine 長什麼樣
| Engine | 結構 | 在哪 |
|---|---|---|
| PostgreSQL | Schema 名為 bbdataarchive | 在 source database 內,跟其他 schema 並列 |
| MySQL / TiDB / MSSQL | Database 名為 bbdataarchive | 同 instance 內的另一個 database |
| Oracle | Database 名為 BBDATAARCHIVE(大寫) | 同 instance 內的另一個 database |
| Snowflake / Cassandra / SQLite / MongoDB / Spanner | 不支援 PriorBackup | 不存在 |
每次跑了帶 enablePriorBackup 的 Plan:
bbdataarchive/ ← schema (PG) or database
├── _a1b2c3_users_20260615120000 ← UPDATE/DELETE on users
├── _d4e5f6_orders_20260615130000 ← UPDATE on orders
├── _g7h8i9_users_20260615140000 ← 又一次 UPDATE on users (新 timestamp + 新 random)
└── ...命名規則:_<random_6_chars>_<source_table>_<unix_ts_or_yyyymmddhhmmss> — 同一張 source 表會累積很多份。
推薦保留政策
| 環境 | 預設 retention | 為什麼 |
|---|---|---|
| Prod | 90 天 | 法務 / 稽核常要求至少季度級回查;90 天涵蓋多數倒帶情境 |
| Staging | 30 天 | 純測試環境,不需太長 |
| Dev / sandbox | 7 天 | 開發者試錯多,但每筆都不重要 |
建議搭配跟法務 / 合規確認 — 不同產業 / 不同地區 retention 法定下限不同。
清理 SOP — 每月跑一次
1. 跑前 30 秒儀式
| 檢查 | 命令 |
|---|---|
| 確認沒有 PRIOR_BACKUP_START 在跑 | 查 task_run_log 最近 15 分鐘有沒有 type='PRIOR_BACKUP_START' 但沒對應 PRIOR_BACKUP_END 的 |
| 確認目前沒有 active rollback 計畫 | 跟 PM / DBA 對齊本月 retention 視窗,避免清掉還在用的 backup |
| 確認 audit_log 已歸檔 | 清 backup 前確認 bb.databases.adminExecute 紀錄仍可查(查詢 audit log) |
2. 列出超過 retention 的 backup tables
PostgreSQL
sql
-- 連到 source database,schema = bbdataarchive
SELECT
schemaname,
tablename,
pg_size_pretty(pg_total_relation_size(format('%I.%I', schemaname, tablename))) AS size
FROM pg_tables
WHERE schemaname = 'bbdataarchive'
-- 命名規則:_<rnd>_<src>_<ts>,按建立時間判斷
AND tablename ~ '^_[a-z0-9]+_.+_[0-9]+$'
ORDER BY tablename;從 tablename 末段 timestamp 算出年齡,超過 retention 的列出來。
MySQL / TiDB / MSSQL
sql
USE bbdataarchive;
SHOW TABLES;
-- 或
SELECT table_name, create_time, data_length + index_length AS size_bytes
FROM information_schema.tables
WHERE table_schema = 'bbdataarchive'
ORDER BY create_time;create_time 直接算年齡。
3. 刪除超過 retention 的 backup tables
不要刪
bbdataarchiveschema/database 本身 — Argus sync 不會自動重建,下次 PriorBackup 會失敗。
PostgreSQL
sql
-- 每張表一條 DROP,方便 audit log 追溯
DROP TABLE bbdataarchive._a1b2c3_users_20260315120000;
DROP TABLE bbdataarchive._d4e5f6_orders_20260315130000;
-- ... 重複MySQL / TiDB / MSSQL / Oracle
sql
USE bbdataarchive;
DROP TABLE _a1b2c3_users_20260315120000;
DROP TABLE _d4e5f6_orders_20260315130000;4. 執行後處理 Schema Drift Event
⚠️ 這是最容易踩坑的步驟。
bbdataarchive 在 Argus 內被當成普通 database — Schema Drift Detection 會掃它。每次你 DROP TABLE,runner 在下次 tick(10 分內)會偵測到 fingerprint 變動 → 寫 schema_drift_event → audit_log。
兩種處理方式:
方式 A — 走正式 Plan(推薦)
- 把清理 SQL 包成一份 Plan(標題:「bbdataarchive 月度清理 2026-03」)
- 走 advisor + 審批(通常 DBA Lead 通過即可)
- 跑 → TaskRun 完成自動祝福新 baseline → 不會有 drift event
方式 B — AdminExecute 直跑 + 補單
- 用 AdminExecute 直跑 DROP TABLE
- 10 分內 drift event 出現
- Auditor 在 drift events 列表看到 → 標
retroactive_plan/manual_ack - 補 retroactive Plan(內容 = 那些 DROP TABLE)
為什麼推薦 A:把月度清理變成可重複、可審計的 Plan,跟一般變更同等待遇。B 是「忘了走 Plan 時的補救」。
5. 驗證
sql
-- PostgreSQL
SELECT count(*) FROM pg_tables WHERE schemaname = 'bbdataarchive';
-- 看 schema_drift_event 是否清乾淨(10 分後)
SELECT instance, db_name, status, detected_at
FROM schema_drift_event
WHERE db_name = 'bbdataarchive' OR (instance = '<your-instance>' AND db_name = '<source-db>')
ORDER BY detected_at DESC LIMIT 5;預期:
- backup table 數量降到本月該保留的量
- drift_event 全
resolved或不再出現
自動化選項
排程跑
最乾淨:用既有的「定時 Plan」機制(如果你的部署有),把清理 SQL 排月度跑。
沒有的話 — cron job 把上述 SOP 包成 script,每月 1 日凌晨 02:00 跑。
不建議的做法
| 做法 | 為什麼不該 |
|---|---|
直接連 PG 用 pg_repack / VACUUM FULL 壓 bbdataarchive | 不解決資料保留問題,只壓縮 |
| 改 Argus source 加 retention 邏輯 | 上游沒這個 feature,自己改會跟之後升級衝突 |
| 一刀切 DROP SCHEMA bbdataarchive CASCADE 重建 | 失去整個歷史;下次 PriorBackup 還會自動建 schema 沒問題,但所有舊倒帶能力一夜消失 |
| 把 bbdataarchive 移到別的 instance | PriorBackup hard-code 同 instance,移走會直接失敗 |
容量警報 — 加入監控
| Metric | 怎麼湊 |
|---|---|
bbdataarchive 占用空間(每 instance) | 上述 SQL pg_total_relation_size / information_schema.tables 跑成 Prometheus exporter |
| 最久 backup table 年齡 | SELECT min(create_time) FROM bbdataarchive |
| Backup table 總數 | SELECT count(*) FROM ... |
警報門檻建議:
- 占用 > instance 總容量 30% → WARNING
- 占用 > instance 總容量 50% → ERROR(緊急清)
- 最久 backup > retention × 1.5 → WARNING(SOP 沒跑)
反模式 — 看到立刻喊停
| 行為 | 為什麼不該 |
|---|---|
| 全部一鍵清 + 不留任何 backup | 失去倒帶能力;事故時無法 forensics |
| 只清 prod 不清 dev | dev 容量也會爆,多人共享環境拖累所有 user |
| 清 backup 前不通知 DBA Lead | 萬一剛好有 pending rollback 需求會撞 |
| 清完不看 drift_event | 留著 OPEN warning 累積,月底 compliance report 數字醜 |
常見錯誤
| 訊息 / 現象 | 含意 | 處理 |
|---|---|---|
DROP TABLE 出現 permission denied | 連的 user 沒 bbdataarchive 的 DROP 權限 | 用 admin data source;或先 GRANT ALL ON ... TO <user> |
| 清完後下次 PriorBackup 失敗 | 你不小心 DROP 了 schema/database 本身(不只是裡面的 table) | PostgreSQL: CREATE SCHEMA bbdataarchive; / MySQL: CREATE DATABASE bbdataarchive; 手動重建 |
| 清完 drift_event 還是 OPEN | 還沒下個 runner tick / 你還沒手動標 resolve | 等 10 分 → 自動 / 手動 resolve |
| bbdataarchive 內有「不知道哪來的」表 | 可能是先前手動操作 / 或 ghost migration 的副作用 | 對照 task_run_log PriorBackupDetail 確認;找不到對應就可清 |
相關
- 概念:變更回滾與資料復原
- 概念:Schema Drift Detection
- 任務:處理 drift event
- DBA:用 AdminExecute 緊急直跑
- 運維:備份與災備 — DB 層級 PITR
- 運維:Audit Log