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() resolves — before 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.
Follow-up from #1831 review (flagged by @kriszyp on
dataLayer/rocksdbBackup.ts).Problem
create_backupis two-phase:rootStore.backup()writes the RocksDB engine backup, thenfinalizeBackup()copies the blob snapshot and publishes the completion manifest.The rocksdb-js backup-directory writer lock is released when
rootStore.backup()resolves — beforefinalizeBackup()copies blobs and writes the manifest. So a concurrentpurge_backups/delete_backupon the same database can acquire that lock, see and purge the just-created engine backup, and return — whilecreate_backupkeeps copying blobs and then writes a manifest (and reports abackup_id) for an engine backup that no longer exists.Net:
create_backupcan report success with a phantombackup_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) acrosscreate_backup/delete_backup/purge_backupsso 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.