pub async fn restore_from(
pool: SqlitePool,
db_path: &Path,
backup_path: &Path,
now: DateTime<Utc>,
) -> DbResult<RestoreOutcome>Expand description
Restores db_path from a backup_to-produced file, replacing its entire contents.
Takes pool by value, not &SqlitePool: restoring means the file underneath every
existing connection is about to be replaced out from under them, so the caller’s old pool
must be given up, not merely borrowed. The type system then enforces that the old handle
can’t accidentally go on being used afterward — every caller must switch to
RestoreOutcome::pool.
Safety, in order:
backup_pathis validated (PRAGMA integrity_check, plus confirming a realtune_runstable exists) before anything about the live database is touched, so a corrupt or unrelated file never gets a chance to destroy good data.- The caller’s own connections to
db_pathare closed first, so step 3’s exclusivity check isn’t confused by this process’s own still-open pool. - If
db_pathalready exists, [exclusive_pre_restore_snapshot] both confirms no other connection — in this process or another — still holds it open, and, while that’s proven true, takes a consistentVACUUM INTOcopy of it (seeRestoreOutcome::pre_restore_backup). Restoring the wrong backup, or restoring when a fresh backup was what was actually wanted, is still recoverable afterward. UsingVACUUM INTOhere rather than a raw file copy means the safety copy can never be silently missing data that was still sitting in a WAL file — the same reasonbackup_touses it. - The backup is copied into place via write-to-a-temp-file-then-rename, so a crash or a
full disk mid-copy leaves the original
db_pathuntouched rather than half-overwritten (rename onto an existing path is atomic on the same filesystem, which a same-directory temp file guarantees; renaming a file onto an existing file — as opposed to a directory — replaces it on Windows too, viaMOVEFILE_REPLACE_EXISTING, so no Windows-specific fallback is needed here). - Any stale
-wal/-shmsidecar files left over from the olddb_pathare removed — they describe uncommitted changes to a database that, after step 4, no longer exists at that path. db_pathis reopened viaconnect, which reapplies the standard pragmas and runs any migrations the backup predates forward — restoring an older backup transparently upgrades its schema, exactly as opening an old database file normally would.
Restoring while another bhtune process (for instance bhtune-server, running
alongside the CLI) has db_path open returns DbError::DatabaseInUse instead of
proceeding — see [exclusive_pre_restore_snapshot] for how that’s detected and its
residual, deliberately-accepted race.