Skip to content

fix(fts): chunk posting reads during segment merge - #8668

Merged
BubbleCal merged 1 commit into
mainfrom
yang/fix-fts-merge-offset-overflow
Aug 21, 2026
Merged

fix(fts): chunk posting reads during segment merge#8668
BubbleCal merged 1 commit into
mainfrom
yang/fix-fts-merge-offset-overflow

Conversation

@BubbleCal

@BubbleCal BubbleCal commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

What is the bug?

FTS segment merge materializes every posting row in an invert.lance partition as one Arrow RecordBatch. Large partitions can exceed the i32 child-offset capacity of the posting, impact, or position List columns while Arrow concatenates pages, causing an offset overflow panic after indexing has otherwise completed.

What issues or incorrect behavior does the bug cause?

Large segmented FTS rebuilds can finish tokenization but fail while finalizing intermediate segments. Because the final index segment is never committed, callers cannot complete the rebuild and automated maintenance can encounter the same deterministic failure again.

How does this PR fix the problem?

  • replace the partition-wide posting read in InvertedPartition::into_builder with sequential token-range chunks
  • reuse the existing posting chunk decoder so each batch is released before the next range is read
  • let merge slices share the current chunk Arrow buffers while prewarm retains compact independently-owned buffers
  • bound current shared-position chunks by token count, an approximately 128 MiB on-disk target, and the exact widest List<i32> child count derived from posting metadata
  • read compressed V1 per-document positions one token at a time because their nested position-block child count is not stored in metadata
  • return a descriptive error if one metadata-bounded token alone cannot fit within the configured child-offset limit

The pre-compression row-based legacy layout keeps its existing row-count fallback and is outside this incident scope.

Token ordering, posting contents, position data, impact data, public APIs, and the on-disk format remain unchanged.

Tests

  • cargo test -p lance-index test_into_builder_chunks_postings_by_list_children -- --nocapture
  • cargo test -p lance-index test_chunk_posting_mode_controls_buffer_sharing -- --nocapture
  • cargo test -p lance-index test_prewarm_streams_in_chunks -- --nocapture
  • cargo test -p lance-index test_merge_segments_ -- --nocapture
  • cargo check -p lance-index --tests
  • cargo fmt --all -- --check
  • git diff --check main...HEAD
  • cargo clippy -p lance-index --tests -- -D warnings -A clippy::single-range-in-vec-init -A clippy::implicit-clone

Strict local Clippy on Rust 1.97 currently reports pre-existing single-range-in-vec-init and implicit-clone findings in untouched files; allowing only those two lints makes the changed package pass cleanly.

@github-actions github-actions Bot added A-index Vector index, linalg, tokenizer bug Something isn't working labels Aug 20, 2026
@BubbleCal
BubbleCal force-pushed the yang/fix-fts-merge-offset-overflow branch 2 times, most recently from bbb4d1a to 58c1573 Compare August 21, 2026 04:57
lance-gatekeeper[bot]

This comment was marked as outdated.

@lance-gatekeeper lance-gatekeeper Bot added the K-changes Latest Gatekeeper recommendation requests changes. label Aug 21, 2026
@codecov

codecov Bot commented Aug 21, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Avoid materializing an entire inverted-index partition in one Arrow batch during segment merge. Bound reads by token count, estimated bytes, and List child offsets while preserving V1 and V3 position layouts.
@BubbleCal
BubbleCal force-pushed the yang/fix-fts-merge-offset-overflow branch from 58c1573 to 83265e6 Compare August 21, 2026 05:41
@lance-gatekeeper lance-gatekeeper Bot removed the K-changes Latest Gatekeeper recommendation requests changes. label Aug 21, 2026

@lance-gatekeeper lance-gatekeeper Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Gate recommendation: approve.

The current-format planner retains exact metadata-based batching and buffer sharing, while compressed V1 LegacyPerDoc reads now use the conservative one-token boundary required by their nested-list layout. The focused coverage verifies both paths.

@lance-gatekeeper lance-gatekeeper Bot added the K-approved Latest Gatekeeper recommendation permits acceptance. label Aug 21, 2026
@BubbleCal
BubbleCal merged commit f40f337 into main Aug 21, 2026
41 of 42 checks passed
@BubbleCal
BubbleCal deleted the yang/fix-fts-merge-offset-overflow branch August 21, 2026 06:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-index Vector index, linalg, tokenizer bug Something isn't working K-approved Latest Gatekeeper recommendation permits acceptance.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants