Skip to content

fix(db): harden interrupted restore recovery across schema versions and descriptor cleanup #1219

Closed

Description

@khaira777

Summary

This issue resolves two integrity hardening gaps in the database restore and recovery subsystem:

  1. Interrupted restore recovery across schema versions (Follow-up to PR fix(main): optimize order search with indexed candidate retrieval #1204):
    When startup recovery (recoverInterruptedDatabaseReplacement) processes a replacement journal (flo-restore-recovery-*.json) with a recovery snapshot from an earlier schema version (e.g. v114 before migration 115 added FTS virtual tables), isHealthyDatabaseFile checked the candidate against the current build's latest schema reference (v115). Because the historical snapshot naturally lacked v115 tables and definitions, isHealthyDatabaseFile failed, causing startup recovery to throw an error and abort boot, preventing initDatabase from restoring and running pending migrations forward.

  2. Backup descriptor-close cleanup (Follow-up to PR fix(db): eliminate redundant restore snapshot staging and ensure temp cleanup #1193):
    In materializeRestoreSource, if fs.closeSync(sourceFd) threw an exception in the finally block, the newly materialized temporary snapshot directory was leaked on disk because its cleanup callback was never returned or called.

Proposed Changes

  • In main/db.ts:
    • Allow runMigrations and buildIdealSchemaDb to accept an optional targetVersion?: number.
    • Cache SchemaRecoveryReference instances by target version in cachedSchemaRecoveryReferences = new Map<number, SchemaRecoveryReference>().
    • In isHealthyDatabaseFile, retrieve getRecoverySchemaReference(schemaVersion) to validate historical databases against their respective valid schema definitions.
    • In materializeRestoreSource, ensure that if writing fails or fs.closeSync(sourceFd) throws, the staged snapshot directory is immediately removed.
  • In tests/backup-restore-production.test.ts:
    • Add test for immediate temporary directory cleanup upon closeSync fault injection.
    • Add test for interrupted restore recovery of a v114 replacement journal, verifying successful restoration and forward migration to v115 on startup.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions