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 ede0dfc1210 branch-3.1: [fix](cloud) Add more prompt information when
compute group is invalid #56946 (#58225)
ede0dfc1210 is described below
commit ede0dfc1210118d73699d9e9e2994623a4b6432e
Author: deardeng <[email protected]>
AuthorDate: Tue Nov 25 12:10:12 2025 +0800
branch-3.1: [fix](cloud) Add more prompt information when compute group is
invalid #56946 (#58225)
cherry pick from #56946
---
.../doris/cloud/load/CloudBrokerLoadJob.java | 6 +-
.../apache/doris/cloud/qe/CloudCoordinator.java | 7 +--
.../doris/datasource/jdbc/JdbcExternalCatalog.java | 9 ++-
.../java/org/apache/doris/qe/ConnectContext.java | 69 +++++++++++++++++++++-
.../java/org/apache/doris/qe/StmtExecutor.java | 8 ++-
.../resource/computegroup/ComputeGroupMgr.java | 47 +++++++++++++++
.../ExternalFileTableValuedFunction.java | 9 ++-
.../tablefunction/NumbersTableValuedFunction.java | 9 ++-
.../multi_cluster/test_no_cluster_hits.groovy | 34 +++++++++--
9 files changed, 182 insertions(+), 16 deletions(-)
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/cloud/load/CloudBrokerLoadJob.java
b/fe/fe-core/src/main/java/org/apache/doris/cloud/load/CloudBrokerLoadJob.java
index 2cbfc57c833..8c10f6e963c 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/cloud/load/CloudBrokerLoadJob.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/cloud/load/CloudBrokerLoadJob.java
@@ -46,6 +46,7 @@ import org.apache.doris.qe.Coordinator;
import org.apache.doris.qe.OriginStatement;
import org.apache.doris.qe.QeProcessorImpl;
import org.apache.doris.qe.StmtExecutor;
+import org.apache.doris.resource.computegroup.ComputeGroupMgr;
import org.apache.doris.system.Backend;
import org.apache.doris.thrift.TStatusCode;
import org.apache.doris.thrift.TUniqueId;
@@ -111,8 +112,9 @@ public class CloudBrokerLoadJob extends BrokerLoadJob {
((CloudSystemInfoService)
Env.getCurrentSystemInfo()).getCloudClusterIdByName(clusterName);
}
if (Strings.isNullOrEmpty(this.cloudClusterId)) {
- LOG.warn("cluster id is empty, cluster name {}", clusterName);
- throw new MetaNotFoundException("cluster id is empty, cluster
name: " + clusterName);
+ LOG.warn("can not find compute group: {}", clusterName);
+ String computeGroupHints =
ComputeGroupMgr.computeGroupNotFoundPromptMsg(clusterName);
+ throw new MetaNotFoundException(computeGroupHints);
}
sessionVariables.put(CLOUD_CLUSTER_ID, this.cloudClusterId);
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/cloud/qe/CloudCoordinator.java
b/fe/fe-core/src/main/java/org/apache/doris/cloud/qe/CloudCoordinator.java
index 2a69e84352d..c051b35103c 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/cloud/qe/CloudCoordinator.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/cloud/qe/CloudCoordinator.java
@@ -29,6 +29,7 @@ import org.apache.doris.planner.Planner;
import org.apache.doris.planner.ScanNode;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.Coordinator;
+import org.apache.doris.resource.computegroup.ComputeGroupMgr;
import org.apache.doris.thrift.TUniqueId;
import com.google.common.base.Strings;
@@ -86,10 +87,8 @@ public class CloudCoordinator extends Coordinator {
if (idToBackend == null || idToBackend.isEmpty()) {
LOG.warn("no available backends, idToBackend {}", idToBackend);
- String clusterName = ConnectContext.get() != null
- ? ConnectContext.get().getCloudCluster() : "ctx empty cant
get clusterName";
- throw new UserException("no available backends, the cluster maybe
not be set or been dropped clusterName = "
- + clusterName);
+ String computeGroupHints =
ComputeGroupMgr.computeGroupNotFoundPromptMsg(cluster);
+ throw new UserException(computeGroupHints);
}
}
}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalCatalog.java
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalCatalog.java
index 642242be419..d852b9df554 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalCatalog.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/datasource/jdbc/JdbcExternalCatalog.java
@@ -23,6 +23,7 @@ import org.apache.doris.catalog.JdbcResource;
import org.apache.doris.catalog.JdbcTable;
import org.apache.doris.catalog.TableIf.TableType;
import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.Config;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.FeConstants;
import org.apache.doris.datasource.CatalogProperty;
@@ -40,6 +41,7 @@ import
org.apache.doris.datasource.mapping.JdbcIdentifierMapping;
import org.apache.doris.proto.InternalService;
import org.apache.doris.proto.InternalService.PJdbcTestConnectionRequest;
import org.apache.doris.proto.InternalService.PJdbcTestConnectionResult;
+import org.apache.doris.resource.computegroup.ComputeGroupMgr;
import org.apache.doris.rpc.BackendServiceProxy;
import org.apache.doris.rpc.RpcException;
import org.apache.doris.system.Backend;
@@ -411,7 +413,12 @@ public class JdbcExternalCatalog extends ExternalCatalog {
throw new DdlException(e.getMessage());
}
if (aliveBe == null) {
- throw new DdlException("Test BE Connection to JDBC Failed: No
Alive backends");
+ String computeGroupHints = "";
+ if (Config.isCloudMode()) {
+ // null: computeGroupNotFoundPromptMsg select cluster for hint
msg
+ computeGroupHints =
ComputeGroupMgr.computeGroupNotFoundPromptMsg(null);
+ }
+ throw new DdlException("Test BE Connection to JDBC Failed: No
Alive backends" + computeGroupHints);
}
TNetworkAddress address = new TNetworkAddress(aliveBe.getHost(),
aliveBe.getBrpcPort());
try {
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java
b/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java
index d6888cf6caa..f8a1678bf42 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/ConnectContext.java
@@ -41,6 +41,7 @@ import org.apache.doris.common.Config;
import org.apache.doris.common.DdlException;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.FeConstants;
+import org.apache.doris.common.Pair;
import org.apache.doris.common.Status;
import org.apache.doris.common.UserException;
import org.apache.doris.common.util.DebugUtil;
@@ -1391,6 +1392,30 @@ public class ConnectContext {
String cluster = null;
String choseWay = null;
+ // 1 get cluster from session
+ String sessionCluster = getSessionVariable().getCloudCluster();
+ if (!Strings.isNullOrEmpty(sessionCluster)) {
+ choseWay = "use session";
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("finally set context compute group name {} for user
{} with chose way '{}'",
+ sessionCluster, getCurrentUserIdentity(), choseWay);
+ }
+ return sessionCluster;
+ }
+
+ // 2 get cluster from user
+ String userPropCluster = getDefaultCloudClusterFromUser(true);
+ if (!StringUtils.isEmpty(userPropCluster)) {
+ choseWay = "user property";
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("finally set context compute group name {} for user
{} with chose way '{}'", userPropCluster,
+ getCurrentUserIdentity(), choseWay);
+ }
+ return userPropCluster;
+ }
+
+ // 3 get cluster from a cached variable in connect context
+ // this value comes from a cluster selection policy
if (!Strings.isNullOrEmpty(this.cloudCluster)) {
cluster = this.cloudCluster;
choseWay = "use context cluster";
@@ -1429,7 +1454,49 @@ public class ConnectContext {
return cluster;
}
- // TODO implement this function
+ private String getDefaultCloudClusterFromUser(boolean checkExist) {
+ String defaultCluster =
Env.getCurrentEnv().getAuth().getDefaultCloudCluster(getQualifiedUser());
+ if (Strings.isNullOrEmpty(defaultCluster)) {
+ return null;
+ }
+ if (!checkExist) {
+ // default cluster may be dropped.
+ return defaultCluster;
+ }
+
+ // Validate cluster existence
+ List<String> cloudClusterNames = ((CloudSystemInfoService)
Env.getCurrentSystemInfo()).getCloudClusterNames();
+ if (cloudClusterNames.contains(defaultCluster)) {
+ return defaultCluster;
+ }
+ LOG.warn("default compute group {} of user {} is invalid, all cluster:
{}", defaultCluster,
+ getQualifiedUser(), cloudClusterNames);
+ return null;
+ }
+
+ // for log use, compute group name and the way to get it
+ // the way may be context policy, session, default compute group from user
+ public static Pair<String, String> computeGroupFromHintMsg() {
+ String clusterName = "";
+ try {
+ if (ConnectContext.get() != null) {
+ clusterName = ConnectContext.get().getCloudCluster();
+ }
+ } catch (Exception e) {
+ clusterName = "ctx empty cant get clusterName";
+
+ }
+ String fromSession =
ConnectContext.get().getSessionVariable().getCloudCluster();
+ String fromDefaultComputeGroup =
ConnectContext.get().getDefaultCloudClusterFromUser(false);
+ String clusterFrom = "context policy";
+ if (clusterName.equalsIgnoreCase(fromSession)) {
+ clusterFrom = "session variable";
+ } else if (clusterName.equalsIgnoreCase(fromDefaultComputeGroup)) {
+ clusterFrom = "default compute group from user";
+ }
+ return Pair.of(clusterName, clusterFrom);
+ }
+
public String getDefaultCloudCluster() {
List<String> cloudClusterNames = ((CloudSystemInfoService)
Env.getCurrentSystemInfo()).getCloudClusterNames();
String defaultCluster =
Env.getCurrentEnv().getAuth().getDefaultCloudCluster(getQualifiedUser());
diff --git a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java
b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java
index 3383651f779..fedf66289b8 100644
--- a/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java
+++ b/fe/fe-core/src/main/java/org/apache/doris/qe/StmtExecutor.java
@@ -188,6 +188,7 @@ import org.apache.doris.qe.cache.Cache;
import org.apache.doris.qe.cache.CacheAnalyzer;
import org.apache.doris.qe.cache.CacheAnalyzer.CacheMode;
import org.apache.doris.qe.cache.SqlCache;
+import org.apache.doris.resource.computegroup.ComputeGroupMgr;
import org.apache.doris.rewrite.ExprRewriter;
import org.apache.doris.rewrite.mvrewrite.MVSelectFailedException;
import org.apache.doris.rpc.BackendServiceProxy;
@@ -2096,7 +2097,12 @@ public class StmtExecutor {
}
}
if (address == null) {
- throw new AnalysisException("No Alive backends");
+ String computeGroupHints = "";
+ if (Config.isCloudMode()) {
+ // null: computeGroupNotFoundPromptMsg select cluster for hint
msg
+ computeGroupHints =
ComputeGroupMgr.computeGroupNotFoundPromptMsg(null);
+ }
+ throw new AnalysisException("No Alive backends" +
computeGroupHints);
}
// 5. send rpc to BE
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/resource/computegroup/ComputeGroupMgr.java
b/fe/fe-core/src/main/java/org/apache/doris/resource/computegroup/ComputeGroupMgr.java
new file mode 100644
index 00000000000..569e9b8f3f2
--- /dev/null
+++
b/fe/fe-core/src/main/java/org/apache/doris/resource/computegroup/ComputeGroupMgr.java
@@ -0,0 +1,47 @@
+// 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.resource.computegroup;
+
+import org.apache.doris.common.Pair;
+import org.apache.doris.qe.ConnectContext;
+import org.apache.doris.system.SystemInfoService;
+
+public class ComputeGroupMgr {
+
+ private SystemInfoService systemInfoService;
+
+ public ComputeGroupMgr(SystemInfoService systemInfoService) {
+ this.systemInfoService = systemInfoService;
+ }
+
+ public static String computeGroupNotFoundPromptMsg(String
physicalClusterName) {
+ StringBuilder sb = new StringBuilder();
+ Pair<String, String> computeGroupInfos =
ConnectContext.computeGroupFromHintMsg();
+ sb.append(" Unable to find the compute group: ");
+ sb.append("<");
+ if (physicalClusterName == null) {
+ sb.append(computeGroupInfos.first);
+ } else {
+ sb.append(physicalClusterName);
+ }
+ sb.append(">");
+ sb.append(". Please check if the compute group has been deleted. how
this compute group is selected: ");
+ sb.append(computeGroupInfos.second);
+ return sb.toString();
+ }
+}
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/ExternalFileTableValuedFunction.java
b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/ExternalFileTableValuedFunction.java
index 9f9f769c780..e67d695bd8e 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/ExternalFileTableValuedFunction.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/ExternalFileTableValuedFunction.java
@@ -32,6 +32,7 @@ import org.apache.doris.catalog.StructType;
import org.apache.doris.catalog.Table;
import org.apache.doris.catalog.Type;
import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.Config;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.Pair;
import org.apache.doris.common.UserException;
@@ -57,6 +58,7 @@ import org.apache.doris.proto.Types.PTypeDesc;
import org.apache.doris.proto.Types.PTypeNode;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.SessionVariable;
+import org.apache.doris.resource.computegroup.ComputeGroupMgr;
import org.apache.doris.rpc.BackendServiceProxy;
import org.apache.doris.rpc.RpcException;
import org.apache.doris.system.Backend;
@@ -234,7 +236,12 @@ public abstract class ExternalFileTableValuedFunction
extends TableValuedFunctio
columns = Lists.newArrayList();
Backend be = getBackend();
if (be == null) {
- throw new AnalysisException("No Alive backends");
+ String computeGroupHints = "";
+ if (Config.isCloudMode()) {
+ // null: computeGroupNotFoundPromptMsg select cluster for hint
msg
+ computeGroupHints =
ComputeGroupMgr.computeGroupNotFoundPromptMsg(null);
+ }
+ throw new AnalysisException("No Alive backends" +
computeGroupHints);
}
if (fileFormatProperties.getFileFormatType() ==
TFileFormatType.FORMAT_WAL) {
diff --git
a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/NumbersTableValuedFunction.java
b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/NumbersTableValuedFunction.java
index b40658e4796..e3486123ddb 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/tablefunction/NumbersTableValuedFunction.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/tablefunction/NumbersTableValuedFunction.java
@@ -21,6 +21,8 @@ import org.apache.doris.catalog.Column;
import org.apache.doris.catalog.Env;
import org.apache.doris.catalog.PrimitiveType;
import org.apache.doris.common.AnalysisException;
+import org.apache.doris.common.Config;
+import org.apache.doris.resource.computegroup.ComputeGroupMgr;
import org.apache.doris.system.Backend;
import org.apache.doris.thrift.TDataGenFunctionName;
import org.apache.doris.thrift.TDataGenScanRange;
@@ -122,7 +124,12 @@ public class NumbersTableValuedFunction extends
DataGenTableValuedFunction {
}
}
if (backendList.isEmpty()) {
- throw new AnalysisException("No Alive backends");
+ String computeGroupHints = "";
+ if (Config.isCloudMode()) {
+ // null: computeGroupNotFoundPromptMsg select cluster for hint
msg
+ computeGroupHints =
ComputeGroupMgr.computeGroupNotFoundPromptMsg(null);
+ }
+ throw new AnalysisException("No Alive backends" +
computeGroupHints);
}
Collections.shuffle(backendList);
diff --git
a/regression-test/suites/cloud_p0/multi_cluster/test_no_cluster_hits.groovy
b/regression-test/suites/cloud_p0/multi_cluster/test_no_cluster_hits.groovy
index 82a77ecb368..41c1ad21ed5 100644
--- a/regression-test/suites/cloud_p0/multi_cluster/test_no_cluster_hits.groovy
+++ b/regression-test/suites/cloud_p0/multi_cluster/test_no_cluster_hits.groovy
@@ -134,6 +134,7 @@ suite('test_no_cluster_hits', 'multi_cluster, docker') {
assertTrue(e.getMessage().contains("ComputeGroupException:
CURRENT_USER_NO_AUTH_TO_USE_COMPUTE_GROUP"))
assertTrue(e.getMessage().contains("set default compute group
failed"))
}
+ sql """SET PROPERTY FOR 'root' 'default_cloud_cluster' =
${currentCluster.cluster}"""
// no cluster
def tag = getCloudBeTagByName(currentCluster.cluster)
@@ -153,14 +154,37 @@ suite('test_no_cluster_hits', 'multi_cluster, docker') {
result.size() == 0
}
+ cluster.addBackend(1, "testCluster")
+
try {
- // errCode = 2, detailMessage = The current compute group
compute_cluster is not registered in the system
- sql """
- select * from $table
- """
+ // test root's default cluster invalid
+ connectInDocker('root', '') {
+ sql """insert into $table values (3, 3)"""
+ }
+ } catch (Exception e) {
+ logger.info("exception: {}", e.getMessage())
+ assertTrue(e.getMessage().contains("Unable to find the compute
group: <compute_cluster>"))
+ }
+
+ try {
+ connectInDocker('root', '') {
+ sql """select * from $table"""
+ }
} catch (Exception e) {
logger.info("exception: {}", e.getMessage())
- assertTrue(e.getMessage().contains("The current compute group
compute_cluster is not registered in the system"))
+ assertTrue(e.getMessage().contains("Unable to find the compute
group: <compute_cluster>"))
}
+
+
+ try {
+ // test tvf
+ connectInDocker('root', '') {
+ sql """select * from numbers("number" = "100")"""
+ }
+ } catch (Exception e) {
+ logger.info("exception: {}", e.getMessage())
+ assertTrue(e.getMessage().contains("how this compute group is
selected: default compute group from user"))
+ }
+
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]