This is an automated email from the ASF dual-hosted git repository.
kxiao pushed a commit to branch branch-2.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-2.0 by this push:
new 44e4e6f7f25 [improvement](statistics)Optimize drop stats operation
(#30158)
44e4e6f7f25 is described below
commit 44e4e6f7f25ac95249d239970b689a5a9bfc708d
Author: Jibing-Li <[email protected]>
AuthorDate: Sun Jan 21 09:58:01 2024 +0800
[improvement](statistics)Optimize drop stats operation (#30158)
---
.../apache/doris/service/FrontendServiceImpl.java | 12 ++++-
.../apache/doris/statistics/AnalysisManager.java | 61 ++++++++++++++++------
.../doris/statistics/InvalidateStatsTarget.java | 36 +++++++++++++
.../apache/doris/statistics/StatisticsCache.java | 17 ++----
4 files changed, 93 insertions(+), 33 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
index 11b42913650..198fdf1d10a 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/service/FrontendServiceImpl.java
@@ -77,7 +77,10 @@ import org.apache.doris.qe.MasterCatalogExecutor;
import org.apache.doris.qe.QeProcessorImpl;
import org.apache.doris.qe.QueryState;
import org.apache.doris.qe.VariableMgr;
+import org.apache.doris.statistics.AnalysisManager;
+import org.apache.doris.statistics.InvalidateStatsTarget;
import org.apache.doris.statistics.StatisticsCacheKey;
+import org.apache.doris.statistics.TableStatsMeta;
import org.apache.doris.statistics.query.QueryStats;
import org.apache.doris.system.Backend;
import org.apache.doris.system.Frontend;
@@ -3088,8 +3091,13 @@ public class FrontendServiceImpl implements
FrontendService.Iface {
@Override
public TStatus invalidateStatsCache(TInvalidateFollowerStatsCacheRequest
request) throws TException {
- StatisticsCacheKey k = GsonUtils.GSON.fromJson(request.key,
StatisticsCacheKey.class);
- Env.getCurrentEnv().getStatisticsCache().invalidate(k.tableId,
k.idxId, k.colName);
+ InvalidateStatsTarget target = GsonUtils.GSON.fromJson(request.key,
InvalidateStatsTarget.class);
+ AnalysisManager analysisManager =
Env.getCurrentEnv().getAnalysisManager();
+ TableStatsMeta tableStats =
analysisManager.findTableStatsStatus(target.tableId);
+ if (tableStats == null) {
+ return new TStatus(TStatusCode.OK);
+ }
+ analysisManager.invalidateLocalStats(target.tableId, target.columns,
tableStats);
return new TStatus(TStatusCode.OK);
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/statistics/AnalysisManager.java
b/fe/fe-core/src/main/java/org/apache/doris/statistics/AnalysisManager.java
index fb7cf3ed384..742afe2957f 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/statistics/AnalysisManager.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/statistics/AnalysisManager.java
@@ -59,6 +59,9 @@ import org.apache.doris.statistics.AnalysisInfo.ScheduleType;
import org.apache.doris.statistics.util.DBObjects;
import org.apache.doris.statistics.util.SimpleQueue;
import org.apache.doris.statistics.util.StatisticsUtil;
+import org.apache.doris.system.Frontend;
+import org.apache.doris.system.SystemInfoService;
+import org.apache.doris.thrift.TInvalidateFollowerStatsCacheRequest;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
@@ -655,18 +658,9 @@ public class AnalysisManager implements Writable {
if (tableStats == null) {
return;
}
- if (cols == null) {
- tableStats.reset();
- } else {
- dropStatsStmt.getColumnNames().forEach(tableStats::removeColumn);
- StatisticsCache statisticsCache =
Env.getCurrentEnv().getStatisticsCache();
- for (String col : cols) {
- statisticsCache.syncInvalidate(tblId, -1L, col);
- }
- tableStats.updatedTime = 0;
- }
- tableStats.userInjected = false;
- logCreateTableStats(tableStats);
+ invalidateLocalStats(tblId, cols, tableStats);
+ // Drop stats ddl is master only operation.
+ invalidateRemoteStats(tblId, cols);
StatisticsRepository.dropStatistics(tblId, cols);
}
@@ -676,14 +670,47 @@ public class AnalysisManager implements Writable {
return;
}
Set<String> cols =
table.getBaseSchema().stream().map(Column::getName).collect(Collectors.toSet());
+ invalidateLocalStats(table.getId(), cols, tableStats);
+ // Drop stats ddl is master only operation.
+ invalidateRemoteStats(table.getId(), cols);
+ StatisticsRepository.dropStatistics(table.getId(), cols);
+ }
+
+ public void invalidateLocalStats(long tableId, Set<String> columns,
TableStatsMeta tableStats) {
+ if (tableStats == null) {
+ return;
+ }
StatisticsCache statisticsCache =
Env.getCurrentEnv().getStatisticsCache();
- for (String col : cols) {
- tableStats.removeColumn(col);
- statisticsCache.syncInvalidate(table.getId(), -1L, col);
+ if (columns != null) {
+ for (String column : columns) {
+ tableStats.removeColumn(column);
+ statisticsCache.invalidate(tableId, -1, column);
+ }
}
tableStats.updatedTime = 0;
- logCreateTableStats(tableStats);
- StatisticsRepository.dropStatistics(table.getId(), cols);
+ tableStats.userInjected = false;
+ }
+
+ public void invalidateRemoteStats(long tableId, Set<String> columns) {
+ InvalidateStatsTarget target = new InvalidateStatsTarget(tableId,
columns);
+ TInvalidateFollowerStatsCacheRequest request = new
TInvalidateFollowerStatsCacheRequest();
+ request.key = GsonUtils.GSON.toJson(target);
+ StatisticsCache statisticsCache =
Env.getCurrentEnv().getStatisticsCache();
+ SystemInfoService.HostInfo selfNode =
Env.getCurrentEnv().getSelfNode();
+ boolean success = true;
+ for (Frontend frontend : Env.getCurrentEnv().getFrontends(null)) {
+ // Skip master
+ if (selfNode.equals(frontend.getHost())) {
+ continue;
+ }
+ success = success && statisticsCache.invalidateStats(frontend,
request);
+ }
+ if (!success) {
+ // If any rpc failed, use edit log to sync table stats to
non-master FEs.
+ LOG.warn("Failed to invalidate all remote stats by rpc for table
{}, use edit log.", tableId);
+ TableStatsMeta tableStats = findTableStatsStatus(tableId);
+ logCreateTableStats(tableStats);
+ }
}
public void handleKillAnalyzeStmt(KillAnalysisJobStmt killAnalysisJobStmt)
throws DdlException {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/statistics/InvalidateStatsTarget.java
b/fe/fe-core/src/main/java/org/apache/doris/statistics/InvalidateStatsTarget.java
new file mode 100644
index 00000000000..1ee7b745048
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/statistics/InvalidateStatsTarget.java
@@ -0,0 +1,36 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package org.apache.doris.statistics;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.Set;
+
+public class InvalidateStatsTarget {
+
+ @SerializedName("tableId")
+ public final long tableId;
+
+ @SerializedName("columns")
+ public final Set<String> columns;
+
+ public InvalidateStatsTarget(long tableId, Set<String> columns) {
+ this.tableId = tableId;
+ this.columns = columns;
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/statistics/StatisticsCache.java
b/fe/fe-core/src/main/java/org/apache/doris/statistics/StatisticsCache.java
index fbec9a60fa0..0cf2808222e 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/statistics/StatisticsCache.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/statistics/StatisticsCache.java
@@ -137,19 +137,6 @@ public class StatisticsCache {
columnStatisticsCache.synchronous().invalidate(new
StatisticsCacheKey(tblId, idxId, colName));
}
- public void syncInvalidate(long tblId, long idxId, String colName) {
- StatisticsCacheKey cacheKey = new StatisticsCacheKey(tblId, idxId,
colName);
- columnStatisticsCache.synchronous().invalidate(cacheKey);
- TInvalidateFollowerStatsCacheRequest request = new
TInvalidateFollowerStatsCacheRequest();
- request.key = GsonUtils.GSON.toJson(cacheKey);
- for (Frontend frontend :
Env.getCurrentEnv().getFrontends(FrontendNodeType.FOLLOWER)) {
- if (StatisticsUtil.isMaster(frontend)) {
- continue;
- }
- invalidateStats(frontend, request);
- }
- }
-
public void updateColStatsCache(long tblId, long idxId, String colName,
ColumnStatistic statistic) {
columnStatisticsCache.synchronous().put(new StatisticsCacheKey(tblId,
idxId, colName), Optional.of(statistic));
}
@@ -261,7 +248,7 @@ public class StatisticsCache {
}
@VisibleForTesting
- public void invalidateStats(Frontend frontend,
TInvalidateFollowerStatsCacheRequest request) {
+ public boolean invalidateStats(Frontend frontend,
TInvalidateFollowerStatsCacheRequest request) {
TNetworkAddress address = new TNetworkAddress(frontend.getHost(),
frontend.getRpcPort());
FrontendService.Client client = null;
try {
@@ -269,11 +256,13 @@ public class StatisticsCache {
client.invalidateStatsCache(request);
} catch (Throwable t) {
LOG.warn("Failed to sync invalidate to follower: {}", address, t);
+ return false;
} finally {
if (client != null) {
ClientPool.frontendPool.returnObject(address, client);
}
}
+ return true;
}
public void putCache(StatisticsCacheKey k, ColumnStatistic c) {
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]