Skip to main content

replace_database

Function replace_database 

Source
pub fn replace_database(
    options: &DbOptions,
    replacement: &Path,
    lock: &LockOptions,
) -> Result<()>
Expand description

Atomically replace the database at options.path with the database at replacement.

Under the store-wide exclusive lock (StoreLock::exclusive, waiting per lock):

  1. replacement is opened read-only with options’ key and every PRAGMA integrity_check row must be ok (DbError::Integrity otherwise; the live database is untouched).
  2. Its committed contents (WAL included) are copied through SQLite’s backup API into a staging file beside the live database, checked, narrowed to owner-only and synced.
  3. The live database’s -wal, -shm and -journal sidecars are removed, so a stale log can never be replayed onto the new file, and the staging file is renamed onto the path.

A failure in step 1 or 2 leaves the live database untouched and removes the staging file. The only crash window is between removing the sidecars and the rename in step 3: the old main file is then still in place without its uncheckpointed log, and the staging file remains (reclaimed by rightkit_fs::sweep_stale_temps). The replacement keeps the options’ key, so it must be encrypted with the same key.

Every connection to the live database, in this process and in any other, must be closed before the call: other processes by holding only StoreLock::shared guards (the exclusive guard cannot be taken while one is held), this process by dropping its writer and calling ReadPool::close_and_wait. On Windows an open connection also makes the rename fail.