This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-4.0 by this push:
new 3b4cabc1f61 branch-4.0: [fix](cloud) Add more prompt information when
compute group is invalid #56946 (#57747)
3b4cabc1f61 is described below
commit 3b4cabc1f611fe3cd00a01b01c658acab9659c0e
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Mon Nov 10 14:43:46 2025 +0800
branch-4.0: [fix](cloud) Add more prompt information when compute group is
invalid #56946 (#57747)
Cherry-picked from #56946
Co-authored-by: deardeng <[email protected]>
---
.../doris/cloud/load/CloudBrokerLoadJob.java | 4 +-
.../apache/doris/cloud/qe/CloudCoordinator.java | 7 ++--
.../doris/datasource/jdbc/JdbcExternalCatalog.java | 9 ++++-
.../BackendDistributedPlanWorkerManager.java | 5 ++-
.../java/org/apache/doris/qe/ConnectContext.java | 43 +++++++++++++++++++---
.../java/org/apache/doris/qe/StmtExecutor.java | 8 +++-
.../resource/computegroup/ComputeGroupMgr.java | 22 ++++++++++-
.../ExternalFileTableValuedFunction.java | 9 ++++-
.../tablefunction/NumbersTableValuedFunction.java | 9 ++++-
.../multi_cluster/test_no_cluster_hits.groovy | 34 ++++++++++++++---
10 files changed, 127 insertions(+), 23 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 09da8c38e7b..cd5c8dd1b0c 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;
@@ -107,7 +108,8 @@ public class CloudBrokerLoadJob extends BrokerLoadJob {
.getCloudClusterIdByName(clusterName);
if (Strings.isNullOrEmpty(this.cloudClusterId)) {
LOG.warn("can not find compute group: {}", clusterName);
- throw new MetaNotFoundException("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 feb93f20086..92b3ff4c0ac 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
@@ -28,6 +28,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;
@@ -85,10 +86,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 e5dd7c933fb..02921aaabbb 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;
@@ -415,7 +417,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/nereids/trees/plans/distribute/worker/BackendDistributedPlanWorkerManager.java
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/distribute/worker/BackendDistributedPlanWorkerManager.java
index 959bc9dbd8e..5ca2c4bc6bf 100644
---
a/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/distribute/worker/BackendDistributedPlanWorkerManager.java
+++
b/fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/distribute/worker/BackendDistributedPlanWorkerManager.java
@@ -27,6 +27,7 @@ import org.apache.doris.common.UserException;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.qe.SimpleScheduler;
import org.apache.doris.resource.computegroup.ComputeGroup;
+import org.apache.doris.resource.computegroup.ComputeGroupMgr;
import org.apache.doris.system.Backend;
import org.apache.doris.thrift.TNetworkAddress;
@@ -102,8 +103,8 @@ public class BackendDistributedPlanWorkerManager implements
DistributedPlanWorke
List<Backend> beList = cg.getBackendList();
if (beList.isEmpty()) {
LOG.warn("no available backends, compute group is {}",
cg.toString());
- throw new UserException("no available backends, the cluster maybe
not be set or been dropped clusterName = "
- + cg.getName());
+ String computeGroupHints =
ComputeGroupMgr.computeGroupNotFoundPromptMsg(cg.getName());
+ throw new UserException(computeGroupHints);
}
Map<Long, Backend> idToBeMap = Maps.newHashMap();
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 607ccf693f4..8df0a2fef0b 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
@@ -40,6 +40,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;
@@ -1430,7 +1431,7 @@ public class ConnectContext {
}
// 2 get cluster from user
- String userPropCluster = getDefaultCloudClusterFromUser();
+ String userPropCluster = getDefaultCloudClusterFromUser(true);
if (!StringUtils.isEmpty(userPropCluster)) {
choseWay = "user property";
if (LOG.isDebugEnabled()) {
@@ -1483,17 +1484,49 @@ public class ConnectContext {
return this.cloudCluster;
}
- // TODO implement this function
- private String getDefaultCloudClusterFromUser() {
- List<String> cloudClusterNames = ((CloudSystemInfoService)
Env.getCurrentSystemInfo()).getCloudClusterNames();
+ private String getDefaultCloudClusterFromUser(boolean checkExist) {
String defaultCluster =
Env.getCurrentEnv().getAuth().getDefaultCloudCluster(getQualifiedUser());
- if (!Strings.isNullOrEmpty(defaultCluster) &&
cloudClusterNames.contains(defaultCluster)) {
+ 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 StatsErrorEstimator getStatsErrorEstimator() {
return statsErrorEstimator;
}
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 d8d86ecf94e..2c4b36197ea 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
@@ -120,6 +120,7 @@ import org.apache.doris.qe.QueryState.MysqlStateType;
import org.apache.doris.qe.cache.Cache;
import org.apache.doris.qe.cache.CacheAnalyzer;
import org.apache.doris.qe.cache.SqlCache;
+import org.apache.doris.resource.computegroup.ComputeGroupMgr;
import org.apache.doris.rpc.BackendServiceProxy;
import org.apache.doris.rpc.RpcException;
import org.apache.doris.statistics.ResultRow;
@@ -1438,7 +1439,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
index e7a58ead33b..23319b572b6 100644
---
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
@@ -20,7 +20,9 @@ package org.apache.doris.resource.computegroup;
import org.apache.doris.catalog.Env;
import org.apache.doris.cloud.system.CloudSystemInfoService;
import org.apache.doris.common.Config;
+import org.apache.doris.common.Pair;
import org.apache.doris.common.UserException;
+import org.apache.doris.qe.ConnectContext;
import org.apache.doris.resource.Tag;
import org.apache.doris.system.Backend;
import org.apache.doris.system.SystemInfoService;
@@ -38,6 +40,22 @@ public class ComputeGroupMgr {
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();
+ }
+
public ComputeGroup getComputeGroupByName(String name) throws
UserException {
if (Config.isCloudMode()) {
CloudSystemInfoService cloudSystemInfoService =
(CloudSystemInfoService) systemInfoService;
@@ -45,8 +63,8 @@ public class ComputeGroupMgr {
.getPhysicalCluster(name);
String clusterId =
cloudSystemInfoService.getCloudClusterIdByName(physicalClusterName);
if (StringUtils.isEmpty(clusterId)) {
- throw new UserException("Can not find compute group:" + name
- + " real compute group name:" + physicalClusterName);
+ String computeGroupHints =
ComputeGroupMgr.computeGroupNotFoundPromptMsg(physicalClusterName);
+ throw new UserException(computeGroupHints);
}
return new CloudComputeGroup(clusterId, physicalClusterName,
cloudSystemInfoService);
} else {
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 11877fe6508..b1030cb1657 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;
@@ -60,6 +61,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;
@@ -249,7 +251,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 f7959267668..2c98e2f68ad 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 = Can not find compute
group:compute_cluster
- 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("Can not find compute group"))
+ 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]