Skip to content

Commit fbf8e02

Browse files
authored
[improvement](statistics)Use min row count of all replicas as tablet/table row count. (#41894) (#41980)
backport: #41894
1 parent 49ca449 commit fbf8e02

File tree

4 files changed

+65
-4
lines changed

4 files changed

+65
-4
lines changed

fe/fe-core/src/main/java/org/apache/doris/catalog/Tablet.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,23 @@ public long getRowCount(boolean singleReplica) {
528528
return singleReplica ? Double.valueOf(s.average().orElse(0)).longValue() : s.sum();
529529
}
530530

531+
// Get the least row count among all valid replicas.
532+
// The replica with the least row count is the most accurate one. Because it performs most compaction.
533+
public long getMinReplicaRowCount(long version) {
534+
long minRowCount = Long.MAX_VALUE;
535+
long maxReplicaVersion = 0;
536+
for (Replica r : replicas) {
537+
if (r.isAlive()
538+
&& r.checkVersionCatchUp(version, false)
539+
&& (r.getVersion() > maxReplicaVersion
540+
|| r.getVersion() == maxReplicaVersion && r.getRowCount() < minRowCount)) {
541+
minRowCount = r.getRowCount();
542+
maxReplicaVersion = r.getVersion();
543+
}
544+
}
545+
return minRowCount == Long.MAX_VALUE ? 0 : minRowCount;
546+
}
547+
531548
/**
532549
* A replica is healthy only if
533550
* 1. the backend is available

fe/fe-core/src/main/java/org/apache/doris/catalog/TabletStatMgr.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,18 @@ protected void runAfterCatalogReady() {
134134
Long tabletDataSize = 0L;
135135
Long tabletRemoteDataSize = 0L;
136136

137-
Long tabletRowCount = 0L;
137+
Long tabletRowCount = Long.MAX_VALUE;
138138

139139
boolean tabletReported = false;
140140
for (Replica replica : tablet.getReplicas()) {
141141
LOG.debug("Table {} replica {} current version {}, report version {}",
142142
olapTable.getName(), replica.getId(),
143143
replica.getVersion(), replica.getLastReportVersion());
144+
// Replica with less row count is more accurate than the others
145+
// when replicas' version are identical. Because less row count
146+
// means this replica does more compaction than the others.
144147
if (replica.checkVersionCatchUp(version, false)
145-
&& replica.getRowCount() >= tabletRowCount) {
148+
&& replica.getRowCount() < tabletRowCount) {
146149
// 1. If replica version and reported replica version are all equal to
147150
// PARTITION_INIT_VERSION, set tabletReported to true, which indicates this
148151
// tablet is empty for sure when previous report.
@@ -173,6 +176,10 @@ protected void runAfterCatalogReady() {
173176
tableDataSize += tabletDataSize;
174177
tableRemoteDataSize += tabletRemoteDataSize;
175178

179+
// When all BEs are down, avoid set Long.MAX_VALUE to index and table row count. Use 0.
180+
if (tabletRowCount == Long.MAX_VALUE) {
181+
tabletRowCount = 0L;
182+
}
176183
tableRowCount += tabletRowCount;
177184
indexRowCount += tabletRowCount;
178185
// Only when all tablets of this index are reported, we set indexReported to true.

fe/fe-core/src/main/java/org/apache/doris/statistics/OlapAnalysisTask.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ protected ResultRow collectBasicStat() {
177177
Map<String, String> params = buildSqlParams();
178178
StringSubstitutor stringSubstitutor = new StringSubstitutor(params);
179179
String sql = stringSubstitutor.replace(BASIC_STATS_TEMPLATE);
180-
ResultRow resultRow = null;
180+
ResultRow resultRow;
181181
try (AutoCloseConnectContext r = StatisticsUtil.buildConnectContext(false)) {
182182
stmtExecutor = new StmtExecutor(r.connectContext, sql);
183183
resultRow = stmtExecutor.executeInternalQuery().get(0);
@@ -321,7 +321,8 @@ protected Pair<List<Long>, Long> calcActualSampleTablets(boolean forPartitionCol
321321
int seekTid = (int) ((i + seek) % ids.size());
322322
long tabletId = ids.get(seekTid);
323323
sampleTabletIds.add(tabletId);
324-
actualSampledRowCount += materializedIndex.getTablet(tabletId).getRowCount(true);
324+
actualSampledRowCount += materializedIndex.getTablet(tabletId)
325+
.getMinReplicaRowCount(p.getVisibleVersion());
325326
if (actualSampledRowCount >= sampleRows && !forPartitionColumn) {
326327
enough = true;
327328
break;

fe/fe-core/src/test/java/org/apache/doris/catalog/TabletTest.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,4 +215,40 @@ public void testTabletColocateHealthStatus() {
215215
Pair.of(1L, false), Pair.of(2L, false), Pair.of(3L, false), Pair.of(4L, true)
216216
);
217217
}
218+
219+
@Test
220+
public void testGetMinReplicaRowCount() {
221+
Tablet t = new Tablet(1);
222+
long row = t.getMinReplicaRowCount(1);
223+
Assert.assertEquals(0, row);
224+
225+
Replica r1 = new Replica(1, 1, 10, 0, 0, 0, 100, ReplicaState.NORMAL, 0, 10);
226+
t.addReplica(r1);
227+
row = t.getMinReplicaRowCount(10);
228+
Assert.assertEquals(100, row);
229+
230+
row = t.getMinReplicaRowCount(11);
231+
Assert.assertEquals(0, row);
232+
233+
Replica r2 = new Replica(2, 2, 10, 0, 0, 0, 110, ReplicaState.NORMAL, 0, 10);
234+
Replica r3 = new Replica(3, 3, 10, 0, 0, 0, 90, ReplicaState.NORMAL, 0, 10);
235+
t.addReplica(r2);
236+
t.addReplica(r3);
237+
row = t.getMinReplicaRowCount(11);
238+
Assert.assertEquals(0, row);
239+
row = t.getMinReplicaRowCount(9);
240+
Assert.assertEquals(90, row);
241+
242+
r3.setBad(true);
243+
row = t.getMinReplicaRowCount(9);
244+
Assert.assertEquals(100, row);
245+
246+
r3.setBad(false);
247+
row = t.getMinReplicaRowCount(9);
248+
Assert.assertEquals(90, row);
249+
250+
r2.updateVersion(11);
251+
row = t.getMinReplicaRowCount(9);
252+
Assert.assertEquals(110, row);
253+
}
218254
}

0 commit comments

Comments
 (0)