fix(storage): share block cache across instances when share-block-cache is enabled (#143) - #412
Conversation
…he is enabled (#143) The block-cache wiring had an inverted condition: with the default share_block_cache = true, no shared cache was ever created and each RocksDB instance silently fell back to its own isolated (RocksDB-default) cache. This defeated the intent of sharing and wasted memory. Changes: - conf: add the share-block-cache config key (default true) and unit tests covering default / yes / no / invalid values. The new field is also serialized into the sample config automatically via to_redis_style. - options: build the shared Arc<Cache> once in from_config and store it on StorageOptions, so every Redis instance reuses the same cache through the shared Arc<StorageOptions>. - storage(redis): prefer the shared cache; only fall back to a per-instance cache when sharing is disabled and a block_cache_size is configured. Fixes #143
|
Warning Review limit reached
Next review available in: 10 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughChangesShared block cache
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Config
participant StorageOptions
participant ColumnFamilyOptions
participant RocksDB
Config->>StorageOptions: provide share_block_cache and cache size
StorageOptions->>StorageOptions: create shared LRU cache when enabled
StorageOptions->>ColumnFamilyOptions: pass optional block cache
ColumnFamilyOptions->>RocksDB: configure shared or per-instance cache
🚥 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.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/storage/src/options.rs (1)
133-140: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winCopy
share_block_cachefromConfig.Line 140 retains
StorageOptions::default().share_block_cache == true. If the configuration setsshare-block-cache no,block_cacheisNone, butsrc/storage/src/redis.rslines 487-490 skip the per-instance fallback because the flag is stilltrue.Set
share_block_cache: config.share_block_cachein this initializer. Add a regression test forshare-block-cache no.Based on PR objectives, disabled sharing must use a per-instance cache.
🤖 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 `@src/storage/src/options.rs` around lines 133 - 140, Propagate config.share_block_cache into the StorageOptions initializer so the configured sharing mode overrides the default. Add a regression test covering share-block-cache no and verify the resulting Redis/storage path uses a per-instance cache when sharing is disabled.
🤖 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.
Inline comments:
In `@src/storage/src/redis.rs`:
- Around line 477-491: Create the non-shared fallback block cache once in
Redis::open when block_cache_size is positive, then pass that cache to every
create_cf_options call for the Redis instance. Update create_cf_options to
accept and reuse the per-instance cache, removing its per-column-family cache
allocation while preserving shared-cache behavior through
StorageOptions::block_cache.
---
Outside diff comments:
In `@src/storage/src/options.rs`:
- Around line 133-140: Propagate config.share_block_cache into the
StorageOptions initializer so the configured sharing mode overrides the default.
Add a regression test covering share-block-cache no and verify the resulting
Redis/storage path uses a per-instance cache when sharing is disabled.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 266bcaa0-b32b-4953-b885-e08018f9be90
📒 Files selected for processing (4)
src/conf/src/config.rssrc/conf/src/lib.rssrc/storage/src/options.rssrc/storage/src/redis.rs
There was a problem hiding this comment.
🟡 Not ready to approve
StorageOptions::from_config does not propagate config.share_block_cache into StorageOptions, breaking the documented share-block-cache no behavior (no shared cache and no per-instance caches).
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Pull request overview
Fixes the storage block-cache sharing logic and adds configuration support so RocksDB instances can correctly share a single block cache when share-block-cache is enabled (default), aligning behavior with the intended memory-efficiency and cache-hit improvements.
Changes:
- Added
share-block-cacheconfig key (defaultyes) with parsing + unit tests. - Built a shared
Arc<Cache>once inStorageOptions::from_configand plumbed it into per-instance RocksDB table options. - Updated RocksDB table options setup to prefer the shared cache and only create per-instance caches when sharing is disabled.
File summaries
| File | Description |
|---|---|
| src/storage/src/redis.rs | Uses StorageOptions.block_cache when present; otherwise optionally builds a per-instance cache when sharing is disabled. |
| src/storage/src/options.rs | Adds block_cache: Option<Arc<Cache>> and builds the shared cache in from_config. |
| src/conf/src/lib.rs | Updates a test config struct literal to include share_block_cache. |
| src/conf/src/config.rs | Adds share_block_cache field, parsing for share-block-cache, and unit tests for default/yes/no/invalid values. |
Review details
Suppressed comments (1)
src/storage/src/options.rs:140
StorageOptions::from_configcomputesblock_cachebased onconfig.share_block_cache, but it never copiesconfig.share_block_cacheinto the returnedStorageOptions(it relies on..Self::default(), which setsshare_block_cache: true). As a result,share-block-cache nowill produceStorageOptions { share_block_cache: true, block_cache: None }, andRediswill neither use a shared cache nor create per-instance caches (because the per-instance branch is gated by!storage_options.share_block_cache).
block_cache,
small_compaction_threshold: config.small_compaction_threshold,
small_compaction_duration_threshold: config.small_compaction_duration_threshold,
db_instance_num: config.db_instance_num,
..Self::default()
- Files reviewed: 4/4 changed files
- Comments generated: 0
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
Propagate share-block-cache into StorageOptions, allocate one fallback cache per Redis instance instead of per column family, and disable RocksDB's implicit cache when the configured size is zero. Preserve the active StorageOptions and shared cache across Raft snapshot hot-swaps. Keep the public cache setters consistent with the derived cache handle and make the default options use one shared cache. Constraint: Limit this follow-up to PR #412 block-cache semantics, snapshot lifecycle preservation, and directly related regression tests. Confidence: High; red-green tests cover config propagation, shared/per-instance cache identity, zero-capacity behavior against real RocksDB, and snapshot cache identity. Scope-risk: Storage option construction, Redis CF cache wiring, and snapshot reopen only. Tested: WSL workspace build; workspace cargo test; storage lib 231/231 with fault injection; snapshot roundtrip 12/12; CI-equivalent workspace all-features Clippy; cargo fmt --check; staged diff check. Co-authored-by: OmX <omx@oh-my-codex.dev> Signed-off-by: Xin.Zh <alexstocks@foxmail.com>
Move the block-cache regression module away from the lifecycle-test attribute changed by current main, and carry the same Clippy allowance on the existing lifecycle module. This removes the textual conflict without changing cache behavior. Constraint: Limit this follow-up to the current-main conflict in src/storage/src/redis.rs. Confidence: High; the exact synthetic merge with main passed cache tests, snapshot roundtrip tests, formatting, and workspace Clippy. Scope-risk: Test-module placement and an attribute already present on main only. Tested: exact main merge-tree; merged block-cache tests 3/3; merged snapshot roundtrip 12/12; merged make lint; cargo fmt --check; staged diff check. Co-authored-by: OmX <omx@oh-my-codex.dev> Signed-off-by: Xin.Zh <alexstocks@foxmail.com>
* fix(planning): pin WP0 validation to immutable merge evidence PR #414 was squash-merged after PR #412, so comparing the original SDD baseline with the moving main branch made the WP0 artifact gate absorb unrelated storage and Raft paths. Record immutable PR and squash-merge evidence, keep WP0 at implemented while exact-main verification is pending, and validate the historical merge-parent diff independently of the current work package. Add regression coverage for concurrent merges, invalid refs, ancestry, and premature lifecycle promotion. Constraint: Keep WP1 and Issue #415 blocked until WP0 has passed exact-main evidence. Confidence: high Scope-risk: narrow Tested: Windows and Ubuntu WSL SDD self-test, validator, Python compile, and git diff checks. Not-tested: GitHub Actions on the pushed Head. Co-authored-by: OmX <omx@oh-my-codex.dev> Signed-off-by: Xin.Zh <alexstocks@foxmail.com> * fix(planning): bind WP0 evidence projections Keep the human-readable WP0 ranges, exact-main status, and current-state table synchronized with the sole machine-readable front matter. Reject duplicate or conflicting projections and stale Issue tracking. Require a passed exact-main ref to exist after the WP0 merge and within the recorded baseline main history, while avoiding misleading ancestry errors when merge objects are unavailable. Add regressions for unrelated verification refs and conflicting evidence lines. Constraint: Preserve offline validation without requiring the squash-merged PR Head object. Confidence: high Scope-risk: narrow Tested: Windows and Ubuntu WSL SDD self-test, validator, and git diff checks. Not-tested: GitHub Actions on this new Head. Co-authored-by: OmX <omx@oh-my-codex.dev> Signed-off-by: Xin.Zh <alexstocks@foxmail.com> * fix(planning): harden WP0 verification evidence Pin the immutable PR #414 identity even when its Head object is unavailable, and require passed exact-main evidence to reference a successful ci workflow push on main for the exact recorded SHA. Reject the WP0 merge commit itself as verification evidence. Make lifecycle mutations state-independent and run the immutable-Head and live-run regressions through the public validator entry point so a future wiring regression fails --self-test. Constraint: Keep WP0 implemented and exact-main verification pending; change only SDD governance and validator behavior under Issue #416. Confidence: high Scope-risk: narrow Tested: Windows and Ubuntu WSL external regressions, validator self-tests, main validator, Python compile, working and staged diff checks. Not-tested: Fresh GitHub Actions on the pushed Head. Related: #416 Co-authored-by: OmX <omx@oh-my-codex.dev> Signed-off-by: Xin.Zh <alexstocks@foxmail.com> * fix(planning): keep WP0 promotion reachable Document that exact-main promotion must advance baseline_ref with the accepted verification commit. Exercise both the rejected stale-baseline path and the accepted advanced-baseline path against real Git history. Refs: #416 Co-authored-by: OmX <omx@oh-my-codex.dev> Signed-off-by: Xin.Zh <alexstocks@foxmail.com> --------- Signed-off-by: Xin.Zh <alexstocks@foxmail.com> Co-authored-by: OmX <omx@oh-my-codex.dev>
The WP0 artifact gate compared the working-tree diff against the WP0 baseline with the WP0 artifact registry. WP0 shipped in arana-db#414, so any later commit on main (e.g. arana-db#412) and any feature branch failed the planning SDD validation job; main itself was red. Remove the gate together with the now-dead git_changed_paths helper and the check_git_diff plumbing. All remaining validation (25 self-test mutations, lifecycle transition, prose guard) is unchanged and still passes.
Summary
Fixes #143 — the block-cache sharing was effectively dead code due to an inverted condition.
With the default
share_block_cache = true, the old code did not create any shared cache:so every RocksDB instance silently fell back to its own isolated (RocksDB-default) cache. This defeated the intent of sharing and wasted memory.
Changes
config.rs): add theshare-block-cacheconfig key (defaulttrue) plus unit tests covering default /yes/no/ invalid values. The new field is also serialized into the sample config automatically viato_redis_style.options.rs): build the sharedArc<Cache>once inStorageOptions::from_configand store it onStorageOptions, so everyRedisinstance reuses the same cache through the sharedArc<StorageOptions>.redis.rs): prefer the shared cache; only fall back to a per-instance cache when sharing is disabled and ablock_cache_sizeis configured.Behavior
share-block-cache yes(default): one cache ofmemorybytes is built once and shared across all instances/CFs.share-block-cache no: each instance builds its own independent cache ofblock_cache_sizebytes.StorageOptions::default()keepsblock_cache: None, so existing unit tests are unaffected.Test plan
cargo test -p conf— 30 passed (incl. 3 newshare-block-cacheparse tests)cargo check -p storage --tests --features test-fault-injection— cleancargo clippy -p conf -p storage --tests --features test-fault-injection— no new warnings from changed filesFixes #143
Summary by CodeRabbit
New Features
yesandnovalues, with validation for invalid settings.Performance