SQLite Backup Restore Drill
SQLite backup restore drill 的核心責任是證明單檔 database 可以被一致備份並還原。這篇承接 File lifecycle / backup boundary,把備份從概念轉成 artifact、validation query 與 RPO / RTO note。
本文的驗收標準是:你能從 live app.db 建立 backup,將它還原到隔離路徑,通過 integrity_check 與核心查詢,並記錄 restore duration。
Prepare Source
Prepare source 的核心責任是建立一個有 WAL 與資料變化的 live database。若你已跑過 local file quickstart,可以直接沿用 /tmp/sqlite-lab/app.db。
1mkdir -p /tmp/sqlite-lab/backup /tmp/sqlite-lab/restore
2cd /tmp/sqlite-lab
3sqlite3 app.db "PRAGMA journal_mode = WAL;"
4sqlite3 app.db "INSERT INTO ledger_entries(account_id, amount_cents, idempotency_key, created_at) VALUES (2, 100, 'backup-drill-1', '2026-05-21T01:00:00Z');"這一步讓 source database 有新的資料。後續會用 backup snapshot 和 source 後續寫入做對照。
Create Backup
Create backup 的核心責任是用 SQLite-aware 方法建立一致 snapshot。SQLite CLI .backup 會透過 SQLite backup API 產出目標檔案。
1sqlite3 app.db ".backup 'backup/app-backup.db'"
2sqlite3 backup/app-backup.db "PRAGMA integrity_check;"預期 integrity_check 輸出 ok。這是最小 backup evidence。
VACUUM INTO 也可以產出 compact copy,適合想順便整理檔案大小的情境。
1sqlite3 app.db "VACUUM INTO 'backup/app-vacuum-copy.db';"
2sqlite3 backup/app-vacuum-copy.db "PRAGMA integrity_check;".backup 與 VACUUM INTO 都要在 runbook 中標明使用條件、耗時、目標路徑與失敗處理。正式環境還要記錄檔案大小、checksum 與 storage retention。
Mutate Source After Backup
Mutate source 的核心責任是確認 backup 是時間點 snapshot。備份後對 source 寫入新資料,再用 restore 驗證 backup 保持原時間點。
1sqlite3 app.db "INSERT INTO ledger_entries(account_id, amount_cents, idempotency_key, created_at) VALUES (1, 777, 'after-backup-write', '2026-05-21T01:05:00Z');"
2sqlite3 app.db "SELECT COUNT(*) FROM ledger_entries;"
3sqlite3 backup/app-backup.db "SELECT COUNT(*) FROM ledger_entries;"Source count 應比 backup count 多一筆。這個差異讓 RPO 討論具體化:backup 只保護到它建立的時間點。
Restore Isolated Copy
Restore isolated copy 的核心責任是避免把演練和 source 混在一起。把 backup 複製到 restore path,所有 validation 都對 restore file 執行。
1cp backup/app-backup.db restore/app-restored.db
2sqlite3 restore/app-restored.db "PRAGMA integrity_check;"
3sqlite3 restore/app-restored.db <<'SQL'
4.headers on
5.mode column
6SELECT account_id, SUM(amount_cents) AS balance_cents
7FROM ledger_entries
8GROUP BY account_id
9ORDER BY account_id;
10SQL正式 restore drill 還要啟動 application 指向 restore/app-restored.db,跑核心 read/write smoke test。若 application 需要 migration,也要確認 restore file 的 PRAGMA user_version 與 app version 相容。
RPO / RTO Note
RPO / RTO note 的核心責任是把演練結果轉成服務承諾。RPO 是可接受資料遺失窗口,RTO 是可接受恢復時間。
| 指標 | 本 lab 記錄方式 |
|---|---|
| RPO | backup 建立時間到事故時間的資料差距 |
| RTO | 從取得 backup 到 app smoke test 成功耗時 |
可以用 shell 的 time 記錄 restore duration。
1time sqlite3 restore/app-restored.db "PRAGMA integrity_check;"正式服務要把 RPO / RTO 寫進 observability / runbook。
Known Gap
Known gap 的核心責任是讓 lab 結果誠實。這個 drill 驗證 SQLite-aware backup 與 restore path;它尚未覆蓋 object storage credential、remote retention、large database restore time、encrypted disk、user device support flow 與 legal retention。
完成本篇後,下一步可以進入 WAL busy reproduction 觀察 writer boundary,或進入 migration fixture lab 建立 schema change evidence。