fix: publish the file number guard from DBCloud - #548
Conversation
The rocksdb-cloud bump to 8802542 ("cloud: fix purger garbage leak and
move file-number-guard writer in-repo") added a hard check in
DBCloudImpl::Open: a writable DBCloud whose cloud file deletion is
delegated to the purger must set publish_file_number_guard. The data
store hardcodes disable_cloud_file_deletion and defaults run_purger to
true, so every S3/GCS open now fails with
Invalid argument: publish_file_number_guard must be enabled for a
writable DBCloud when cloud file deletion is delegated to the purger
and the server never starts.
Enable the option. That both satisfies the check and installs the
in-repo FileNumberGuardPublisher, which is the writer rocksdb-cloud
moved in-repo -- so drop our own copy (PurgerEventListener and
SlidingWindow) rather than run both. Two publishers racing on the same
smallest_new_file_number-<epoch> object could land PUTs out of order and
reinstate a stale high watermark, letting the purger delete an SST that
is still in flight.
The in-repo publisher supersedes ours: it sources the epoch from the
cloud manifest instead of having it injected after open, writes the
0 sentinel before recovery can flush, and gates SST uploads through
ProtectFileUpload so the watermark is lowered before the upload rather
than on a timer -- closing the window our timer-based publisher left
between an SST reaching S3 and the guard being republished.
The on-cloud protocol is unchanged: same object key and same ASCII
uint64 value, so upgraded and old nodes interoperate on one bucket.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
WalkthroughThe change removes RocksDB cloud purger listener and sliding-window components from builds and database initialization. It adds the S3 downloader source and enables the cloud file-number publication guard while retaining database epoch validation. ChangesCloud purger update
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
store_handler/eloq_data_store_service/rocksdb_cloud_data_store.cpp (1)
743-762: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick winRelease
db_whenGetCurrentEpochreturns an empty epoch.When
current_epoch.empty(), this branch resumes background work and returnsfalsewithout closingdb_, deleting it, or settingdb_ = nullptr. BecauseOpenCloudDBopensdb_before this validation, the failed start path leaves a partially initialized database and retained resources; apply the same cleanup as the surrounding failure paths.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@store_handler/eloq_data_store_service/rocksdb_cloud_data_store.cpp` around lines 743 - 762, Update the current_epoch.empty() failure branch in OpenCloudDB to close and delete db_, then set db_ to nullptr before returning false, while preserving the existing ContinueBackgroundWork() call as required.
🧹 Nitpick comments (1)
store_handler/eloq_data_store_service/rocksdb_cloud_data_store.cpp (1)
652-653: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUpdate stale purger comments.
The purger listener and
BlockPurger()call were removed, but Lines 665-666, 729-730, and 766 still describe blocking the purger. Replace those comments with the actual background-work and auto-compaction lifecycle.Proposed comment update
- // Disable auto compactions before blocking purger + // Disable auto compactions during cloud database initialization - // Stop background work - memtable flush and compaction - // before blocking purger + // Pause background work while validating the database epoch - // Enable auto compactions after blocking purger + // Re-enable auto compactions after cloud database initializationAs per coding guidelines, update stale nearby comments and the corresponding
docs/design document when behavior changes.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@store_handler/eloq_data_store_service/rocksdb_cloud_data_store.cpp` around lines 652 - 653, The comments near the RocksDB configuration and related code still describe the removed purger listener and BlockPurger() behavior. Update the stale comments around the affected sections to accurately describe the current background-work and auto-compaction lifecycle, and update the corresponding docs/ design document to match the implemented behavior.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@store_handler/eloq_data_store_service/rocksdb_cloud_data_store.cpp`:
- Around line 743-762: Update the current_epoch.empty() failure branch in
OpenCloudDB to close and delete db_, then set db_ to nullptr before returning
false, while preserving the existing ContinueBackgroundWork() call as required.
---
Nitpick comments:
In `@store_handler/eloq_data_store_service/rocksdb_cloud_data_store.cpp`:
- Around line 652-653: The comments near the RocksDB configuration and related
code still describe the removed purger listener and BlockPurger() behavior.
Update the stale comments around the affected sections to accurately describe
the current background-work and auto-compaction lifecycle, and update the
corresponding docs/ design document to match the implemented behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: f3ee72f5-f39a-4131-a232-8e49108cdb87
📒 Files selected for processing (7)
CMakeLists.txtstore_handler/eloq_data_store_service/CMakeLists.txtstore_handler/eloq_data_store_service/purger_event_listener.cppstore_handler/eloq_data_store_service/purger_event_listener.hstore_handler/eloq_data_store_service/purger_sliding_window.cppstore_handler/eloq_data_store_service/purger_sliding_window.hstore_handler/eloq_data_store_service/rocksdb_cloud_data_store.cpp
💤 Files with no reviewable changes (6)
- store_handler/eloq_data_store_service/purger_event_listener.cpp
- store_handler/eloq_data_store_service/CMakeLists.txt
- store_handler/eloq_data_store_service/purger_sliding_window.h
- store_handler/eloq_data_store_service/purger_event_listener.h
- CMakeLists.txt
- store_handler/eloq_data_store_service/purger_sliding_window.cpp
Problem
eloqkvmain CI is red on all fourELOQDSS_ROCKSDB_CLOUD_S3jobs. The server never starts:The rocksdb-cloud bump in d342a5c (to 8802542, "cloud: fix purger garbage leak and move file-number-guard writer in-repo") added a hard check in
DBCloudImpl::Open(cloud/db_cloud_impl.cc:139): a writable DBCloud whose cloud file deletion is delegated to the purger must setpublish_file_number_guard.RocksDBCloudDataStore::StartDBhardcodesdisable_cloud_file_deletion = trueand defaultsrun_purgertotrue, so the condition always matches and every open fails. The log service is unaffected — it setsrun_purger = false.Fix
Enable the option. It does two things: satisfies the check, and opens the gate at
db_cloud_impl.cc:256that installs the in-repoFileNumberGuardPublisher+FileNumberGuardListener.That publisher is precisely the writer rocksdb-cloud moved in-repo. We already had our own —
PurgerEventListener+SlidingWindow— so this change removes ours rather than running both:SlidingWindowFileNumberSlidingWindowPurgerEventListenerFileNumberGuardListenerS3FileNumberUpdaterFileNumberGuardPublisherBlockPurger()writes 0Both push a listener into the same
options.listenersand PUT to the samesmallest_new_file_number-<epoch>key. Running both would let two publishers land PUTs out of order and reinstate a stale high watermark — the purger would then delete an SST that is still in flight.FileNumberGuardPublisher'spublish_mutex_only serializes PUTs within one publisher.Why the in-repo one supersedes ours
""and patched viaSetEpochafter open.Open.ProtectFileUpload(cloud/cloud_storage_provider.cc:203): the watermark is lowered before the upload proceeds. Ours republished on a timer, leaving a window where an SST was already in S3 but the guard had not come down yet — the purger could delete it. This is one of the leaks the upstream commit fixes.Compatibility
On-cloud protocol is unchanged — same key
<object_path>/smallest_new_file_number-<epoch>, same ASCII uint64 value, same0/UINT64_MAXsentinels. The object is per-epoch and each writer node owns its epoch, so mixed-version nodes on one bucket do not collide.One behavior change comes from the submodule bump itself, not this PR: the purger's
require_guard_markernow defaults totrue, so an epoch with no marker aborts the purge cycle instead of falling back to the MANIFEST high watermark. Effect on an existing bucket is that old markerless epochs stop being collected (storage grows); no data loss.--require_guard_marker=falseis available for a staged rollout.Verification
rocksdb_cloud_data_store.cppcompiles clean (-Wall,-fsyntax-only) against the submodule's rocksdb-cloud headers under-DDATA_STORE_TYPE_ELOQDSS_ROCKSDB_CLOUD_S3./opt/eloq/third_partyprebuilt rocksdb-cloud predates the bump and lacks both the option and the check. CI'sprime-third-partyrebuilds it from the submodule, so the S3 jobs are the real gate.🤖 Generated with Claude Code
Summary by CodeRabbit