Add incremental backup support (Phase 8)
Some checks failed
Test / test (push) Has been cancelled
Test / build (push) Has been cancelled

BackupScheduler Enhancement:
- Added incremental: bool field to BackupScheduleConfig
- Default: incremental=true (enabled by default)
- copy_incremental_to_snapshot() method
- file_changed() detection (size + mtime comparison)
- Hardlink unchanged files to base snapshot (ZFS-style)

Incremental Backup Algorithm:
1. If incremental=true and previous snapshot exists:
   - Compare file size and mtime with base snapshot
   - If unchanged: create hardlink to base (zero disk usage)
   - If changed: copy and compress (new content)
2. If incremental=false or no previous snapshot:
   - Full copy (traditional backup)

Storage Savings:
- Unchanged files: hardlink (0 extra disk space)
- Changed files: copy + compress (minimal overhead)
- Similar to ZFS snapshot mechanism

BackupConfigResponse Updated:
- Added incremental field
- Added compress field (GUI: dropdown select)

Backup.vue Updated:
- Incremental switch with explanation text
- Compression dropdown (None/LZ4/ZSTD)
- Default values loaded from backend

REST API Test:
curl /api/v2/backup/config
{incremental:true,compress:zstd,...}

Build: 495 tests pass
This commit is contained in:
Warren
2026-06-24 04:20:33 +08:00
parent 2d8e9049b0
commit d76a200560
4 changed files with 103 additions and 2 deletions

View File

@@ -2753,6 +2753,7 @@ pub struct BackupConfigResponse {
pub compress: String,
pub encrypt: bool,
pub include_checksums: bool,
pub incremental: bool,
}
#[derive(Debug, Serialize, Deserialize)]
@@ -2806,6 +2807,7 @@ async fn get_backup_config_handler() -> Json<BackupConfigResponse> {
compress: compress_name.to_string(),
encrypt: config.encrypt,
include_checksums: config.include_checksums,
incremental: config.incremental,
})
}
@@ -2824,6 +2826,7 @@ async fn set_backup_config_handler(Json(config): Json<BackupConfigResponse>) ->
compress,
encrypt: config.encrypt,
include_checksums: config.include_checksums,
incremental: config.incremental,
};
scheduler.set_config(new_config);
Json(serde_json::json!({"success": true, "message": "Backup config updated"}))