# 重播與復原

本頁說明 ToriiDB 如何從 snapshot 與 log 載入資料庫、退回較舊世代，以及如何備份資料。

## 重播

資料庫在第一次使用時載入（`sync.Once`）：

1. 移除殘留的 `*.tmp` 檔。
2. 由新到舊列出 snapshot 編號；沒有 snapshot 時從世代 `0` 開始（只有 log）。
3. 世代 `N`：重播 `N.snap`（若 `N > 0`），接著依序重播存在的 `N+1.log`、`N+2.log`、...。
4. 遇到 I/O 錯誤時記為 `loadErr`，改試下一個較舊的 snapshot。
5. 成功時清除 `loadErr`，並持續附加到最後一個存在的 log。

以 `bufio.Reader.ReadBytes('\n')` 讀行，行長不受限制。不使用 `bufio.Scanner`，因為它預設 64 KB 的行長上限曾讓一個 70 KB 的值使整個資料庫讀不出來。空行或格式錯誤的 JSON 行會略過；只有真正的讀取錯誤（例如 `.snap` 路徑其實是目錄）才讓重播失敗。

重播會重建帶過期與向量的 `SET` 項目，套用 `DEL`/`EXPIRE`/`EXPIREAT`/`PERSIST`，並預熱 JSON 值的解析快取。

## 備份與復原

- 備份整個資料目錄，包含所有 `db_N/` 目錄。
- 需要一致的時間點副本時，先關閉 store（或停止寫入）再複製。
- 最新 snapshot 無法讀取時，資料庫會自動從前一世代載入。
- 沒有任何世代能重播時，process 仍接受附加寫入但拒絕壓縮，因此不會覆寫任何 snapshot。

## 相關頁面

- [檔案與寫入](/zh/persistence)
- [壓縮與回收](/zh/persistence-compaction)
- [已移除 API](/zh/removed-api)
