Skip to content

Clean up stale star-tree index leftover from killed prior build - #19331

Merged
Jackie-Jiang merged 1 commit into
apache:masterfrom
deepthi912:fix/startree-stale-index-cleanup
Aug 23, 2026
Merged

Clean up stale star-tree index leftover from killed prior build#19331
Jackie-Jiang merged 1 commit into
apache:masterfrom
deepthi912:fix/startree-stale-index-cleanup

Conversation

@deepthi912

@deepthi912 deepthi912 commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Problem

MultipleTreesBuilder.build() opens StarTreeIndexCombiner, which requires star_tree_index to not already exist (StarTreeIndexCombiner.java:47).

If a previous build is hard-killed (JVM crash, container OOM, thread interrupt) after the combiner opens but before the metadata save at line 265, star_tree_index is left on disk while segment metadata has no STAR_TREE_COUNT. Every subsequent preprocess on that segment throws IllegalStateException: Star-tree index file already exists — not self-healing.

2026/08/20 10:15:55.134 INFO [org.apache.pinot.segment.local.startree.v2.builder.MultipleTreesBuilder] [st-state-transition-default-690] Starting building 1 star-trees with configs: [StarTreeV2BuilderConfig[splitOrder=[businessdate, firmaccountmnemonic, productidsubtype],skipStarNodeCreation=[],aggregationSpecs={count__*=AggregationSpec[compressionCodec=PASS_THROUGH,deriveNumDocsPerChunk=false,indexVersion=4,targetMaxChunkSizeBytes=1048576,targetDocsPerChunk=1000,functionParameters={}], sum__cr01=AggregationSpec[compressionCodec=PASS_THROUGH,deriveNumDocsPerChunk=false,indexVersion=4,targetMaxChunkSizeBytes=1048576,targetDocsPerChunk=1000,functionParameters={}], sum__cr10=AggregationSpec[compressionCodec=PASS_THROUGH,deriveNumDocsPerChunk=false,indexVersion=4,targetMaxChunkSizeBytes=1048576,targetDocsPerChunk=1000,functionParameters={}], sum__jumptodefault=AggregationSpec[compressionCodec=PASS_THROUGH,deriveNumDocsPerChunk=false,indexVersion=4,targetMaxChunkSizeBytes=1048576,targetDocsPerChunk=1000,functionParameters={}]},maxLeafRecords=1]] using OFF_HEAP builder
2026/08/20 10:15:55.136 ERROR [org.apache.pinot.segment.local.segment.index.loader.SegmentPreProcessor] [st-state-transition-default-690] Failed to build star-tree index for table: Position_OFFLINE, skipping
java.lang.IllegalStateException: Star-tree index file already exists
	at org.apache.pinot.shaded.com.google.common.base.Preconditions.checkState(Preconditions.java:513)
	at org.apache.pinot.segment.local.startree.v2.builder.StarTreeIndexCombiner.<init>(StarTreeIndexCombiner.java:47)
	at org.apache.pinot.segment.local.startree.v2.builder.MultipleTreesBuilder.build(MultipleTreesBuilder.java:225)
	at org.apache.pinot.segment.local.segment.index.loader.SegmentPreProcessor.processStarTrees(SegmentPreProcessor.java:406)
	at org.apache.pinot.segment.local.segment.index.loader.SegmentPreProcessor.process(SegmentPreProcessor.java:176)
	at org.apache.pinot.segment.local.indexsegment.immutable.ImmutableSegmentLoader.preprocessSegment(ImmutableSegmentLoader.java:321)
	at org.apache.pinot.segment.local.indexsegment.immutable.ImmutableSegmentLoader.preprocess(ImmutableSegmentLoader.java:169)
	at org.apache.pinot.core.data.manager.BaseTableDataManager.tryLoadExistingSegmentWithoutRegistering(BaseTableDataManager.java:1632)
	at org.apache.pinot.core.data.manager.BaseTableDataManager.tryLoadExistingSegment(BaseTableDataManager.java:1563)
	at org.apache.pinot.core.data.manager.BaseTableDataManager.addNewOnlineSegment(BaseTableDataManager.java:461)
	at org.apache.pinot.core.data.manager.offline.OfflineTableDataManager.doAddOnlineSegment(OfflineTableDataManager.java:79)
	at ai.startree.pinot.data.tier.table.StarTreeOfflineTableDataManager.lambda$doAddOnlineSegment$0(StarTreeOfflineTableDataManager.java:174)
	at ai.startree.pinot.data.tier.table.segmentgroup.SegmentGroupTableDataManager.doAddOnlineSegment(SegmentGroupTableDataManager.java:244)
	at ai.startree.pinot.data.tier.table.StarTreeOfflineTableDataManager.doAddOnlineSegment(StarTreeOfflineTableDataManager.java:174)
	at org.apache.pinot.core.data.manager.BaseTableDataManager.addOnlineSegment(BaseTableDataManager.java:401)
	at org.apache.pinot.server.starter.helix.HelixInstanceDataManager.addOnlineSegment(HelixInstanceDataManager.java:331)
	at org.apache.pinot.server.starter.helix.SegmentOnlineOfflineStateModelFactory$SegmentOnlineOfflineStateModel.onBecomeOnlineFromOffline(SegmentOnlineOfflineStateModelFactory.java:170)
	at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
	at java.base/java.lang.reflect.Method.invoke(Method.java:580)
	at org.apache.helix.messaging.handling.HelixStateTransitionHandler.invoke(HelixStateTransitionHandler.java:351)
	at org.apache.helix.messaging.handling.HelixStateTransitionHandler.handleMessage(HelixStateTransitionHandler.java:279)
	at org.apache.helix.messaging.handling.HelixTask.call(HelixTask.java:97)
	at org.apache.helix.messaging.handling.HelixTask.call(HelixTask.java:49)
	at org.apache.pinot.core.data.manager.SegmentOperationsTaskContext.lambda$wrap$1(SegmentOperationsTaskContext.java:70)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
	at java.base/java.lang.Thread.run(Thread.java:1583)

