Skip to content

create_backup: serialize backup management ops to close a finalize/purge race #2031

Description

@cb1kenobi

Follow-up from #1831 review (flagged by @kriszyp on dataLayer/rocksdbBackup.ts).

Problem

create_backup is two-phase: rootStore.backup() writes the RocksDB engine backup, then finalizeBackup() copies the blob snapshot and publishes the completion manifest.

The rocksdb-js backup-directory writer lock is released when rootStore.backup() resolvesbefore finalizeBackup() copies blobs and writes the manifest. So a concurrent purge_backups / delete_backup on the same database can acquire that lock, see and purge the just-created engine backup, and return — while create_backup keeps copying blobs and then writes a manifest (and reports a backup_id) for an engine backup that no longer exists.

Net: create_backup can report success with a phantom backup_id, and a manifest can outlive its engine backup.

Scope / severity

Only bites when two backup admin operations run concurrently on the same database — uncommon, but a real correctness gap.

Suggested fix

Hold a per-database backup-management lock (an OS flock like the restore lock in dataLayer/restoreMarker.ts) across create_backup / delete_backup / purge_backups so they serialize through completion, i.e. the whole engine-backup + blob-snapshot + manifest sequence is exclusive. This is the 'serialize management operations through completion' aspect deferred during #1831.

Add a regression that races a create (during its blob-copy phase) against a purge.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    Priority

    P1

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions