This is an automated email from the ASF dual-hosted git repository.
morrysnow pushed a commit to branch branch-3.1
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-3.1 by this push:
new f6802a4053b branch-3.1: [improve](statistic)Reduce call of olap table
getVisibleVersion for cloud version. #53903 (#54205)
f6802a4053b is described below
commit f6802a4053bd7d4c0c252b3a561bb927ede59e5a
Author: James <[email protected]>
AuthorDate: Mon Aug 4 10:00:03 2025 +0800
branch-3.1: [improve](statistic)Reduce call of olap table getVisibleVersion
for cloud version. #53903 (#54205)
backport: #53903
---
.../doris/statistics/StatisticsAutoCollector.java | 85 ++++++++++++----------
.../doris/statistics/StatisticsJobAppender.java | 58 ++++++++-------
.../doris/statistics/util/StatisticsUtil.java | 19 +++--
.../statistics/StatisticsAutoCollectorTest.java | 66 +++++++++++------
.../statistics/StatisticsJobAppenderTest.java | 78 +++++++++-----------
.../doris/statistics/util/StatisticsUtilTest.java | 34 ++++++---
6 files changed, 187 insertions(+), 153 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/statistics/StatisticsAutoCollector.java
b/fe/fe-core/src/main/java/org/apache/doris/statistics/StatisticsAutoCollector.java
index 512e807c620..8cd96bc4957 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/statistics/StatisticsAutoCollector.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/statistics/StatisticsAutoCollector.java
@@ -28,7 +28,6 @@ import org.apache.doris.common.Pair;
import org.apache.doris.common.util.MasterDaemon;
import org.apache.doris.datasource.hive.HMSExternalTable;
import org.apache.doris.persist.TableStatsDeletionLog;
-import org.apache.doris.rpc.RpcException;
import org.apache.doris.statistics.AnalysisInfo.AnalysisMethod;
import org.apache.doris.statistics.AnalysisInfo.JobType;
import org.apache.doris.statistics.AnalysisInfo.ScheduleType;
@@ -140,23 +139,32 @@ public class StatisticsAutoCollector extends MasterDaemon
{
}
}
- protected void processOneJob(TableIf table, Set<Pair<String, String>>
columns,
- JobPriority priority) throws DdlException {
- appendAllColumns(table, columns);
- AnalysisMethod analysisMethod = table.getDataSize(true) >=
StatisticsUtil.getHugeTableLowerBoundSizeInBytes()
+ protected void processOneJob(TableIf table, Set<Pair<String, String>>
columns, JobPriority priority) {
+ AnalysisMethod analysisMethod =
(StatisticsUtil.getHugeTableLowerBoundSizeInBytes() == 0
+ || table.getDataSize(true) >=
StatisticsUtil.getHugeTableLowerBoundSizeInBytes())
? AnalysisMethod.SAMPLE : AnalysisMethod.FULL;
if (StatisticsUtil.enablePartitionAnalyze() &&
table.isPartitionedTable()) {
analysisMethod = AnalysisMethod.FULL;
}
boolean isSampleAnalyze = analysisMethod.equals(AnalysisMethod.SAMPLE);
OlapTable olapTable = table instanceof OlapTable ? (OlapTable) table :
null;
+ AnalysisManager manager = Env.getServingEnv().getAnalysisManager();
+ TableStatsMeta tableStatsStatus =
manager.findTableStatsStatus(table.getId());
+ long rowCount = table.getRowCount();
+ if (!readyToSample(table, rowCount, manager, tableStatsStatus,
isSampleAnalyze)) {
+ return;
+ }
+ appendAllColumns(table, columns);
+ long olapTableVersion = StatisticsUtil.getOlapTableVersion(olapTable);
columns = columns.stream()
- .filter(c -> StatisticsUtil.needAnalyzeColumn(table, c) ||
StatisticsUtil.isLongTimeColumn(table, c))
+ .filter(c -> StatisticsUtil.needAnalyzeColumn(table, c)
+ || StatisticsUtil.isLongTimeColumn(table, c,
olapTableVersion))
.filter(c -> olapTable == null ||
StatisticsUtil.canCollectColumn(
olapTable.getIndexMetaByIndexId(olapTable.getIndexIdByName(c.first)).getColumnByName(c.second),
table, isSampleAnalyze,
olapTable.getIndexIdByName(c.first)))
.collect(Collectors.toSet());
- AnalysisInfo analyzeJob = createAnalyzeJobForTbl(table, columns,
priority, analysisMethod);
+ AnalysisInfo analyzeJob = createAnalyzeJobForTbl(table, columns,
priority, analysisMethod,
+ rowCount, tableStatsStatus, olapTableVersion);
if (analyzeJob == null) {
return;
}
@@ -172,8 +180,34 @@ public class StatisticsAutoCollector extends MasterDaemon {
}
}
+ protected boolean readyToSample(TableIf table, long rowCount,
AnalysisManager manager,
+ TableStatsMeta tableStatsStatus, boolean isSample) {
+ if (!isSample) {
+ return true;
+ }
+ OlapTable olapTable = table instanceof OlapTable ? (OlapTable) table :
null;
+ if (olapTable != null
+ && olapTable.getRowCountForIndex(olapTable.getBaseIndexId(),
true) == TableIf.UNKNOWN_ROW_COUNT) {
+ LOG.info("Table {} row count is not fully reported, skip auto
analyzing it.", olapTable.getName());
+ return false;
+ }
+ // We don't auto analyze empty table to avoid all 0 stats.
+ // Because all 0 is more dangerous than unknown stats when row count
report is delayed.
+ if (rowCount <= 0) {
+ LOG.info("Table {} is empty, remove its old stats and skip auto
analyze it.", table.getName());
+ // Remove the table's old stats if exists.
+ if (tableStatsStatus != null &&
!tableStatsStatus.isColumnsStatsEmpty()) {
+ manager.removeTableStats(table.getId());
+ Env.getCurrentEnv().getEditLog().logDeleteTableStats(new
TableStatsDeletionLog(table.getId()));
+ manager.dropStats(table, null);
+ }
+ return false;
+ }
+ return true;
+ }
+
// If partition changed (partition first loaded, partition dropped and so
on), need re-analyze all columns.
- protected void appendAllColumns(TableIf table, Set<Pair<String, String>>
columns) throws DdlException {
+ private void appendAllColumns(TableIf table, Set<Pair<String, String>>
columns) {
if (!(table instanceof OlapTable)) {
return;
}
@@ -198,30 +232,9 @@ public class StatisticsAutoCollector extends MasterDaemon {
&& ((HMSExternalTable)
tableIf).getDlaType().equals(HMSExternalTable.DLAType.HIVE);
}
- protected AnalysisInfo createAnalyzeJobForTbl(
- TableIf table, Set<Pair<String, String>> jobColumns, JobPriority
priority, AnalysisMethod analysisMethod) {
- AnalysisManager manager = Env.getServingEnv().getAnalysisManager();
- TableStatsMeta tableStatsStatus =
manager.findTableStatsStatus(table.getId());
- if (table instanceof OlapTable &&
analysisMethod.equals(AnalysisMethod.SAMPLE)) {
- OlapTable ot = (OlapTable) table;
- if (ot.getRowCountForIndex(ot.getBaseIndexId(), true) ==
TableIf.UNKNOWN_ROW_COUNT) {
- LOG.info("Table {} row count is not fully reported, skip auto
analyzing this time.", ot.getName());
- return null;
- }
- }
- // We don't auto analyze empty table to avoid all 0 stats.
- // Because all 0 is more dangerous than unknown stats when row count
report is delayed.
- long rowCount = table.getRowCount();
- if (rowCount <= 0) {
- LOG.info("Table {} is empty, remove its old stats and skip auto
analyze it.", table.getName());
- // Remove the table's old stats if exists.
- if (tableStatsStatus != null &&
!tableStatsStatus.isColumnsStatsEmpty()) {
- manager.removeTableStats(table.getId());
- Env.getCurrentEnv().getEditLog().logDeleteTableStats(new
TableStatsDeletionLog(table.getId()));
- manager.dropStats(table, null);
- }
- return null;
- }
+ protected AnalysisInfo createAnalyzeJobForTbl(TableIf table,
Set<Pair<String, String>> jobColumns,
+ JobPriority priority, AnalysisMethod analysisMethod, long
rowCount, TableStatsMeta tableStatsStatus,
+ long version) {
if (jobColumns == null || jobColumns.isEmpty()) {
return null;
}
@@ -230,14 +243,6 @@ public class StatisticsAutoCollector extends MasterDaemon {
for (Pair<String, String> pair : jobColumns) {
stringJoiner.add(pair.toString());
}
- long version = 0;
- try {
- if (table instanceof OlapTable) {
- version = ((OlapTable) table).getVisibleVersion();
- }
- } catch (RpcException e) {
- LOG.warn("table {}, in cloud getVisibleVersion exception",
table.getName(), e);
- }
return new AnalysisInfoBuilder()
.setJobId(Env.getCurrentEnv().getNextId())
.setCatalogId(table.getDatabase().getCatalog().getId())
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/statistics/StatisticsJobAppender.java
b/fe/fe-core/src/main/java/org/apache/doris/statistics/StatisticsJobAppender.java
index 7597c25633f..3ddd360fb5e 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/statistics/StatisticsJobAppender.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/statistics/StatisticsJobAppender.java
@@ -24,6 +24,7 @@ import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.OlapTable;
import org.apache.doris.catalog.Table;
import org.apache.doris.catalog.TableIf;
+import org.apache.doris.common.Config;
import org.apache.doris.common.Pair;
import org.apache.doris.common.util.MasterDaemon;
import org.apache.doris.datasource.InternalCatalog;
@@ -31,6 +32,7 @@ import org.apache.doris.statistics.util.StatisticsUtil;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.Lists;
+import com.google.common.collect.Sets;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -144,10 +146,10 @@ public class StatisticsJobAppender extends MasterDaemon {
}
}
- protected void appendToLowJobs(Map<TableName, Set<Pair<String, String>>>
lowPriorityJobs,
+ protected int appendToLowJobs(Map<TableName, Set<Pair<String, String>>>
lowPriorityJobs,
Map<TableName, Set<Pair<String, String>>>
veryLowPriorityJobs) {
if (System.currentTimeMillis() - lastRoundFinishTime <
lowJobIntervalMs) {
- return;
+ return 0;
}
InternalCatalog catalog = Env.getCurrentInternalCatalog();
List<Long> sortedDbs =
catalog.getDbIds().stream().sorted().collect(Collectors.toList());
@@ -173,35 +175,34 @@ public class StatisticsJobAppender extends MasterDaemon {
Set<String> columns = t.getSchemaAllIndexes(false).stream()
.filter(c ->
!StatisticsUtil.isUnsupportedType(c.getType()))
.map(Column::getName).collect(Collectors.toSet());
- Set<Pair<String, String>> columnIndexPairs =
t.getColumnIndexPairs(columns)
- .stream().filter(p ->
StatisticsUtil.needAnalyzeColumn(t, p))
- .collect(Collectors.toSet());
TableName tableName = new
TableName(t.getDatabase().getCatalog().getName(),
t.getDatabase().getFullName(), t.getName());
- // Append to low job map first.
- if (!columnIndexPairs.isEmpty()) {
- boolean appended = doAppend(lowPriorityJobs,
columnIndexPairs, tableName);
- // If low job map is full, stop this iteration.
- if (!appended) {
- LOG.debug("Low Priority job map is full.");
- return;
- }
- } else {
- // Append to very low job map.
- columnIndexPairs = t.getColumnIndexPairs(columns)
- .stream().filter(p ->
StatisticsUtil.isLongTimeColumn(t, p))
- .collect(Collectors.toSet());
- if (!columnIndexPairs.isEmpty()) {
- boolean appended = doAppend(veryLowPriorityJobs,
columnIndexPairs, tableName);
- // If very low job map is full, simply ignore it and
go to the next table.
- if (!appended) {
+ boolean appended = false;
+ long version = Config.isCloudMode() ? 0 :
StatisticsUtil.getOlapTableVersion((OlapTable) t);
+ for (Pair<String, String> p : t.getColumnIndexPairs(columns)) {
+ // Append to low job map first.
+ if (StatisticsUtil.needAnalyzeColumn(t, p)) {
+ // If low job map is full, stop this iteration.
+ if (!doAppend(lowPriorityJobs, p, tableName)) {
+ LOG.debug("Low Priority job map is full.");
+ return processed;
+ }
+ appended = true;
+ } else if (StatisticsUtil.isLongTimeColumn(t, p, version))
{
+ // If very low job map is full, simply ignore it and
go to the next column.
+ if (!doAppend(veryLowPriorityJobs, p, tableName)) {
LOG.debug("Very low Priority job map is full.");
+ } else {
+ appended = true;
}
}
}
currentTableId = t.getId();
- if (++processed >= TABLE_BATCH_SIZE) {
- return;
+ if (appended) {
+ processed++;
+ }
+ if (processed >= TABLE_BATCH_SIZE) {
+ return processed;
}
}
}
@@ -212,6 +213,7 @@ public class StatisticsJobAppender extends MasterDaemon {
currentDbId = 0;
currentTableId = 0;
lastRoundFinishTime = System.currentTimeMillis();
+ return processed;
}
protected List<Table> sortTables(List<Table> tables) {
@@ -223,16 +225,18 @@ public class StatisticsJobAppender extends MasterDaemon {
@VisibleForTesting
public boolean doAppend(Map<TableName, Set<Pair<String, String>>> jobMap,
- Set<Pair<String, String>> columnIndexPairs,
+ Pair<String, String> columnIndexPair,
TableName tableName) {
synchronized (jobMap) {
if (!jobMap.containsKey(tableName) && jobMap.size() >=
JOB_MAP_SIZE) {
return false;
}
if (jobMap.containsKey(tableName)) {
- jobMap.get(tableName).addAll(columnIndexPairs);
+ jobMap.get(tableName).add(columnIndexPair);
} else {
- jobMap.put(tableName, columnIndexPairs);
+ Set<Pair<String, String>> columnSet = Sets.newHashSet();
+ columnSet.add(columnIndexPair);
+ jobMap.put(tableName, columnSet);
}
}
return true;
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/statistics/util/StatisticsUtil.java
b/fe/fe-core/src/main/java/org/apache/doris/statistics/util/StatisticsUtil.java
index 8989cfd9b87..7cbbfc43591 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/statistics/util/StatisticsUtil.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/statistics/util/StatisticsUtil.java
@@ -1180,7 +1180,7 @@ public class StatisticsUtil {
}
// This function return true means the column hasn't been analyzed for
longer than the configured time.
- public static boolean isLongTimeColumn(TableIf table, Pair<String, String>
column) {
+ public static boolean isLongTimeColumn(TableIf table, Pair<String, String>
column, long version) {
if (column == null) {
return false;
}
@@ -1213,15 +1213,20 @@ public class StatisticsUtil {
}
// For olap table, if the table visible version and row count doesn't
change since last analyze,
// we don't need to analyze it because its data is not changed.
- OlapTable olapTable = (OlapTable) table;
- long version = 0;
+ return version != columnStats.tableVersion
+ || table.getRowCount() != columnStats.rowCount;
+ }
+
+ public static long getOlapTableVersion(OlapTable olapTable) {
+ if (olapTable == null) {
+ return 0;
+ }
try {
- version = ((OlapTable) table).getVisibleVersion();
+ return olapTable.getVisibleVersion();
} catch (RpcException e) {
- LOG.warn("in cloud getVisibleVersion exception", e);
+ LOG.warn("table {}, in cloud getVisibleVersion exception",
olapTable.getName(), e);
+ return 0;
}
- return version != columnStats.tableVersion
- || olapTable.getRowCount() != columnStats.rowCount;
}
public static boolean canCollect() {
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/statistics/StatisticsAutoCollectorTest.java
b/fe/fe-core/src/test/java/org/apache/doris/statistics/StatisticsAutoCollectorTest.java
index 095a0df5138..625fd904809 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/statistics/StatisticsAutoCollectorTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/statistics/StatisticsAutoCollectorTest.java
@@ -19,12 +19,15 @@ package org.apache.doris.statistics;
import org.apache.doris.analysis.TableName;
import org.apache.doris.catalog.Column;
+import org.apache.doris.catalog.Database;
import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.OlapTable;
import org.apache.doris.catalog.PrimitiveType;
+import org.apache.doris.catalog.TableIf;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.Pair;
import org.apache.doris.datasource.ExternalTable;
+import org.apache.doris.datasource.InternalCatalog;
import org.apache.doris.datasource.hive.HMSExternalCatalog;
import org.apache.doris.datasource.hive.HMSExternalDatabase;
import org.apache.doris.datasource.hive.HMSExternalTable;
@@ -35,10 +38,12 @@ import org.apache.doris.datasource.jdbc.JdbcExternalTable;
import org.apache.doris.statistics.AnalysisInfo.AnalysisMethod;
import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
import mockit.Mock;
import mockit.MockUp;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
import java.util.ArrayList;
import java.util.HashSet;
@@ -155,30 +160,45 @@ public class StatisticsAutoCollectorTest {
@Test
public void testCreateAnalyzeJobForTbl() {
StatisticsAutoCollector collector = new StatisticsAutoCollector();
- OlapTable table = new OlapTable();
- new MockUp<OlapTable>() {
- @Mock
- public long getDataSize(boolean singleReplica) {
- return 100;
- }
+ OlapTable table = Mockito.mock(OlapTable.class);
+ Database db = Mockito.mock(Database.class);
+ InternalCatalog catalog = Mockito.mock(InternalCatalog.class);
+ Mockito.when(table.getDatabase()).thenReturn(db);
+ Mockito.when(db.getCatalog()).thenReturn(catalog);
+ Mockito.when(db.getId()).thenReturn(100L);
+ Mockito.when(catalog.getId()).thenReturn(10L);
+
+
+ Assertions.assertNull(collector.createAnalyzeJobForTbl(table, null,
null, AnalysisMethod.SAMPLE, 100, null, 10));
+
+ Set<Pair<String, String>> jobColumns = Sets.newHashSet();
+ jobColumns.add(Pair.of("a", "b"));
+ jobColumns.add(Pair.of("c", "d"));
+ AnalysisInfo analyzeJobForTbl =
collector.createAnalyzeJobForTbl(table, jobColumns, JobPriority.HIGH,
AnalysisMethod.SAMPLE, 100,
+ null, 10);
+ Assertions.assertEquals("[a:b,c:d]", analyzeJobForTbl.colName);
+ Assertions.assertEquals(JobPriority.HIGH, analyzeJobForTbl.priority);
+ Assertions.assertEquals(AnalysisMethod.SAMPLE,
analyzeJobForTbl.analysisMethod);
+ Assertions.assertEquals(100, analyzeJobForTbl.rowCount);
+ Assertions.assertEquals(10, analyzeJobForTbl.tableVersion);
+ }
- @Mock
- public long getRowCountForIndex(long indexId, boolean strict) {
- return -1;
- }
+ @Test
+ public void testReadyToSample() {
+ StatisticsAutoCollector collector = new StatisticsAutoCollector();
+ OlapTable table = Mockito.mock(OlapTable.class);
+ Mockito.when(table.getName()).thenReturn("table");
+ Mockito.when(table.getRowCountForIndex(Mockito.anyLong(),
Mockito.anyBoolean())).thenReturn(TableIf.UNKNOWN_ROW_COUNT);
+ // not sample
+ Assertions.assertTrue(collector.readyToSample(table, 100, null, null,
false));
+ // not fully reported.
+ Assertions.assertFalse(collector.readyToSample(table, 100, null, null,
true));
+
+ Mockito.when(table.getRowCountForIndex(Mockito.anyLong(),
Mockito.anyBoolean())).thenReturn(100L);
+ // Row count is 0
+ Assertions.assertFalse(collector.readyToSample(table, 0, null, null,
true));
+ // ready to sample
+ Assertions.assertTrue(collector.readyToSample(table, 100, null, null,
true));
- @Mock
- public boolean isPartitionedTable() {
- return false;
- }
- };
- Assertions.assertNull(collector.createAnalyzeJobForTbl(table, null,
null, AnalysisMethod.SAMPLE));
- new MockUp<OlapTable>() {
- @Mock
- public long getRowCountForIndex(long indexId, boolean strict) {
- return 100;
- }
- };
- Assertions.assertNull(collector.createAnalyzeJobForTbl(table, null,
null, AnalysisMethod.SAMPLE));
}
}
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/statistics/StatisticsJobAppenderTest.java
b/fe/fe-core/src/test/java/org/apache/doris/statistics/StatisticsJobAppenderTest.java
index 94c50c91ee3..aa7f3fc06d4 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/statistics/StatisticsJobAppenderTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/statistics/StatisticsJobAppenderTest.java
@@ -34,7 +34,6 @@ import org.apache.doris.statistics.util.StatisticsUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
import mockit.Mock;
import mockit.MockUp;
import org.junit.jupiter.api.Assertions;
@@ -192,30 +191,29 @@ public class StatisticsJobAppenderTest {
StatisticsJobAppender appender = new StatisticsJobAppender();
appender.appendToLowJobs(testLowMap, testVeryLowMap);
Assertions.assertEquals(100, testLowMap.size());
+ Assertions.assertEquals(0, testVeryLowMap.size());
testLowMap.clear();
appender.appendToLowJobs(testLowMap, testVeryLowMap);
Assertions.assertEquals(40, testLowMap.size());
-
- for (int i = 0; i < StatisticsJobAppender.JOB_MAP_SIZE; i++) {
- Database db = new Database(id++, "testDb" + i);
- testCatalog.unprotectCreateDb(db);
- Column column1 = new Column("placeholder", PrimitiveType.INT);
- List<Column> schema = new ArrayList<>();
- schema.add(column1);
- OlapTable table1 = new OlapTable(id++, "testTable" + id + "_1",
schema, null, null, null);
- OlapTable table2 = new OlapTable(id++, "testTable" + id + "_1",
schema, null, null, null);
- db.createTableWithLock(table1, true, false);
- db.createTableWithLock(table2, true, false);
- }
-
+ Assertions.assertEquals(0, testVeryLowMap.size());
testLowMap.clear();
- appender.setLastRoundFinishTime(0);
+ // Less than 1 minutes since last iteration.
appender.appendToLowJobs(testLowMap, testVeryLowMap);
+ Assertions.assertEquals(0, testLowMap.size());
+ Assertions.assertEquals(0, testVeryLowMap.size());
+
+ testLowMap.clear();
appender.setLastRoundFinishTime(0);
- appender.appendToLowJobs(testLowMap, testVeryLowMap);
+ int processed = appender.appendToLowJobs(testLowMap, testVeryLowMap);
+ Assertions.assertEquals(100, testLowMap.size());
+ Assertions.assertEquals(0, testVeryLowMap.size());
+ Assertions.assertEquals(100, processed);
appender.setLastRoundFinishTime(0);
- appender.appendToLowJobs(testLowMap, testVeryLowMap);
+ processed = appender.appendToLowJobs(testLowMap, testVeryLowMap);
+ Assertions.assertEquals(100, testLowMap.size());
+ Assertions.assertEquals(0, testVeryLowMap.size());
Assertions.assertEquals(StatisticsJobAppender.JOB_MAP_SIZE,
testLowMap.size());
+ Assertions.assertEquals(0, processed);
}
@Test
@@ -260,7 +258,7 @@ public class StatisticsJobAppenderTest {
}
@Mock
- public boolean isLongTimeColumn(TableIf table, Pair<String,
String> column) {
+ public boolean isLongTimeColumn(TableIf table, Pair<String,
String> column, long version) {
return true;
}
};
@@ -268,33 +266,28 @@ public class StatisticsJobAppenderTest {
Map<TableName, Set<Pair<String, String>>> testLowMap = new HashMap<>();
Map<TableName, Set<Pair<String, String>>> testVeryLowMap = new
HashMap<>();
StatisticsJobAppender appender = new StatisticsJobAppender();
- appender.appendToLowJobs(testLowMap, testVeryLowMap);
+ int processed = appender.appendToLowJobs(testLowMap, testVeryLowMap);
+ Assertions.assertEquals(0, testLowMap.size());
Assertions.assertEquals(100, testVeryLowMap.size());
+ Assertions.assertEquals(100, processed);
testVeryLowMap.clear();
- appender.appendToLowJobs(testLowMap, testVeryLowMap);
+ processed = appender.appendToLowJobs(testLowMap, testVeryLowMap);
+ Assertions.assertEquals(0, testLowMap.size());
Assertions.assertEquals(40, testVeryLowMap.size());
-
- for (int i = 0; i < StatisticsJobAppender.JOB_MAP_SIZE; i++) {
- Database db = new Database(id++, "testDb" + i);
- testCatalog.unprotectCreateDb(db);
- Column column1 = new Column("placeholder", PrimitiveType.INT);
- List<Column> schema = new ArrayList<>();
- schema.add(column1);
- OlapTable table1 = new OlapTable(id++, "testTable" + id + "_1",
schema, null, null, null);
- OlapTable table2 = new OlapTable(id++, "testTable" + id + "_1",
schema, null, null, null);
- db.createTableWithLock(table1, true, false);
- db.createTableWithLock(table2, true, false);
- }
+ Assertions.assertEquals(40, processed);
testLowMap.clear();
appender.setLastRoundFinishTime(0);
- appender.appendToLowJobs(testLowMap, testVeryLowMap);
- appender.setLastRoundFinishTime(0);
- appender.appendToLowJobs(testLowMap, testVeryLowMap);
+ processed = appender.appendToLowJobs(testLowMap, testVeryLowMap);
+ Assertions.assertEquals(0, testLowMap.size());
+ Assertions.assertEquals(100, testVeryLowMap.size());
+ Assertions.assertEquals(100, processed);
+
appender.setLastRoundFinishTime(0);
- appender.appendToLowJobs(testLowMap, testVeryLowMap);
+ processed = appender.appendToLowJobs(testLowMap, testVeryLowMap);
Assertions.assertEquals(0, testLowMap.size());
- Assertions.assertEquals(StatisticsJobAppender.JOB_MAP_SIZE,
testVeryLowMap.size());
+ Assertions.assertEquals(100, testVeryLowMap.size());
+ Assertions.assertEquals(0, processed);
}
@Test
@@ -348,23 +341,19 @@ public class StatisticsJobAppenderTest {
@Test
public void testDoAppend() {
Map<TableName, Set<Pair<String, String>>> jobMap = Maps.newHashMap();
- Set<Pair<String, String>> columnIndexPairs1 = Sets.newHashSet();
- Set<Pair<String, String>> columnIndexPairs2 = Sets.newHashSet();
TableName tableName1 = new TableName("catalog1", "db1", "table1");
TableName tableName2 = new TableName("catalog2", "db2", "table2");
Pair<String, String> pair1 = Pair.of("index1", "col1");
- columnIndexPairs1.add(pair1);
StatisticsJobAppender appender = new StatisticsJobAppender();
- Assertions.assertTrue(appender.doAppend(jobMap, columnIndexPairs1,
tableName1));
+ Assertions.assertTrue(appender.doAppend(jobMap, pair1, tableName1));
Assertions.assertEquals(1, jobMap.size());
Assertions.assertTrue(jobMap.containsKey(tableName1));
Assertions.assertEquals(1, jobMap.get(tableName1).size());
Assertions.assertTrue(jobMap.get(tableName1).contains(pair1));
Pair<String, String> pair2 = Pair.of("index2", "col2");
- columnIndexPairs1.add(pair2);
- Assertions.assertTrue(appender.doAppend(jobMap, columnIndexPairs1,
tableName1));
+ Assertions.assertTrue(appender.doAppend(jobMap, pair2, tableName1));
Assertions.assertEquals(1, jobMap.size());
Assertions.assertTrue(jobMap.containsKey(tableName1));
Assertions.assertEquals(2, jobMap.get(tableName1).size());
@@ -372,8 +361,7 @@ public class StatisticsJobAppenderTest {
Assertions.assertTrue(jobMap.get(tableName1).contains(pair2));
Pair<String, String> pair3 = Pair.of("index3", "col3");
- columnIndexPairs2.add(pair3);
- Assertions.assertTrue(appender.doAppend(jobMap, columnIndexPairs2,
tableName2));
+ Assertions.assertTrue(appender.doAppend(jobMap, pair3, tableName2));
Assertions.assertEquals(2, jobMap.size());
Assertions.assertTrue(jobMap.containsKey(tableName2));
Assertions.assertEquals(1, jobMap.get(tableName2).size());
diff --git
a/fe/fe-core/src/test/java/org/apache/doris/statistics/util/StatisticsUtilTest.java
b/fe/fe-core/src/test/java/org/apache/doris/statistics/util/StatisticsUtilTest.java
index 8b641e01ebd..3ad3b6c977b 100644
---
a/fe/fe-core/src/test/java/org/apache/doris/statistics/util/StatisticsUtilTest.java
+++
b/fe/fe-core/src/test/java/org/apache/doris/statistics/util/StatisticsUtilTest.java
@@ -43,6 +43,7 @@ import org.apache.doris.datasource.jdbc.JdbcExternalCatalog;
import org.apache.doris.datasource.jdbc.JdbcExternalDatabase;
import org.apache.doris.datasource.jdbc.JdbcExternalTable;
import org.apache.doris.qe.SessionVariable;
+import org.apache.doris.rpc.RpcException;
import org.apache.doris.statistics.AnalysisManager;
import org.apache.doris.statistics.ColStatsMeta;
import org.apache.doris.statistics.ResultRow;
@@ -56,6 +57,7 @@ import mockit.MockUp;
import org.apache.iceberg.CatalogProperties;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
import java.nio.charset.StandardCharsets;
import java.time.LocalTime;
@@ -381,7 +383,7 @@ class StatisticsUtilTest {
OlapTable table = new OlapTable(200, "testTable", schema, null, null,
null);
// Test column is null
- Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table, null));
+ Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table, null,
0));
// Test table auto analyze is disabled.
new MockUp<OlapTable>() {
@@ -390,7 +392,7 @@ class StatisticsUtilTest {
return false;
}
};
- Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName())));
+ Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName()), 0));
new MockUp<OlapTable>() {
@Mock
public boolean autoAnalyzeEnabled() {
@@ -410,7 +412,7 @@ class StatisticsUtilTest {
props.put(CatalogProperties.WAREHOUSE_LOCATION, "s3://tmp");
IcebergExternalCatalog catalog = new IcebergHadoopExternalCatalog(0,
"iceberg_ctl", "", props, "");
IcebergExternalTable icebergTable = new IcebergExternalTable(0, "",
"", catalog, icebergDatabase);
- Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(icebergTable,
Pair.of("index", column.getName())));
+ Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(icebergTable,
Pair.of("index", column.getName()), 0));
// Test table stats meta is null.
new MockUp<AnalysisManager>() {
@@ -419,7 +421,7 @@ class StatisticsUtilTest {
return null;
}
};
- Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName())));
+ Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName()), 0));
// Test column stats meta is null
TableStatsMeta tableMeta = new TableStatsMeta();
@@ -435,7 +437,7 @@ class StatisticsUtilTest {
return null;
}
};
- Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName())));
+ Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName()), 0));
new MockUp<TableStatsMeta>() {
@Mock
public ColStatsMeta findColumnStatsMeta(String indexName, String
colName) {
@@ -445,16 +447,16 @@ class StatisticsUtilTest {
// Test table stats is user injected
tableMeta.userInjected = true;
- Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName())));
+ Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName()), 0));
tableMeta.userInjected = false;
// Test Config.auto_analyze_interval_seconds == 0
Config.auto_analyze_interval_seconds = 0;
- Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName())));
+ Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName()), 0));
// Test column analyzed within the time interval
Config.auto_analyze_interval_seconds = 86400;
- Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName())));
+ Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName()), 0));
// Test column hasn't analyzed for longer than time interval, but
version and row count doesn't change
new MockUp<TableStatsMeta>() {
@@ -481,7 +483,7 @@ class StatisticsUtilTest {
}
};
Config.auto_analyze_interval_seconds = 1;
- Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName())));
+ Assertions.assertFalse(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName()), 10));
// Test column hasn't analyzed for longer than time interval, and
version change
new MockUp<OlapTable>() {
@@ -495,7 +497,7 @@ class StatisticsUtilTest {
return 100;
}
};
- Assertions.assertTrue(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName())));
+ Assertions.assertTrue(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName()), 11));
// Test column hasn't analyzed for longer than time interval, and row
count change
new MockUp<OlapTable>() {
@@ -509,7 +511,7 @@ class StatisticsUtilTest {
return 101;
}
};
- Assertions.assertTrue(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName())));
+ Assertions.assertTrue(StatisticsUtil.isLongTimeColumn(table,
Pair.of("index", column.getName()), 10));
}
@Test
@@ -565,4 +567,14 @@ class StatisticsUtilTest {
Assertions.assertTrue(StatisticsUtil.canCollectColumn(column, table,
true, 1));
}
+
+ @Test
+ public void testGetOlapTableVersion() throws RpcException {
+ Assertions.assertEquals(0, StatisticsUtil.getOlapTableVersion(null));
+ OlapTable ot = Mockito.mock(OlapTable.class);
+ Mockito.when(ot.getVisibleVersion()).thenReturn(100L);
+ Assertions.assertEquals(100, StatisticsUtil.getOlapTableVersion(ot));
+ Mockito.when(ot.getVisibleVersion()).thenThrow(new RpcException("",
""));
+ Assertions.assertEquals(0, StatisticsUtil.getOlapTableVersion(ot));
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]