Fix

Before opening the combiner, if _separator == null (no matching star-tree in metadata → any on-disk artifact is orphaned), delete star_tree_index, star_tree_index_map, and any lingering EXISTING_STAR_TREE_TEMP_DIR. The incremental path (_separator != null) is untouched.

Tests

MultipleTreesBuilderStaleCleanupTest — both fail without the fix.

@codecov-commenter

codecov-commenter commented Aug 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.50000% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 67.06%. Comparing base (3c92923) to head (7320a7a).
⚠️ Report is 4 commits behind head on master.

Files with missing lines Patch % Lines
...ocal/startree/v2/builder/MultipleTreesBuilder.java 87.50% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master   #19331      +/-   ##
============================================
+ Coverage     66.97%   67.06%   +0.08%     
  Complexity     1424     1424              
============================================
  Files          3463     3467       +4     
  Lines        222078   222329     +251     
  Branches      34957    34996      +39     
============================================
+ Hits         148743   149103     +360     
+ Misses        61467    61318     -149     
- Partials      11868    11908      +40     
Flag Coverage Δ
integration 100.00% <ø> (ø)
integration1 100.00% <ø> (ø)
integration2 0.00% <ø> (ø)
java-25 67.06% <87.50%> (+0.08%) ⬆️
lane-a 100.00% <ø> (ø)
lane-b 0.00% <ø> (ø)
temurin 67.06% <87.50%> (+0.08%) ⬆️
unittests 67.06% <87.50%> (+0.08%) ⬆️
unittests1 57.83% <25.00%> (+0.14%) ⬆️
unittests2 38.83% <87.50%> (-0.05%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Jackie-Jiang Jackie-Jiang added bug Something is not working as expected index Related to indexing (general) labels Aug 21, 2026

@Jackie-Jiang Jackie-Jiang 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.

Just minor comments

@deepthi912
deepthi912 force-pushed the fix/startree-stale-index-cleanup branch from b74de8d to b90d348 Compare August 22, 2026 21:30
@deepthi912 deepthi912 added the star-tree index Related to StarTree index label Aug 22, 2026
MultipleTreesBuilder.build() opens StarTreeIndexCombiner which requires the target
star_tree_index file to NOT exist (StarTreeIndexCombiner:47). A previous build that was
hard-killed (JVM crash, container OOM, thread hard-interrupt) can leave a partial
star_tree_index at the segment root without a matching STAR_TREE_COUNT in segment metadata,
because the metadata save at line 265 runs only after all trees complete. The catch block
at line 249-262 cleans up on Java exceptions but never runs on process kill.

On the next preprocess, segment metadata says "no star-tree" so `_separator == null`, the
incremental move-aside step is skipped, and the combiner opens on the leftover file, hitting
the checkState. The failure is not self-healing: the leftover keeps blocking every retry.

Fix: when `_separator == null` (fresh build, no matching metadata), delete any stale
star_tree_index / star_tree_index_map / EXISTING_STAR_TREE_TEMP_DIR before opening the
combiner. Metadata is authoritative — with `_separator == null`, any on-disk star-tree
artifact is orphaned. Log at WARN so operators see the recovery. The incremental path
(`_separator != null`) is untouched.

Adds MultipleTreesBuilderStaleCleanupTest covering:
- stale star_tree_index at segment root -> cleaned up + fresh tree built
- stale EXISTING_STAR_TREE_TEMP_DIR -> cleaned up + fresh tree built
@deepthi912
deepthi912 force-pushed the fix/startree-stale-index-cleanup branch from b90d348 to 7320a7a Compare August 22, 2026 21:40
@Jackie-Jiang
Jackie-Jiang merged commit b18c96d into apache:master Aug 23, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something is not working as expected index Related to indexing (general) star-tree index Related to StarTree index

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants