運維

備份與災難恢復

備份什麼、如何恢復,以及如何為故障做規劃。

ObjectOS 本身是無狀態的 —— 執行時可以從容器映象重建。**備份針對的是 ObjectOS 所 依賴的資料,而不是 ObjectOS 本身。**請圍繞這些資料集規劃恢復。本頁的所有內容同樣 適用於 Community 和 Enterprise。

備份什麼

資產歸屬備份策略
業務資料庫客戶資料庫原生備份(託管服務用 PITR);每季度測試一次恢復
編譯後的產物(objectstack.json)應用/釋出團隊把每個已釋出的產物存放在不可變儲存中;絕不覆蓋
金鑰基線 —— 首先是 OS_SECRET_KEY客戶的金鑰管理器託管備份這些值本身;按策略確定輪換週期
物件/檔案儲存(啟用 storage 能力時)客戶儲存桶版本控制 + 按需跨區域複製
本地儲存上的上傳檔案(OS_STORAGE_LOCAL_ROOT)客戶與資料庫相同的計劃,這樣記錄及其附件會恢復到同一個時間點
客戶自管的身份提供商IdP 廠商廠商原生方式

**沒有 OS_SECRET_KEY 的資料庫備份是不完整的備份。**每個儲存的金鑰 —— 加密的 設定、secret 欄位、資料來源憑據 —— 都用這一個金鑰加密。在沒有原始金鑰的情況下 恢復的資料庫會保留這些值,但它們將永遠無法讀取。在生成金鑰的當天就託管備份它, 並把金鑰和資料庫視為一個備份單元。

一個設定了 OS_DATABASE_URL 和 OS_SECRET_KEY 的容器,其檔案系統本身不需要備份: 它的快取都可以重建 —— 快取的產物每次讀取時都會依據其完整性固定值重新校驗,所以 丟失快取只會多一次獲取,絕不會影響正確性。使用預設值執行的單臺主機則不同: 它的主目錄儲存著 SQLite 資料庫、上傳的檔案和自行生成的加密金鑰,所以要把它納入 你的檔案備份。

資料庫備份

根據驅動選擇策略:

驅動推薦做法
PostgreSQL持續 WAL 歸檔 + 基礎備份;時間點恢復。對於小型資料庫,pg_dump --format=custom 是可行的邏輯備份
MySQL二進位制日誌歸檔 + 完整轉儲;時間點恢復
MongoDB副本集快照;用 oplog 實現 PITR
SQLite(單節點 / 桌面)WAL 模式 + 通過 VACUUM INTO 或線上備份 API 做熱快照;可選用 Litestream 做持續複製 —— 參見下文的 SQLite 部署

無論使用哪種驅動,都要驗證:

  • 備份能在客戶的 RPO 內完成;
  • 一個全新的資料庫可以用同一個產物啟動 ObjectOS 並提供服務;
  • 至少每季度端到端地演練一次恢復測試。

SQLite 部署

SQLite 是預設驅動,對於單節點的 ObjectOS 是正當的生產選擇 —— 桌面應用、小團隊 的內部工具、邊緣 / 本地部署的一體機、評估環境。代價是結構性的:SQLite 只允許單個 寫入者,所以它不適合多節點 ObjectOS、高併發寫入吞吐量或共享資料庫的部署。對於 這些場景,請使用 PostgreSQL。

當你確實在生產環境中執行 SQLite 時,讓它安全的配置和備份方案是配套的:

執行時配置

  • 執行時讓基於檔案的 SQLite 保持 WAL 模式(讀者不會阻塞寫入者;崩潰安全)。這 意味著資料庫旁邊的 app.db-wal 可能儲存著尚未寫入 app.db 的已提交寫入 —— 在執行時執行期間,絕不要單獨複製 app.db。
  • PRAGMA synchronous=NORMAL 是常見的桌面/單節點預設值 —— 搭配 WAL 是安全的, 而且比 FULL 快得多。
  • 把資料庫檔案放在本地磁碟上。在執行時執行期間,不要把它放在 NFS、SMB 上, 或者放在由 Dropbox / OneDrive / iCloud 同步的資料夾中 —— SQLite 的鎖在這些地方 不可靠,這是 SQLite 部署損壞最常見的原因。

熱快照(無停機)

在你用 SQLite 的線上備份 API 或 VACUUM INTO 製作快照時,執行時會繼續提供服務:

VACUUM INTO '/var/backups/objectos/db-2026-05-27T13-00Z.sqlite';

按與你的 RPO 相匹配的頻率排程它(cron、systemd 定時器或程序內排程器)。給每個 快照標上產生它的產物版本,這樣你就可以把資料庫和產物一起回滾(參見下文的 產物版本管理)。

異地副本

本地快照無法在磁碟損壞後倖存。把每個快照推送到持久儲存:

  • 伺服器 / 虛擬機器:推送到 S3 或任何相容 S3 的儲存桶(你很可能已經為 storage 能力配置了一個)。
  • 桌面應用:把快照寫入使用者控制的同步資料夾(OneDrive / iCloud / Google Drive)—— 在這裡是可以接受的,因為與活動資料庫不同,快照檔案是已關閉且不可變的。

