Uh oh!
There was an error while loading. Please reload this page.
[fix](cloud) skip call getReplicas in cloud tablet - #59934
Conversation
Thearas
commented
Jan 15, 2026
Thank you for your contribution to Apache Doris. Please clearly describe your PR:
|
There was a problem hiding this comment.
Pull request overview
This PR refactors the cloud tablet replica access pattern to avoid calling getReplicas() on cloud tablets. Instead, it introduces a dedicated getCloudReplica() method for direct access to the single CloudReplica in a CloudTablet.
Changes:
- Converts several concrete methods in
Tabletto abstract methods, with optimized implementations inCloudTabletandLocalTablet - Replaces
getReplicas().get(0)calls with((CloudTablet) tablet).getCloudReplica()throughout cloud-specific code - Optimizes list creation by using
Collections.singletonList()andCollections.emptyList()instead of Guava'sLists.newArrayList()
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| CloudInternalCatalog.java | Updates replica access in partition drop and replica update methods to use getCloudReplica() |
| CloudTabletRebalancer.java | Refactors all replica access patterns in rebalancing logic to use getCloudReplica() |
| CloudTabletInvertedIndex.java | Optimizes replica list creation with immutable collections |
| CloudTablet.java | Adds getCloudReplica() method and optimized implementations of abstract methods; simplifies addReplica() |
| Tablet.java | Converts concrete methods to abstract, removing single-replica-specific logic |
| LocalTablet.java | Implements abstract methods moved from Tablet with multi-replica logic |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Uh oh!
There was an error while loading. Please reload this page.
mymeiyi
commented
Jan 15, 2026
run buildall |
doris-robot
commented
Jan 15, 2026
TPC-H: Total hot run time: 31696 ms |
doris-robot
commented
Jan 15, 2026
TPC-DS: Total hot run time: 173227 ms |
doris-robot
commented
Jan 15, 2026
ClickBench: Total hot run time: 27.14 s |
hello-stephen
commented
Jan 15, 2026
FE UT Coverage ReportIncrement line coverage |
hello-stephen
commented
Jan 15, 2026
FE Regression Coverage ReportIncrement line coverage |
mymeiyi
commented
Jan 16, 2026
run cloud_p0 |
hello-stephen
commented
Jan 16, 2026
FE Regression Coverage ReportIncrement line coverage |
PR approved by at least one committer and no changes requested. |
PR approved by anyone and no changes requested. |
dataroaring
left a comment
There was a problem hiding this comment.
PR Review: fix skip call getReplicas in cloud tablet
Summary
This PR optimizes CloudTablet by avoiding unnecessary list creation when accessing the single replica. It makes several methods abstract in the base Tablet class and provides optimized implementations in CloudTablet that directly access the replica field.
Critical Issues
1. [Critical] Behavioral Change in CloudTablet.addReplica - Version Check Removed
The old code:
privatebooleanisLatestReplicaAndDeleteOld(ReplicanewReplica) {
if (replica == null) {
returntrue;
}
if (replica.getVersion() <= newReplica.getVersion()) {
replica = null;
returntrue;
}
returnfalse; // Reject if existing replica has newer version
}
@OverridepublicvoidaddReplica(Replicareplica, booleanisRestore) {
if (isLatestReplicaAndDeleteOld(replica)) { // <-- Version check!this.replica = replica;
// ...
}
}The new code:
@OverridepublicvoidaddReplica(Replicareplica, booleanisRestore) {
this.replica = replica; // <-- Unconditionally overwrites!// ...
}Problem: The version comparison logic that prevents replacing a newer replica with an older one has been completely removed. This could cause data consistency issues if addReplica is called with an older replica version.
Recommendation: Restore the version check or document why it's no longer needed:
@OverridepublicvoidaddReplica(ReplicanewReplica, booleanisRestore) {
if (this.replica == null || this.replica.getVersion() <= newReplica.getVersion()) {
this.replica = newReplica;
if (!isRestore) {
Env.getCurrentInvertedIndex().addReplica(id, newReplica);
}
}
}2. [High] filterSizeZero Parameter Ignored in CloudTablet.getDataSize
// LocalTablet - respects filterSizeZeropubliclonggetDataSize(booleansingleReplica, booleanfilterSizeZero) {
LongStreams = getReplicas().stream()
.filter(r -> r.getState() == ReplicaState.NORMAL)
.filter(r -> !filterSizeZero || r.getDataSize() > 0) // <-- Filtered!
.mapToLong(Replica::getDataSize);
returnsingleReplica ? Double.valueOf(s.average().orElse(0)).longValue() : s.sum();
}
// CloudTablet - ignores filterSizeZeropubliclonggetDataSize(booleansingleReplica, booleanfilterSizeZero) {
if (replica != null && replica.getState() == ReplicaState.NORMAL) {
returnreplica.getDataSize(); // <-- filterSizeZero not checked!
}
return0;
}Problem: If filterSizeZero=true and the replica's dataSize is 0, CloudTablet will return 0 while LocalTablet would also return 0 but for the right reason (filtered out). The semantics are inconsistent.
Recommendation:
publiclonggetDataSize(booleansingleReplica, booleanfilterSizeZero) {
if (replica != null && replica.getState() == ReplicaState.NORMAL) {
longsize = replica.getDataSize();
if (filterSizeZero && size == 0) {
return0;
}
returnsize;
}
return0;
}3. [Medium] Immutable List May Break Callers
// Old - mutable listpublicList<Replica> getReplicas() {
if (replica == null) {
returnLists.newArrayList(); // Mutable
}
returnLists.newArrayList(replica); // Mutable
}
// New - immutable listpublicList<Replica> getReplicas() {
if (replica == null) {
returnCollections.emptyList(); // Immutable
}
returnCollections.singletonList(replica); // Immutable
}Problem: Any caller that modifies the returned list (e.g., getReplicas().add(...) or getReplicas().remove(...)) will now throw UnsupportedOperationException.
Recommendation: Search the codebase for any callers that modify the list returned by CloudTablet.getReplicas(). If none exist, this is acceptable but should be documented with a comment.
Minor Issues
4. [Low] Inconsistent Null Return vs Empty List
getCloudReplica() returns null when no replica exists, but getReplicas() returns an empty list. This inconsistency could lead to NPEs if callers expect non-null.
publicCloudReplicagetCloudReplica() {
if (replica == null) {
returnnull; // Returns null
}
return (CloudReplica) replica;
}Positive Aspects
Good use of
Collections.singletonList(): Avoids unnecessary object allocation inCloudTabletInvertedIndex.Direct field access optimization:
getCloudReplica()provides O(1) access without list iteration or allocation, improving performance in hot paths likeCloudTabletRebalancer.Clean abstraction: Making methods abstract in
Tabletenforces proper implementation in subclasses.Consistent pattern: All callers in
CloudTabletRebalancerandCloudInternalCatalognow use the newgetCloudReplica()method instead ofgetReplicas().get(0).
Missing Items
No tests: The PR checklist shows no regression/unit tests are selected.
PR description incomplete: "Problem Summary" is empty - should explain the memory/performance issue being solved.
Verdict
Needs changes before merge.
- [Must fix] Restore the version comparison logic in
addReplicaor explain why it's no longer needed - [Should fix] Handle
filterSizeZeroparameter correctly ingetDataSize - [Should verify] Ensure no callers modify the list returned by
getReplicas() - Add unit tests for the new implementations
mymeiyi
commented
Jan 26, 2026
run feut |
8d01fd0 to
b1a7d7fComparemymeiyi
commented
Jan 27, 2026
run buildall |
doris-robot
commented
Jan 27, 2026
TPC-H: Total hot run time: 32440 ms |
doris-robot
commented
Jan 27, 2026
ClickBench: Total hot run time: 28.62 s |
hello-stephen
commented
Jan 27, 2026
FE UT Coverage ReportIncrement line coverage |
PR approved by at least one committer and no changes requested. |
Uh oh!
There was an error while loading. Please reload this page.
What problem does this PR solve?
Issue Number: close #xxx
Related PR: #xxx
Problem Summary:
Release note
None
Check List (For Author)
Test
Behavior changed:
Does this need documentation?
Check List (For Reviewer who merge this PR)