Repository navigation
fix(backup): skip DB backup when the index is unchanged - #10
Conversation
Each backup is a full 15G copy of code_index.db. The index had not changed since 2026-07-09, so the twice-daily job was keeping four identical copies (60G). Record the source size and mtime after each backup and skip when they match and the WAL is empty. Also lower the default retention from 14 to 4. Co-Authored-By: Claude <noreply@anthropic.com>
Runs backup-db.sh against a throwaway SQLite file: an unchanged DB is skipped, a changed DB or a missing stamp file produces a new backup. Co-Authored-By: Claude <noreply@anthropic.com>
Address review findings on the skip-if-unchanged change: - copy to a .tmp file and rename on success, so a killed run never leaves a truncated file that the skip check would treat as a valid backup - record the backup file name in the stamp and skip only if it still exists - use size, nanosecond mtime, and inode, and write the stamp only if the source did not change during the copy - tests now use WAL mode and cover pending WAL frames, same-second writes, and a deleted newest backup Co-Authored-By: Claude <noreply@anthropic.com>
|
Important Review skippedAuto reviews are limited based on label configuration. 🏷️ Required labels (at least one) (1)
Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository: escoffier-labs/coderabbit/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
Concurrent writers or backup runs can bypass change detection or expose an incomplete backup.
Review effort: Balanced
Findings: 2
Open (2)
What changed in this PR
Adds change-aware SQLite backups to avoid redundant large copies.
Changes:
- Skips unchanged databases using source metadata and WAL state.
- Adds temporary-file backups and reduces default retention to four.
- Adds regression tests for backup and skip scenarios.
| File | Description |
|---|---|
backup-db.sh |
Implements change detection, atomic replacement, and retention changes. |
tests/test_backup_db.py |
Tests skip and forced-backup scenarios. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| WAL_BEFORE="$(wal_size)" | ||
| if [ "$WAL_BEFORE" -eq 0 ] && [ -f "$STAMP_FILE" ]; then | ||
| IFS=$'\t' read -r LAST_STATE LAST_BACKUP < "$STAMP_FILE" || true | ||
| if [ "${LAST_STATE:-}" = "$BEFORE" ] && [ -n "${LAST_BACKUP:-}" ] \ | ||
| && [ -f "$BACKUP_DIR/$LAST_BACKUP" ]; then |
| BACKUP_NAME="code_index_$TIMESTAMP.db" | ||
| TMP_BACKUP="$BACKUP_DIR/$BACKUP_NAME.tmp" | ||
| trap 'rm -f "$TMP_BACKUP"' EXIT | ||
| rm -f "$TMP_BACKUP" |

What
backup-db.shmakes a full copy of the index on every scheduled run. When the index has not changed, that only adds another identical copy. On one install the index had been static for months, and four identical 15G copies were sitting inbackups/.This change makes the script skip the copy when nothing changed since the last good backup:
backups/.last-source-stampwith the DB's size, nanosecond mtime, and inode, plus the backup file name.-walfile is empty, and that backup file still exists.*.db.tmpand is renamed on success. A killed run cannot leave a truncated file that looks like a valid backup.CODE_SEARCH_MAX_BACKUPSstill overrides it).Verify
tests/test_backup_db.py(new, 5 tests): unchanged DB is skipped; a same-second write, pending WAL frames, a missing stamp, or a deleted newest backup each force a new backup; no.tmpfile is left behind.main's script and passes with this change../scripts/verifypasses: mcp typecheck/test/build, 28 Python tests, serve smoke test.Review notes
An existing stamp in the old format will not match, so the first run after upgrading takes one more backup and then starts skipping.
🤖 Generated with Claude Code