Recovery Resync
This page explains how data from the fallback period flows from local files through memory back to Redis once Redis recovers, and which entries are not written back.
Steps
changeToNormalMode (sync.go:50-92) runs in order:
| Step | Action | On failure |
|---|---|---|
| 1 | Walk every .json file under {DBPath}/{DB} |
Errors such as a missing directory → the whole flow aborts and isHealth stays false |
| 2 | Read and parse each file as Cache, store it in the memory cache under Cache.Key |
A file that fails to read or parse → error logged, file skipped |
| 3 | syncMemoryToRedis: iterate the entire memory cache and pipeline entries to Redis |
Pipeline execution errors are not checked |
| 4 | cleanupLocalFile: delete every .json file and empty subdirectory (keeping {DBPath}/{DB} itself) |
A failed delete → error logged, continue |
| 5 | isHealth = true |
— |
Write-Back Rules
syncMemoryToRedis (sync.go:94-133):
| Item | Rule |
|---|---|
| Scope | Every non-expired entry in the memory cache, including entries that were in memory before fallback |
| Redis TTL | Timestamp + TTL − now seconds (remaining time) |
| Remaining TTL ≤ 0 | Not written; entries without a TTL (ttl = 0) also land here |
| Batching | One Exec per 100 non-expired entries, plus a final Exec for the remainder |
| Format | JSON of Data (strings have quotes trimmed), same as Set |
| Concurrency guard | isRecovering uses CAS so only one resync runs at a time; a concurrent call returns immediately |
Observed Results
Two keys written while Redis was down, then Redis restored:
| Key | Write | Redis after recovery | Local file after recovery |
|---|---|---|---|
ttlkey |
Set("ttlkey", "t", time.Hour) |
Present, TTL 59m59s | Deleted |
forever |
Set("forever", "f", 0) |
Absent | Deleted |
forever is still in the memory cache; the first read in normal mode writes it back to Redis through Read-Repair.
When Data Survives Only in Memory
Step 4 deletes local files whether or not step 3 succeeded. After any of the following, the data lives only in the memory cache and is lost when the process exits:
| Case | Reason |
|---|---|
Pipeline Exec fails (for example Redis drops again during recovery) |
Errors are unchecked and files are deleted anyway |
| A resync is already running | The second syncMemoryToRedis call returns immediately, but the file cleanup still runs |
ttl = 0 entries |
Not in the batch; only read-repair writes them back |
Memory Cache After Recovery
Recovery does not clear the memory cache. Every loaded entry stays in memory until it expires and is removed by the background sweep; in normal mode, Get always hits memory for these keys and never asks Redis.