fix(mem-wal): reject mismatched shard specs before epoch claim - #7949
fix(mem-wal): reject mismatched shard specs before epoch claim#7949u70b3 wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthrough
ChangesShard claim validation
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 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.
Note
Quiet mode is enabled, so only the most important comments were posted inline. Other review comments are grouped below.
🟡 Other comments (1)
rust/lance/src/dataset/mem_wal/manifest.rs-445-447 (1)
445-447: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick winDocument sealed-manifest refusal in
# Errors.
claim_epochnow returns an error for sealed manifests, but this public API’s error contract only documents epoch conflicts, shard-spec conflicts, and contention. Document the sealed refusal and its no-claim effect. As per coding guidelines, “Ensure doc comments match actual semantics; distinguish mutates-in-place (&mut self) from returns-new-value behavior.”🤖 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 `@rust/lance/src/dataset/mem_wal/manifest.rs` around lines 445 - 447, Update the public `claim_epoch` documentation comment’s `# Errors` section to include refusal for sealed manifests and state that this path makes no claim or mutation. Keep the existing documentation for epoch conflicts, shard-spec conflicts, and contention, and accurately describe the method’s in-place `&mut self` 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.
Other comments:
In `@rust/lance/src/dataset/mem_wal/manifest.rs`:
- Around line 445-447: Update the public `claim_epoch` documentation comment’s
`# Errors` section to include refusal for sealed manifests and state that this
path makes no claim or mutation. Keep the existing documentation for epoch
conflicts, shard-spec conflicts, and contention, and accurately describe the
method’s in-place `&mut self` behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: QUIET
Plan: Pro Plus
Run ID: eddae87c-eea7-4d35-949b-1203ad196d84
📒 Files selected for processing (1)
rust/lance/src/dataset/mem_wal/manifest.rs
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
hamersaw
left a comment
There was a problem hiding this comment.
I think this change has the right intent, but will not fix underlying issues correctly. It's meant to disallow claiming a table with a different shard_spec_id than the base table. However, Lance currently only uses 0 and 1 as valid values to not manual and automatic sharding configuration. IMO this is part of a larger discussion, we should update the shard spec configuration so that IDs are monotonically increasing. That would make this change valid.
|
Thanks, I think I understand the concern. The manifest-side equality check is only meaningful if every distinct sharding-spec revision has a unique ID. Today the public initialization path assigns It sounds like the prerequisites are:
Would you prefer that I expand this PR to implement the spec-ID lifecycle, or split the monotonic allocation/base-table validation into a prerequisite PR and rebase this change on it? |
6151ec2 to
8a49ce1
Compare
|
Following up on my previous comment: I split the prerequisite work into #8112. #8112 introduces monotonic spec-ID allocation ( The current initializer only creates the first spec, so an empty history produces spec ID Once #8112 lands, I'll rebase #7949 on top of it. #7949 will remain focused on claim-time manifest validation. |
8a49ce1 to
812fe55
Compare
The proto contract promises sharding spec ids are never reused, but the public init path hardcoded id 1 for every automatic sharding configuration, leaving distinct specs indistinguishable at shard-claim time. - add next_spec_id(): greatest id + 1, with 0 reserved as the manual-shard sentinel (MANUAL_SHARD_SPEC_ID) - reject reserved/duplicate spec ids when decoding MemWalIndexDetails - add MemWalIndexDetails::active_sharding_spec() (greatest id) - mem_wal_writer resolves an unset (0) shard_spec_id to the active spec and rejects an explicit mismatch before any shard claim Prerequisite for lance-format#7949.
812fe55 to
0f7bd7f
Compare
The proto contract promises sharding spec ids are never reused, but the public init path hardcoded id 1 for every automatic sharding configuration, leaving distinct specs indistinguishable at shard-claim time. - add next_spec_id(): greatest id + 1, with 0 reserved as the manual-shard sentinel (MANUAL_SHARD_SPEC_ID) - reject reserved/duplicate spec ids when decoding MemWalIndexDetails - add MemWalIndexDetails::active_sharding_spec() (greatest id) - mem_wal_writer resolves an unset (0) shard_spec_id to the active spec and rejects an explicit mismatch before any shard claim Prerequisite for lance-format#7949.
The proto contract promises sharding spec ids are never reused, but the public init path hardcoded id 1 for every automatic sharding configuration, leaving distinct specs indistinguishable at shard-claim time. - add next_spec_id(): greatest id + 1, with 0 reserved as the manual-shard sentinel (MANUAL_SHARD_SPEC_ID) - reject reserved/duplicate spec ids when decoding MemWalIndexDetails - add MemWalIndexDetails::active_sharding_spec() (greatest id) - mem_wal_writer resolves an unset (0) shard_spec_id to the active spec and rejects an explicit mismatch before any shard claim Prerequisite for lance-format#7949.
0f7bd7f to
dc95ea2
Compare
The proto contract promises sharding spec ids are never reused, but the public init path hardcoded id 1 for every automatic sharding configuration, leaving distinct specs indistinguishable at shard-claim time. - add next_spec_id(): greatest id + 1, with 0 reserved as the manual-shard sentinel (MANUAL_SHARD_SPEC_ID) - reject reserved/duplicate spec ids when decoding MemWalIndexDetails - add MemWalIndexDetails::active_sharding_spec() (greatest id) - mem_wal_writer resolves an unset (0) shard_spec_id to the active spec and rejects an explicit mismatch before any shard claim Prerequisite for lance-format#7949.
The proto contract promises sharding spec ids are never reused, but the public init path hardcoded id 1 for every automatic sharding configuration, leaving distinct specs indistinguishable at shard-claim time. - add next_spec_id(): greatest id + 1, with 0 reserved as the manual-shard sentinel (MANUAL_SHARD_SPEC_ID) - reject reserved/duplicate spec ids when decoding MemWalIndexDetails - add MemWalIndexDetails::active_sharding_spec() (greatest id) - mem_wal_writer resolves an unset (0) shard_spec_id to the active spec and rejects an explicit mismatch before any shard claim Prerequisite for lance-format#7949.
Summary
shard_spec_idmismatches before advancing a shardmanifest version or writer epoch
distinguishable sealed-shard error
rejection, and concurrent claims with different specs
Depends on #8112, which establishes unique monotonic sharding-spec IDs and resolves the writer's active table spec before claim.
flowchart TD A["Read latest manifest"] B{"Sealed?"} C{"Spec identity matches?"} D["Return sealed error"] E["Return InvalidInput<br/>manifest unchanged"] F["Write next version / epoch"] G{"Write conflict?"} A --> B B -- Yes --> D B -- No --> C C -- No --> E C -- Yes --> F F --> G G -- Yes --> Ashard_spec_id=0remains the immutable identity for manually created shards;it is not treated as a wildcard.
Fixes #7945.
Test Plan
cargo fmt --all -- --checkcargo test -p lance dataset::mem_wal::manifest::tests --lib -- --nocapturecargo clippy --all --tests --benches -- -D warnings