fix(index): resolve frag-reuse index single-flight self-deadlock in open_frag_reuse_index - #42
Open
zehiko wants to merge 2 commits into
Open
fix(index): resolve frag-reuse index single-flight self-deadlock in open_frag_reuse_index#42zehiko wants to merge 2 commits into
zehiko wants to merge 2 commits into
Conversation
…pen_frag_reuse_index
The cache loader passed to index_cache.get_or_insert_with_key on the
frag_reuse/{uuid} key called self.load_index(uuid), which re-enters
load_indices() and performs get_or_insert_with_key on the SAME key.
moka holds the waiter's write lock across the init future, so the
re-entrant call parks against its own guard: a permanent zero-CPU
deadlock that stalls every reader of the dataset.
Use the IndexMetadata already fetched by load_index_by_name instead,
mirroring the safe loader in load_indices(). Guard comments added on
both FRI loader closures. Deterministic regression test included
(zero-capacity index cache forces the poisoned loader path).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…order The lance clippy CI job denies print_stdout even in tests, and rustfmt wants lance_index::IndexType sorted before the lance_index submodule imports. The test's assertions and panic messages carry the signal; the progress prints added nothing. Co-Authored-By: Claude Fable 5 <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.
Port of #41 (release-8.0.0) to release-9.0.0.
Mechanism
DatasetIndexInternalExt::open_frag_reuse_indexpasses a loader closure toindex_cache.get_or_insert_with_key(frag_reuse_key, ...)that callsself.load_index(&frag_reuse_uuid).load_indexrunsload_indices(), which does its ownget_or_insert_with_keyon the samefrag_reuse/{uuid}cache key. moka'soptionally_get_withholds the waiter's write lock across the init future, so the re-entrant inner call parks onread().awaitagainst its own outer write guard: a permanent, zero-CPU self-deadlock. Every subsequent reader of the dataset then parks behind the poisoned key — all reads of the dataset stall indefinitely.Trigger conditions
frag_reuse/{uuid}entry must be absent at the secondget_or_insert_with_key— i.e. evicted in the window between the pre-populate inload_indices()and the probe inopen_frag_reuse_index.Impact
Root cause of the ab-repro-0155 total registration stall on 2026-08-18, and of RR-5448's previously unexplained "second stall mechanism" on ab-repro-new.
Fix
The loader now uses the
IndexMetadataalready fetched byload_index_by_nameat the top of the function and callsload_frag_reuse_index_details+open_frag_reuse_indexdirectly — mirroring the (safe) loader insideload_indices(). Guard comments added on both FRI loader closures: they must never callload_indices/load_index, which re-enter the same cache key.Verification
rust/lance/tests/frag_reuse_deadlock.rs): a zero-capacity index cache forces the poisoned loader path; unfixed = deadlock caught by a 20s tokio timeout, fixed = passes.Upstream
Upstream
lancedb/lancemain carries the same defect (rust/lance/src/index.rs:3003-3005, loader callsself.load_index(...)), as does ourrelease-9.0.0branch (rust/lance/src/index.rs:2494-2496) — this fix should be forward-ported.🤖 Generated with Claude Code