Skip to content

feat(vindex): build indexes from streamed data splits - #707

Merged
jerry-024 merged 3 commits into
apache:mainfrom
jerry-024:feat/vector-index-data-split-build
Aug 13, 2026
Merged

feat(vindex): build indexes from streamed data splits#707
jerry-024 merged 3 commits into
apache:mainfrom
jerry-024:feat/vector-index-data-split-build

Conversation

@jerry-024

@jerry-024 jerry-024 commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Purpose

The previous vindex builder collected every Arrow batch and then flattened all vectors into another contiguous buffer. For a 10M x 768 float32 shard, those two full-size copies alone could exceed 57 GiB before index training started.

This change builds each vindex shard from a single streamed DataSplit, keeping builder-owned memory bounded while preserving one index file per shard.

Brief change log

  • Stream Arrow record batches once, validating vector shape, nulls, sliced-array offsets, and contiguous row IDs batch by batch.
  • Spill validated raw vectors to one anonymous local temporary file while incrementally feeding the trainer.
  • Add Java-compatible <index-type>.train.sample-ratio and field-level overrides; the ratio affects training only and every row is still indexed.
  • After training, read the spill file through a bounded aligned buffer and add vectors in chunks.
  • Stream the completed index directly to FileIO without a full serialized Vec<u8> or a second local temporary file.
  • Best-effort delete visible output objects on failures, including outputs from earlier shards through TableCommit::abort.

Tests

  • RUSTC_BOOTSTRAP=1 RUSTFLAGS='-Zcrate-attr=feature(stdarch_neon_f16)' cargo test -p paimon --lib vindex
  • RUSTC_BOOTSTRAP=1 RUSTFLAGS='-Zcrate-attr=feature(stdarch_neon_f16)' cargo check -p paimon --lib --features fulltext
  • Covers option precedence and invalid training ratios.
  • Covers sliced List and FixedSizeList Arrow arrays.
  • Covers multiple source batches, incremental builds, one file per shard, and cleanup when a later shard fails.

API and Format

Adds the optional vindex build setting <index-type>.train.sample-ratio, defaulting to 1.0 with valid range (0, 1]. There is no index storage-format change; each logical shard still produces one existing-format index file.

Documentation

The SQL documentation now describes train.sample-ratio, its valid range, and that all rows remain indexed.

Notes

IVF-Flat core still retains raw vector state and creates per-list serialization copies. Chunked IVF-Flat serialization is intentionally deferred to a separate paimon-vindex-core change.

The current FileIO async-writer wrapper cannot explicitly abort an unfinished multipart upload. Failed builds delete visible objects best-effort; object-store lifecycle rules should reclaim invisible abandoned multipart uploads.

@jerry-024 jerry-024 changed the title feat(vindex): stream data split index builds feat(vindex): build indexes from streamed data splits Aug 13, 2026
tokio::task::spawn_blocking(move || -> std::io::Result<()> {
let mut writer = writer;
writer.write(&mut PosWriter::new(&mut output))?;
output.shutdown()

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.

Suggestion: Since a running spawn_blocking task cannot be aborted, cancelling the outer build future may still allow this worker to finish output.shutdown() after the surrounding cleanup path has been dropped. The resulting index file would not be referenced by any commit message or manifest.

If orphan index files are already covered by a separate cleanup mechanism, could we document or test that assumption here? Otherwise, it may be worth keeping a provisional output guard or another cleanup mechanism until the file is transferred into a CommitMessage.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch. I think this should be handled by orphan-file cleanup rather than adding cancellation-specific ownership logic to the index builder. A guard here would still not cover equivalent leaks caused by process/runtime shutdown, while orphan cleanup can consistently remove any unreferenced index files after the retention window. I will address the gap in the orphan cleanup path instead.

@QuakeWang QuakeWang left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@jerry-024
jerry-024 merged commit 9f9739a into apache:main Aug 13, 2026
13 checks passed
@jerry-024
jerry-024 deleted the feat/vector-index-data-split-build branch August 13, 2026 09:45
jerry-024 added a commit to jerry-024/paimon-rust that referenced this pull request Aug 14, 2026
…timing

* upstream/main:
  fix(vindex): avoid full index reads during refine (apache#708)
  feat(vindex): build indexes from streamed data splits (apache#707)
  feat: support deletion vector merge-on-read (apache#706)

# Conflicts:
#	crates/paimon/src/table/vector_search_builder.rs
#	crates/paimon/src/vindex/mod.rs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants