Skip to content

Auto force-commit partial OFFLINE consuming segments - #19083

Open
Vamsi-klu wants to merge 1 commit into
apache:masterfrom
Vamsi-klu:fix/15897-auto-repair-partial-offline-consuming
Open

Auto force-commit partial OFFLINE consuming segments#19083
Vamsi-klu wants to merge 1 commit into
apache:masterfrom
Vamsi-klu:fix/15897-auto-repair-partial-offline-consuming

Conversation

@Vamsi-klu

Copy link
Copy Markdown
Contributor

Why

When a server hits fatal consumption errors it marks its replica OFFLINE in IdealState. RSVM already recreates a consuming segment when all replicas are OFFLINE, but partial OFFLINE (common after transient stream blips) was left alone. Queries then fan in to the remaining CONSUMING replicas indefinitely — imbalance and partial-result risk.

There is a separate flag that only flips OFFLINE→CONSUMING (#11314 path). This PR implements the issue’s requested approach: partition-scoped force-commit when enough progress is likely, behind an opt-in config.

Impact

  • Heals chronic under-replication of consuming segments without manual force-commit.
  • Rebalances sealed data onto a new CONSUMING generation for all replicas.
  • Safe by default: feature flag off; age gate avoids force-committing brand-new empty segments; once-per-segment tracking avoids RSVM storms; reuses validateForceCommitAllowed (partial upsert / drop-OOO guards).
  • New meters: success / failed / skipped auto force-commit.

How

  • Config:
    • controller.realtime.segment.autoForceCommitOnPartialOfflineEnabled (default false)
    • controller.realtime.segment.autoForceCommitOnPartialOfflineMinAgeMs (default 5 minutes)
  • In ensureAllPartitionsConsuming, when IdealState shows mixed CONSUMING+OFFLINE for an IN_PROGRESS segment and age gate passes, call existing partition-scoped forceCommit.
  • Do not combine with OFFLINE→CONSUMING repair in the same tick when force-commit fires.

Test plan

  • PinotLLCRealtimeSegmentManagerTest: force-commit when partial OFFLINE + age ok; age gate skip; all-OFFLINE still recreates; paused table skip; validateForceCommit failure skip.
  • ./mvnw -pl pinot-controller -am -Dtest=PinotLLCRealtimeSegmentManagerTest -Dsurefire.failIfNoSpecifiedTests=false test
  • Staging: enable flag on a non-prod realtime table, mark one replica OFFLINE after the segment is aged, confirm force-commit + new CONSUMING.

Related

fixes: #15897

Reviewers

Suggested: sajjad-moradi (issue author), maintainers of LLC realtime

Config / release notes

New controller configs (default off) — consider release-notes label.


Was generative AI tooling used to co-author this PR?
  • Yes — Grok Build (xAI)

Generated-by: Grok Build (xAI)

When only some replicas of a consuming segment go OFFLINE after stream blips,
queries fan in to the remaining replicas indefinitely. Optionally detect mixed
CONSUMING+OFFLINE IdealState and force-commit the partition once the segment
is old enough, reusing the existing force-commit path behind a config flag.
@codecov-commenter

codecov-commenter commented Jul 25, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 74.24242% with 17 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.49%. Comparing base (2bcbdfe) to head (5eb27dd).

Files with missing lines Patch % Lines
.../core/realtime/PinotLLCRealtimeSegmentManager.java 72.13% 11 Missing and 6 partials ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master   #19083      +/-   ##
============================================
+ Coverage     65.47%   65.49%   +0.02%     
+ Complexity     1421     1415       -6     
============================================
  Files          3426     3426              
  Lines        217315   217374      +59     
  Branches      34509    34517       +8     
============================================
+ Hits         142283   142369      +86     
+ Misses        63513    63491      -22     
+ Partials      11519    11514       -5     
Flag Coverage Δ
custom-integration1 ?
integration ?
integration1 ?
integration2 ?
java-25 65.49% <74.24%> (+0.02%) ⬆️
temurin 65.49% <74.24%> (+0.02%) ⬆️
unittests 65.49% <74.24%> (+0.02%) ⬆️
unittests1 56.85% <100.00%> (+0.02%) ⬆️
unittests2 37.89% <74.24%> (+0.01%) ⬆️

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.

@Vamsi-klu

Copy link
Copy Markdown
Contributor Author

Ready for review — all required CI checks are green on this PR.

Issue: #15897

Could the following folks take a look when convenient?
@Jackie-Jiang
@sajjad-moradi

Formal GitHub "Request review" is unavailable from a fork contributor account on apache/pinot (API returns 404/403), so this is the review ping.

Thank you!

@Jackie-Jiang
Jackie-Jiang requested a review from Copilot July 28, 2026 21:17
@Jackie-Jiang Jackie-Jiang added release-notes Referenced by PRs that need attention when compiling the next release notes configuration Config changes (addition/deletion/change in behavior) ingestion Related to data ingestion pipeline feature New functionality real-time Related to realtime table ingestion and serving labels Jul 28, 2026
@Jackie-Jiang

Copy link
Copy Markdown
Contributor

cc @swaminathanmanish @noob-se7en

Copilot AI 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.

Pull request overview

Adds an opt-in controller-side repair path for LLC realtime partitions where the latest consuming segment is IN_PROGRESS but IdealState shows a mix of CONSUMING + OFFLINE replicas, by triggering a partition-scoped force-commit (age-gated and tracked at-most-once per segment per controller-leader lifetime) and emitting new controller meters.

Changes:

  • Add controller.realtime.segment.autoForceCommitOnPartialOfflineEnabled (default false) and controller.realtime.segment.autoForceCommitOnPartialOfflineMinAgeMs (default 300_000) to gate the new behavior.
  • Implement partial-OFFLINE auto force-commit logic in ensureAllPartitionsConsuming, including pruning/bounding of “already requested” tracking.
  • Add controller meters and unit tests covering success, age-gate skip, all-OFFLINE recreate path, paused-table skip, and validateForceCommit failure handling.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
pinot-controller/src/main/java/org/apache/pinot/controller/helix/core/realtime/PinotLLCRealtimeSegmentManager.java Implements auto force-commit on partial OFFLINE consuming replicas (feature-flagged), adds tracking + pruning, and avoids combining with OFFLINE→CONSUMING flip in the same tick.
pinot-controller/src/main/java/org/apache/pinot/controller/ControllerConf.java Introduces new controller periodic-task config keys + accessors with safe defaults (feature off by default).
pinot-common/src/main/java/org/apache/pinot/common/metrics/ControllerMeter.java Adds meters for auto force-commit success/failed/skipped.
pinot-controller/src/test/java/org/apache/pinot/controller/helix/core/realtime/PinotLLCRealtimeSegmentManagerTest.java Adds test coverage for partial-OFFLINE auto force-commit behavior and gating.
Comments suppressed due to low confidence (5)

pinot-controller/src/test/java/org/apache/pinot/controller/helix/core/realtime/PinotLLCRealtimeSegmentManagerTest.java:743

  • This section header Javadoc is duplicated multiple times consecutively. Please remove the duplicates and keep just one copy immediately before the related tests.
  /**
   * Test cases for the scenario where stream partitions increase, and the validation manager is attempting to create
   * segments for new partitions. This test assumes that all other factors remain the same (no error conditions or
   * inconsistencies in metadata and ideal state).
   */

pinot-controller/src/test/java/org/apache/pinot/controller/helix/core/realtime/PinotLLCRealtimeSegmentManagerTest.java:896

  • There are multiple consecutive copies of the same long Javadoc comment describing the repair scenarios. This makes the file much harder to scan. Collapse this to a single Javadoc block.
  /**
   * Tests that we can repair all invalid scenarios during segment completion.
   *
   * Segment completion takes place in 3 steps:
   * 1. Update committing segment ZK metadata to status DONE

pinot-controller/src/test/java/org/apache/pinot/controller/helix/core/realtime/PinotLLCRealtimeSegmentManagerTest.java:1878

  • Redundant duplicate Javadoc blocks were added before this segment-store upload test section. Remove the duplicates and keep a single section header comment.
  /**
   * Test cases for fixing LLC segment by uploading to segment store if missing
   */

pinot-controller/src/test/java/org/apache/pinot/controller/helix/core/realtime/PinotLLCRealtimeSegmentManagerTest.java:2017

  • Redundant duplicate Javadoc blocks were added before this V2 segment-store upload test section. Remove the duplicates and keep a single section header comment.
  /**
   * Test cases for fixing LLC segment by uploading to segment store if missing
   */

pinot-controller/src/test/java/org/apache/pinot/controller/helix/core/realtime/PinotLLCRealtimeSegmentManagerTest.java:2388

  • This Javadoc is repeated three times consecutively. Keep one copy to document the test, and delete the duplicates.
  /**
   * Verifies that {@code buildPartitionGroupConsumptionStatusFromZKMetadata} produces the same results as
   * {@code getPartitionGroupConsumptionStatusList} for the common case where IdealState and ZK metadata are in sync.
   * This validates that the optimization in {@code fetchPartitionGroupIdToSmallestOffset} (reusing the pre-computed
   * latestSegmentZKMetadataMap instead of rescanning the entire IdealState) does not change behavior.
   */

Comment on lines +181 to +192
/**
* Test cases for new table being created, and initial segments setup that follows.
*/

/**
* Test cases for new table being created, and initial segments setup that follows.
*/

/**
* Test cases for new table being created, and initial segments setup that follows.
*/

Comment on lines +2650 to +2664
/**
* Reset consumption start offsets for selected partition groups (issue #6637).
* For each partition: OFFLINE the latest CONSUMING segment if needed, then create a new IN_PROGRESS
* consuming segment at the requested offset. Does not attempt to seal/commit poisoned segments.
*
* <p>Best-effort per partition: successes and failures are returned independently. Concurrent RSVM/commit
* races and pauseless edge cases are not fully serialized yet (IdealState is written via {@link #setIdealState},
* not Helix CAS — callers must avoid concurrent commits on the same partitions).
*
* @param tableNameWithType realtime table name with type
* @param partitionToOffsetSerialized map of partition group id → serialized {@link StreamPartitionMsgOffset}
* @param comment optional operator comment for logs (newlines stripped)
* @return per-partition result maps with keys status/oldSegment/newSegment/offset/message
*/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

configuration Config changes (addition/deletion/change in behavior) feature New functionality ingestion Related to data ingestion pipeline real-time Related to realtime table ingestion and serving release-notes Referenced by PRs that need attention when compiling the next release notes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Automatically repair a problematic consuming segment

4 participants