Skip to content

[core][flink][spark] Refresh data evolution vector indexes incrementally#8818

Draft
leaves12138 wants to merge 1 commit into
apache:masterfrom
leaves12138:codex/de-vector-index-refresh
Draft

[core][flink][spark] Refresh data evolution vector indexes incrementally#8818
leaves12138 wants to merge 1 commit into
apache:masterfrom
leaves12138:codex/de-vector-index-refresh

Conversation

@leaves12138

@leaves12138 leaves12138 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Purpose

Data-evolution append tables can partially update an indexed vector column, for example by filling an embedding from NULL to a value. Incremental global-index builds previously considered only uncovered row ranges, so an existing vector index could remain readable but permanently miss those updated vectors unless users performed a full rebuild.

This change refreshes only affected logical vector-index ranges while keeping the old index active until its replacement is ready.

Changes

  • Store the data snapshot scanned by every generic global-index build as scanSnapshotId in GlobalIndexMeta.sourceMeta, encoded with a DEIX magic number and version. Source metadata is recorded unconditionally once the build has a scan snapshot, independent of scalar/vector index type.
  • Keep source tracking separate from automatic refresh: scalar indexes record the watermark but retain their existing build behavior; only supported vectors on data-evolution tables enter the refresh planner.
  • Deliberately record the scan snapshot rather than the later index-commit snapshot, so data updates committed while an index build is running remain newer than the recorded watermark and are picked up by the next build.
  • Select an existing vector-index range for refresh when an active data file intersects its row range, physically contains an indexed field resolved by stable field ID, and has maxSequenceNumber newer than scanSnapshotId.
  • Refresh legacy vector indexes without this metadata once.
  • Merge refreshed ranges with newly uncovered ranges in the Flink and Spark builders.
  • Commit old-index deletion and replacement-index addition atomically.
  • Detect concurrent replacements by requiring the expected old index file to remain active and by preventing an older scan generation from replacing a newer one.
  • Require a non-null scan snapshot whenever a generic Flink index build produces work.

User impact

Users can continuously populate embedding columns and run incremental index builds. Search continues using the previous complete index during construction, then switches atomically to the more complete replacement without an index-unavailable window. Scalar generic indexes also carry the scan watermark for future type-specific handling, without changing their refresh behavior.

Tests

  • Core data-evolution metadata, planner, manifest, and conflict-detection suites passed.
  • Flink generic topology and scalar full-text suites: 34 passed.
  • Spark scalar full-text suite: 7 passed.
  • Spark Lumina native suite on Linux: 10 passed.
  • Downstream Morax topology and vector suites on Linux: 35 passed, 1 existing platform-assumption skip.
  • Spotless and git diff --check passed.

@leaves12138
leaves12138 force-pushed the codex/de-vector-index-refresh branch from fc35361 to d756da5 Compare July 23, 2026 12:57
@leaves12138
leaves12138 force-pushed the codex/de-vector-index-refresh branch from d756da5 to 86c6eb8 Compare July 23, 2026 14:29
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.

1 participant