BenoStreamDB Recovery Runbook¶
This document outlines the formal recovery procedures for BenoStreamDB, detailing RPO/RTO expectations and step-by-step resolution paths for catastrophic failures.
BenoStreamDB is designed around a strict separation of authoritative state (Iceberg snapshots, Parquet data files) and derived state (HNSW/BM25 indexes). This architecture ensures that most “database corruption” events are merely cache-invalidation events that can be resolved without data loss.
Recovery Objectives¶
RPO (Recovery Point Objective)¶
BenoStreamDB’s RPO depends entirely on your configured WalDurability setting:
WalDurability::Sync: RPO = 0. Every acknowledged write is synchronously fsync’d to the Write-Ahead Log before the client receives an OK. No committed data is lost in a crash.WalDurability::Async: RPO = < 1s (configurable). Writes are buffered in memory and flushed periodically. A hard crash will lose the in-memory buffer (unacknowledged or acknowledged asynchronously).
RTO (Recovery Time Objective)¶
Data Availability: Seconds. On startup, BenoStreamDB reads the latest Iceberg manifest and replays the WAL. This process typically takes under a second. The data is immediately available for querying (falling back to scalar/vector scans if indexes are missing).
Performance Recovery (Index Rebuild): Minutes to Hours. If an index is lost or corrupted, queries will gracefully degrade to full-scans. Rebuilding the index is an asynchronous background process whose duration depends on dataset size.
1. Restore-from-Object-Store Procedure¶
Because Iceberg/Parquet in the object store is the authoritative source of truth, BenoStreamDB compute nodes are essentially stateless cache engines.
Scenario: The physical server hosting BenoStreamDB is destroyed. Action:
Provision a new compute node.
Ensure the node has IAM/network access to the backing object store (S3/GCS/Azure).
Start the BenoStreamDB process pointing to the existing URI:
let table = Table::new_async("s3://my-bucket/my-table").await?;
Result: The system will immediately read the latest
commit.lockor catalog pointer, load the manifest, and resume serving reads and writes.
2. WAL Recovery Procedure¶
The Write-Ahead Log (_wal/) stores durable writes that have not yet been compacted into an Iceberg manifest.
Scenario: The process crashes mid-write, corrupting the active WAL file. Upon restart, the database fails to initialize with a WalCorruptionError.
Action:
BenoStreamDB prioritizes data safety and will refuse to start if it detects torn or corrupted WAL batches. To forcibly recover availability at the cost of losing un-manifested writes:
Locate the WAL directory (default:
[table_uri]/_wal/).Identify the corrupted
.arrowfile (usually the one with the most recent timestamp).Move the file out of the directory:
mv s3://my-bucket/my-table/_wal/wal_0042.arrow /backup/corrupted_wal_0042.arrow
Restart the database.
Result: The DB will replay all valid WAL files and resume operation. Any writes contained in
wal_0042.arroware permanently lost.
3. Index Rebuild Procedure¶
Indexes (HNSW, BM25, Bloom filters) are non-authoritative. If they become corrupted, out-of-sync, or are accidentally deleted, they can be regenerated directly from the Parquet data files.
Scenario: Vector search latency spikes because the HNSW index was partially deleted, or logs report IndexChecksumMismatch.
Action:
Drop the corrupted index. This removes the metadata pointer and deletes the corrupted
.binfiles:table.drop_index("embedding").await?;
Re-create the index. The database will launch a background task to rebuild it from the authoritative Iceberg data:
table.add_index("embedding".to_string(), IndexAlgorithm::HNSW).await?;
Result: The system will serve vector similarity searches using exact nearest-neighbor (flat scan) until the HNSW build completes, at which point it will seamlessly swap to using the new index.
4. Catalog Recovery Procedure¶
If you are using a decoupled catalog (e.g., Nessie, REST, or Hive Metastore) to track table states instead of the built-in file-based commit.lock:
Scenario: The external catalog database (e.g., PostgreSQL backing Nessie) is irrecoverably corrupted.
Action:
Because BenoStreamDB writes valid Iceberg metadata files (v1.metadata.json, v2.metadata.json) into the metadata/ directory of the object store, the table can be recovered even if the catalog is lost.
Inspect the
metadata/directory in your object store.Identify the highest numbered metadata file (e.g.,
v42.metadata.json).Manually register this table in your new/restored catalog using the Iceberg REST API or catalog-specific CLI:
POST /v1/namespaces/default/register HTTP/1.1 Content-Type: application/json { "name": "my-table", "metadata-location": "s3://my-bucket/my-table/metadata/v42.metadata.json" }
Result: The new catalog will point to the exact transaction state of
v42, and BenoStreamDB will resume operations normally.