持續複製(更低的 RPO)

如果要在不放棄 SQLite 的前提下實現一分鐘以內的 RPO,就在 ObjectOS 程序旁邊執行 Litestream。它把 WAL 流式傳輸到相容 S3 的儲存,並支援 時間點恢復。當單節點 SQLite 部署需要接近零的資料丟失時,這是推薦的路徑。

恢復

停止執行時,用選定的快照替換資料庫檔案(或者執行 litestream restore),確保旁邊 沒有殘留過期的 -wal 或 -shm 檔案,然後針對產生該快照的同一個產物版本啟動執行時。

產物版本管理

把已釋出的產物視為不可變的。給每個產物標上編譯它所用的釋出 id(例如 objectstack-2026-05-24.json)。恢復到一個已知良好的業務狀態,通常意味著:

  1. 把資料庫恢復到選定的時間點。
  2. 把 ObjectOS 重新指向當時線上的產物版本。
  3. 重啟執行時。

如果你原地覆蓋產物,即使資料庫備份完美無缺,你也會失去幹淨回滾的能力。

RPO/RTO 規劃

客戶部署的一個可行的起始目標:

類別RPORTO備註
評估 / 演示盡力而為盡力而為SQLite 快照即可
桌面應用 / 小團隊單節點≤ 1 小時(快照)或 ≤ 數秒(Litestream)數分鐘SQLite + WAL + 定時 VACUUM INTO + 異地副本
單租戶生產≤ 15 分鐘≤ 1 小時帶 PITR 的託管 PostgreSQL + 預熱映象
多租戶 / 受監管≤ 5 分鐘≤ 30 分鐘高可用資料庫 + 多可用區 ObjectOS + 經過測試的執行手冊

更嚴格的目標需要 ObjectOS 容器本身之外的平臺變更(高可用資料庫、多可用區入口、 預熱副本)。

值得演練的故障模式

  • **資料庫長時間不可用。**從 ObjectStack 17.0 起,這是有約定的行為,而不是隻能 期望的事情:只要某個資料驅動沒有響應,/api/v1/ready 就返回 503,所以就緒探針 會把 Pod 標記為未就緒。要演練的是恢復 —— 資料庫恢復後副本會重新加入,並且 不需要任何重啟就能察覺。物件所繫結的資料來源如果在啟動時無法連線,現在會讓啟動 失敗,所以要在應用副本滾動之前確認你的恢復已經完成。
  • **產物回退。**回滾產物指標;資料不受影響。
  • **金鑰輪換。**輪換 OS_AUTH_SECRET 會使所有會話失效。在維護視窗期間進行,或在 各副本之間錯開進行。
  • **區域故障。**如果客戶要求區域故障轉移,業務資料庫、金鑰管理器和入口都需要跨 區域。ObjectOS 本身可以在任何能獲取到映象的地方執行。

恢復演練

在上線之前,在一臺臨時主機上演練這一流程,並在任何儲存變更之後再演練一次。 一個你從未恢復過的備份只是一種希望,而不是備份。

  1. 準備一臺乾淨的主機,使用與製作備份時相同的映象版本。

  2. 恢復資料庫 —— 用提供商的快照,或者:

    pg_restore --clean --if-exists -d "$OS_DATABASE_URL" backup-2026-07-14.dump
  3. 提供原始的金鑰。OS_SECRET_KEY 和 OS_AUTH_SECRET 必須是託管備份的原始值, 絕不能是新生成的值。如果你使用本地儲存,也要恢復上傳的檔案。

  4. 針對同一個產物版本啟動,並驗證:

    curl -fsS https://app.example.com/api/v1/health
    curl -fsS https://app.example.com/api/v1/ready

    然後端到端地證明恢復成功:用一個真實賬戶登入,開啟一條在備份之前就存在的 記錄,並讀取一個加密設定的值 —— 這才會用到 OS_SECRET_KEY。

執行手冊中要記錄什麼

  • 每個資料集的備份計劃、保留期和值班聯絡人。
  • 分步的恢復流程(先資料庫,再產物,然後啟動 ObjectOS)。
  • 用於確認恢復後的資料庫一致的驗證查詢。
  • 同時覆蓋 ObjectOS 映象和產物版本的回滾計劃(參見 升級與回滾)。
  • 面向客戶可見事件的溝通模板。

企業版額外提供

  • **把上一個映象摘要與備份儲存在一起。**恢復到某個時間點,就是恢復到當時正在執行 的摘要,而在物理隔離的站點上,上一個摘要可能是唯一的副本 —— 參見 物理隔離。
  • **OS_LICENSE_KEY 屬於金鑰基線。**恢復後的部署會用交給它的許可證啟動,而多組織 姿態沒有許可證會拒絕啟動。
  • **在副本滾動之前完成恢復。**捆綁的技術棧會在任何副本啟動之前執行它的一次性遷移, 所以當技術棧啟動時,資料庫必須已經完整。