Add RocksDB managed backup and restore operations#1831
Draft
cb1kenobi wants to merge 7 commits into
Draft
Conversation
New operations, also runnable from the CLI under their operation name (and offline against a stopped server): create_backup, list_backups, verify_backup, delete_backup, purge_backups, restore_backup — plus RocksDB support for get_backup, which streams a gzipped-by-default tar (gzip=false for a plain tar) and works against a remote target. Managed backups are an incremental, checksum-verified, server-side repository under storage.backupPath (default <rootPath>/backup), one subdirectory per database, and capture the transaction log alongside the data. Restore closes the database across all worker threads, verifies process-wide closure (registryStatus), then purges and rewrites the directory — guarded by a per-database flock plus an fsynced marker so an interrupted restore is detected and not loaded on restart. A database a loaded component holds open, and always the system database, cannot be restored online (409 pointing at running it offline with the server stopped); offline restore additionally probes RocksDB's own lock before purging. Job workers release their RocksDB handles on exit so the closure check can pass. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This comment has been minimized.
This comment has been minimized.
…wrapping
- bin/backup.ts: load `.env` at the top of runBackupCommand so useOperationApi /
resolveRequestOptions see HARPER_CLI_TARGET/CLI_TARGET — otherwise a .env-configured
remote target was invisible and a destructive backup op could run against local.
- rocksdbBackup.ts: restore into an empty/tableless database no longer fails with
"no tables to back up" — guard requireRocksRootStore on the database actually having
tables (validate + online restore paths).
- restoreMarker.ts: directory fsync is now best-effort via a shared fsyncDir helper that
ignores EPERM/EISDIR/ENOTSUP, so beginRestore/completeRestore work on Windows.
- rocksdbBackup.ts: wrap restore-failure errors in a new Error({cause}) instead of
mutating error.message (a frozen/library error's message can be non-writable in strict mode).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cb1kenobi
added a commit
to HarperFast/documentation
that referenced
this pull request
Jul 16, 2026
Companion to HarperFast/harper#1831. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Backup operation responses exposed rocksdb-js's camelCase BackupInfo fields
(backupId, numberFiles) directly, inconsistent with the snake_case Operations API
convention and these operations' own snake_case inputs. Map at the API boundary:
list_backups returns { backup_id, timestamp, size, file_count } (dropping the internal
appMetadata), and create/verify/restore return backup_id (offline restore: restored_to).
listBackupsInDir stays camelCase for internal use; a new listBackupsOffline maps the CLI
offline list to match. Tests updated.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…rocksdb-backup-operations
cb1kenobi
added a commit
to HarperFast/documentation
that referenced
this pull request
Jul 16, 2026
…_count) Matches HarperFast/harper#1831, which now returns snake_case. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds managed backup/restore for RocksDB databases as Operations API operations —
create_backup,list_backups,verify_backup,delete_backup,purge_backups,restore_backup— plus RocksDB support forget_backup(streams a gzipped-by-defaulttar;gzip=falsefor plaintar; works against a remotetarget=). Each is also runnable from the CLI under its operation name, and offline against a stopped server. Managed backups are an incremental, checksum-verified, server-side repository understorage.backupPath(default<rootPath>/backup), one subdirectory per database, capturing the transaction log alongside the data.Purpose
Give RocksDB first-class server-managed backup/restore (LMDB already had volume-snapshot workflows), without stopping the server for the common case.
Where to focus review
dataLayer/rocksdbBackup.ts(restoreBackup) +dataLayer/restoreMarker.ts. Online restore writes an fsynced marker + takes a per-db flock, closes the DB across all worker threads, verifies process-wide closure viaregistryStatus(), then purges + rewrites. A component-held DB (and alwayssystem) can't be closed → 409 pointing at offline restore. Worth checking the close→verify→purge ordering and the marker/lock crash-recovery states (in-progress/incomplete/clear).restoreBackupOffline. The offline path is chosen on a PID heuristic, but the PID file is briefly absent duringharper restart, so it now probes RocksDB's own lock (RocksDatabase.open) before purging — a lock error aborts, a corrupt/half-restored dir still proceeds (recovery).server/jobs/jobProcess.ts+resources/databases.ts(closeDatabase/closeLoadedDatabases, new). Job workers close their process-global RocksDB handles on exit or the closure check can never pass;systemis intentionally left open; tableless databases are handled explicitly.bin/cliOperations.ts. Extracted target + auth resolution intoresolveRequestOptions, now shared bycliOperationsand the streamingget_backupdownload.cliOperationsbehavior should be unchanged (bin suite green).Cross-model review (codex + Gemini)
Fixed from review: offline-restore lock probe, CLI
content-dispositionpath traversal,jobProcesscleanup whenupdateJobrejects, marker-removal fsync, tableless-DB handle leak. Deferred (not blocking):registryStatus()polling — the cross-process case is covered by the offline probe; a native primitive is a rocksdb-js follow-on.resetDatabasesshares the gap), filed as Table background work (expiration timer, delete/cleanup callbacks) not disposed when a database's stores are closed #1811.Docs
Companion docs PR: HarperFast/documentation#590.
Generated by an LLM (Claude Opus 4.8, 1M context).
🤖 Generated with Claude Code