Skip to main content

archive

Function archive 

Source
pub async fn archive(
    conn: &Connection,
    cutoff: &str,
    archived_at: &str,
    archive_path: &Path,
) -> Result<ArchiveReport>
Expand description

Move closed edge intervals and superseded log rows older than cutoff into the cold database at archive_path (§5.7, D-012, D-022).

The whole session is one BEGIN IMMEDIATE … COMMIT transaction (D-012): copy-then-delete must be atomic, or a crash between the phases duplicates or loses rows. The archive-session marker that unlocks the delete guards (D-008 revised) is created as the first statement of that transaction and dropped as the last, so it never exists as committed state — commit drops it, rollback discards it, and there is no crash path that leaves the guards disarmed.

ATTACH is issued outside the transaction and DETACH is issued unconditionally on the way out, including on error: ATTACH is not transactional and survives ROLLBACK, so a leaked handle would make every later archive or cold-DB reconstruct fail with “database cold is already in use”. archived_at is when the session ran; cutoff is the boundary it used.

Both go into cold.archive_horizon, and until Wave 4.5 both columns were written with the cutoff — so the table recorded that every archive had run at the instant it was archiving up to, which is the one time it certainly did not run. The two are different clocks (Doctrine II) and the row exists to carry both: the cutoff says what was moved, archived_at says when the decision was taken, and only the second can answer “how stale is this cold file”. The column was there, correctly named, holding the wrong value.