📝 Description
During tenant shuffle-sharding rebalancing events under concurrent query load, the Query Frontend intermittently merges cached query fragments generated by different (and potentially outdated) shard assignments. This results in a race condition where a PromQL query returns a partial result set to the client while still responding with an incorrect HTTP 200 OK status.
This issue is transient and isolated to the window of time when a tenant's shard assignment is transitioning. The root cause lies in the cache key generation logic, which does not currently account for active shard routing topologies or epoch versions, combined with a lack of validation during shard ownership transitions in the Query Frontend.
🎯 Acceptance Criteria
🛠️ Technical Specifications & Context
Within the rasoolharlym8/CockroachDB repository (specifically looking at the query distribution and caching layers, typically located in paths like pkg/queryfrontend/, pkg/frontend/queryrange/, or equivalent query-routing directories):
-
Cache Key Generation:
- Locate the cache key generator (e.g.,
Extractor or KeyGenerator implementations in the query range split-and-merge middleware).
- Update the key generation struct/function to append the tenant's current shard configuration hash or epoch version:
// Example conceptual change
func (g *KeyGenerator) GenerateKey(req Request, tenantID string, shardEpoch int64) string {
return fmt.Sprintf("%s:%d:%s", tenantID, shardEpoch, req.Hash())
}
-
Shard Transition Validation:
- In the query execution path (where sub-queries/fragments are dispatched to downstream shard targets), capture the routing table epoch at the start of the request.
- Before writing merged results back to the query cache, verify that the routing table epoch has not changed. If a change is detected, discard the cache write and discard/retry the query.
-
Concurrency Control:
- Review the tenant routing state storage in the Query Frontend. Ensure that updates to the routing table use atomic pointers (
sync/atomic) or read-write locks (sync.RWMutex) to prevent dirty reads during rebalancing.
🧪 Verification & Testing
- Unit Tests:
- Add unit tests in the query frontend package to verify that cache keys differ when the same query is executed under two different shard configurations.
- Write a test simulating a mid-flight shard configuration change to verify that the cache write-back is safely aborted.
- Integration & Chaos Testing:
- Implement a mock test case simulating a tenant shuffle-sharding rebalance.
- Generate concurrent PromQL query load during the rebalance and assert that:
- No partial results are returned to the client.
- All successful responses (
HTTP 200 OK) contain complete datasets.
- Any interrupted queries are retried internally or fail gracefully with an appropriate non-200 error code.
- Race Detection:
- Run the test suite with the Go race detector enabled (
go test -race ./...) to ensure no data races exist in the updated routing table lookup and cache key generation paths.

This repo is using Opire - what does it mean? 👇
💵 Everyone can add rewards for this issue commenting /reward 100 (replace 100 with the amount).
🕵️♂️ If someone starts working on this issue to earn the rewards, they can comment /try to let everyone know!
🙌 And when they open the PR, they can comment /claim #3 either in the PR description or in a PR's comment.
🪙 Also, everyone can tip any user commenting /tip 20 @rasoolharlym8 (replace 20 with the amount, and @rasoolharlym8 with the user to tip).
📖 If you want to learn more, check out our documentation.
📝 Description
During tenant shuffle-sharding rebalancing events under concurrent query load, the Query Frontend intermittently merges cached query fragments generated by different (and potentially outdated) shard assignments. This results in a race condition where a PromQL query returns a partial result set to the client while still responding with an incorrect
HTTP 200 OKstatus.This issue is transient and isolated to the window of time when a tenant's shard assignment is transitioning. The root cause lies in the cache key generation logic, which does not currently account for active shard routing topologies or epoch versions, combined with a lack of validation during shard ownership transitions in the Query Frontend.
🎯 Acceptance Criteria
HTTP 200 OK.🛠️ Technical Specifications & Context
Within the
rasoolharlym8/CockroachDBrepository (specifically looking at the query distribution and caching layers, typically located in paths likepkg/queryfrontend/,pkg/frontend/queryrange/, or equivalent query-routing directories):Cache Key Generation:
ExtractororKeyGeneratorimplementations in the query range split-and-merge middleware).Shard Transition Validation:
Concurrency Control:
sync/atomic) or read-write locks (sync.RWMutex) to prevent dirty reads during rebalancing.🧪 Verification & Testing
HTTP 200 OK) contain complete datasets.go test -race ./...) to ensure no data races exist in the updated routing table lookup and cache key generation paths.This repo is using Opire - what does it mean? 👇
💵 Everyone can add rewards for this issue commenting
/reward 100(replace100with the amount).🕵️♂️ If someone starts working on this issue to earn the rewards, they can comment
/tryto let everyone know!🙌 And when they open the PR, they can comment
/claim #3either in the PR description or in a PR's comment.🪙 Also, everyone can tip any user commenting
/tip 20 @rasoolharlym8(replace20with the amount, and@rasoolharlym8with the user to tip).📖 If you want to learn more, check out our documentation.