Skip to content

Fix FD_AWARE instance assignment when pool tags do not start at 0 - #19266

Merged
Jackie-Jiang merged 1 commit into
apache:masterfrom
Vamsi-klu:fix-12239-fd-aware-nonzero-pool-tags
Aug 18, 2026
Merged

Fix FD_AWARE instance assignment when pool tags do not start at 0#19266
Jackie-Jiang merged 1 commit into
apache:masterfrom
Vamsi-klu:fix-12239-fd-aware-nonzero-pool-tags

Conversation

@Vamsi-klu

Copy link
Copy Markdown
Contributor

Problem

FDAwareInstancePartitionSelector sizes _fdCounter by the number of pools, then indexes it by the raw Helix pool tag. Deployments whose pool tags are {1,2,3} instead of {0,1,2} fail table creation:

java.lang.ArrayIndexOutOfBoundsException: Index 3 out of bounds for length 3
    at ...FDAwareInstancePartitionSelector$...setNewInstance

InstanceReplicaGroupPartitionSelector is fine: it looks pool ids up as map keys, never as array indexes. Existing FD_AWARE tests only tagged pools 0..N-1, so this never showed up.

What I did

I deleted _fdCounter and the three writes that touched it (setNewInstance, setExistingInstance, unSetInstance).

_fdCounter is dead state. It is written in those three places and read nowhere. The only intended consumers, normalize() and swapToInvariantState(), are still unimplemented stubs. Its only runtime effect today is this crash.

How I did it

Remove the unused array instead of adding a dense poolId -> index map. Net change is about −5 lines in FDAwareInstancePartitionSelector. No config, metric, HTTP, wire, or on-disk change. I did not rewrite InstanceTagPoolSelector, renumber Helix tags, or implement the normalize / swapToInvariantState TODOs.

seekKey on the minimize-data-movement path still mixes count-space and key-space. The miss is absorbed by ceilingKey / firstKey (no crash, wrong rotation start). I left that out of this PR on purpose.

If reviewers want the unfinished counter kept for later normalization work, the alternative is a dense map built from the already-sorted faultDomainToInstanceConfigsMap.keySet(). Happy to switch.

Impact

POST /tables with FD_AWARE and non-zero-based pool tags ({1,2,3}, sparse {5,9}, single pool 7, negative pool ids) no longer crashes. Zero-based {0,1,2} is unchanged. Replica-group assignment is unchanged.

Testing

InstanceAssignmentTest#testPoolBasedFDAwareNonZeroBasedPools failed on current master with Index 5 out of bounds for length 5, then passed after the delete. It copies testPoolBasedFDAware but sets pool = (i % numPools) + 1, and also covers the reporter {1,2,3} case plus an incremental uplift that hits setExistingInstance with the raw pool ids.

./mvnw -pl pinot-controller -am -Dtest=InstanceAssignmentTest#testPoolBasedFDAwareNonZeroBasedPools,InstanceAssignmentTest#testPoolBasedFDAware test
./mvnw spotless:apply checkstyle:check license:format license:check -pl pinot-controller

Fixes #12239

Made with Cursor

_fdCounter is sized by pool count but indexed by the raw Helix tag, so
tags such as {1,2,3} crash table creation. The array is written and never
read, so delete it rather than remap the indexes.

Co-authored-by: Cursor <cursoragent@cursor.com>
@codecov-commenter

codecov-commenter commented Aug 15, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 66.98%. Comparing base (388bc64) to head (e77e0e5).
⚠️ Report is 5 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff            @@
##             master   #19266   +/-   ##
=========================================
  Coverage     66.97%   66.98%           
  Complexity     1423     1423           
=========================================
  Files          3453     3453           
  Lines        218949   218955    +6     
  Branches      34805    34805           
=========================================
+ Hits         146648   146661   +13     
- Misses        60585    60586    +1     
+ Partials      11716    11708    -8     
Flag Coverage Δ
integration 100.00% <ø> (ø)
integration1 100.00% <ø> (ø)
integration2 0.00% <ø> (ø)
java-25 66.98% <ø> (+<0.01%) ⬆️
lane-a 100.00% <ø> (ø)
lane-b 0.00% <ø> (ø)
temurin 66.98% <ø> (+<0.01%) ⬆️
unittests 66.97% <ø> (+<0.01%) ⬆️
unittests1 57.74% <ø> (+<0.01%) ⬆️
unittests2 39.03% <ø> (-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.

@Jackie-Jiang
Jackie-Jiang requested review from J-HowHuang and a balanced review from Copilot August 18, 2026 19:53
@Jackie-Jiang Jackie-Jiang added data-manager enhancement Improvement to existing functionality labels Aug 18, 2026
@Jackie-Jiang Jackie-Jiang added bug Something is not working as expected segment-rebalance Related to segment rebalancing across servers and removed enhancement Improvement to existing functionality data-manager labels Aug 18, 2026
@Jackie-Jiang
Jackie-Jiang merged commit 811d64c into apache:master Aug 18, 2026
15 of 17 checks passed

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

Fixes FD-aware assignment crashes for non-zero-based Helix pool IDs.

Changes:

  • Removes the unused fault-domain counter indexed by raw pool IDs.
  • Adds regression coverage for positive non-zero-based pools and incremental assignment.

Reviewed changes

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

File Description
FDAwareInstancePartitionSelector.java Removes unsafe dead counter state.
InstanceAssignmentTest.java Tests non-zero-based pool assignment.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 327 to 329
private void setExistingInstance(int replicaGroupId, int instanceIndex, String instance, int fdId) {
_replicaGroupIdToInstancesMap[replicaGroupId][instanceIndex] = new Instance(instance, fdId, replicaGroupId);
_usedInstances.put(instance, fdId);
private static List<InstanceConfig> newFDAwarePoolInstanceConfigs(int numInstances, int numPools) {
List<InstanceConfig> instanceConfigs = new ArrayList<>(numInstances);
for (int i = 0; i < numInstances; i++) {
int pool = (i % numPools) + 1;
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 segment-rebalance Related to segment rebalancing across servers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FD_AWARE_INSTANCE_PARTITION_SELECTOR fails when pool tag does not start with 0

4 participants