This is an automated email from the ASF dual-hosted git repository.

yiguolei pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/doris.git


The following commit(s) were added to refs/heads/branch-4.1 by this push:
     new 089c3658fd5 branch-4.1: [fix](doris catalog) FragmentMgr should not 
cancel virtual doris cluster query #62135 (#62213)
089c3658fd5 is described below

commit 089c3658fd556941ef74966f13e24b6f6ac1441e
Author: github-actions[bot] 
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Thu Apr 9 11:03:27 2026 +0800

    branch-4.1: [fix](doris catalog) FragmentMgr should not cancel virtual 
doris cluster query #62135 (#62213)
    
    Cherry-picked from #62135
    
    Co-authored-by: HonestManXin <[email protected]>
---
 be/src/runtime/fragment_mgr.cpp                    |  18 ++-
 be/src/runtime/query_context.cpp                   |   2 +
 be/src/runtime/query_context.h                     |   3 +-
 .../fragment_mgr_cross_cluster_cancel_test.cpp     | 156 +++++++++++++++++++++
 4 files changed, 175 insertions(+), 4 deletions(-)

diff --git a/be/src/runtime/fragment_mgr.cpp b/be/src/runtime/fragment_mgr.cpp
index ae22def3012..8f1edbd00df 100644
--- a/be/src/runtime/fragment_mgr.cpp
+++ b/be/src/runtime/fragment_mgr.cpp
@@ -764,9 +764,16 @@ Status FragmentMgr::_get_or_create_query_ctx(const 
TPipelineFragmentParams& para
 
                         // This may be a first fragment request of the query.
                         // Create the query fragments context.
-                        query_ctx = QueryContext::create(query_id, _exec_env, 
params.query_options,
-                                                         params.coord, 
params.is_nereids,
-                                                         
params.current_connect_fe, query_source);
+                        // Cross-cluster query: coordinator FE may not belong 
to local cluster.
+                        // In that case, cancel_worker() should not cancel it 
based on local FE liveness.
+                        QuerySource actual_query_source = query_source;
+                        if (query_source == QuerySource::INTERNAL_FRONTEND &&
+                            
!_exec_env->get_running_frontends().contains(params.coord)) {
+                            actual_query_source = 
QuerySource::EXTERNAL_FRONTEND;
+                        }
+                        query_ctx = QueryContext::create(
+                                query_id, _exec_env, params.query_options, 
params.coord,
+                                params.is_nereids, params.current_connect_fe, 
actual_query_source);
                         
SCOPED_SWITCH_THREAD_MEM_TRACKER_LIMITER(query_ctx->query_mem_tracker());
                         RETURN_IF_ERROR(DescriptorTbl::create(
                                 &(query_ctx->obj_pool), params.desc_tbl, 
&(query_ctx->desc_tbl)));
@@ -1119,6 +1126,11 @@ void FragmentMgr::_collect_invalid_queries(
                                  -> Status {
         for (const auto& it : map) {
             if (auto q_ctx = it.second.lock()) {
+                // Cross-cluster query: coordinator FE is not in local 
`running_fes`,
+                // we should not cancel it based on local coordinator liveness.
+                if (q_ctx->get_query_source() == 
QuerySource::EXTERNAL_FRONTEND) {
+                    continue;
+                }
                 q_contexts.push_back(q_ctx);
                 const int64_t fe_process_uuid = q_ctx->get_fe_process_uuid();
 
diff --git a/be/src/runtime/query_context.cpp b/be/src/runtime/query_context.cpp
index 198666346c0..e00a37aadb1 100644
--- a/be/src/runtime/query_context.cpp
+++ b/be/src/runtime/query_context.cpp
@@ -73,6 +73,8 @@ const std::string toString(QuerySource queryType) {
         return "ROUTINE_LOAD";
     case QuerySource::EXTERNAL_CONNECTOR:
         return "EXTERNAL_CONNECTOR";
+    case QuerySource::EXTERNAL_FRONTEND:
+        return "EXTERNAL_FRONTEND";
     default:
         return "UNKNOWN";
     }
diff --git a/be/src/runtime/query_context.h b/be/src/runtime/query_context.h
index c4ed6cafe85..d5e559890c0 100644
--- a/be/src/runtime/query_context.h
+++ b/be/src/runtime/query_context.h
@@ -70,7 +70,8 @@ enum class QuerySource {
     STREAM_LOAD,
     GROUP_COMMIT_LOAD,
     ROUTINE_LOAD,
-    EXTERNAL_CONNECTOR
+    EXTERNAL_CONNECTOR,
+    EXTERNAL_FRONTEND
 };
 
 const std::string toString(QuerySource query_source);
diff --git a/be/test/runtime/fragment_mgr_cross_cluster_cancel_test.cpp 
b/be/test/runtime/fragment_mgr_cross_cluster_cancel_test.cpp
new file mode 100644
index 00000000000..91c242f4b8f
--- /dev/null
+++ b/be/test/runtime/fragment_mgr_cross_cluster_cancel_test.cpp
@@ -0,0 +1,156 @@
+// 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.
+
+#include <gen_cpp/PaloInternalService_types.h>
+#include <gtest/gtest.h>
+
+#include "runtime/descriptor_helper.h"
+#include "runtime/exec_env.h"
+#include "runtime/fragment_mgr.h"
+#include "runtime/workload_group/workload_group_manager.h"
+
+namespace doris {
+
+class FragmentMgrCrossClusterCancelTest : public testing::Test {
+public:
+    void SetUp() override {
+        // Make frontends list deterministic for this ExecEnv instance.
+        _exec_env.update_frontends({});
+
+        _exec_env._workload_group_manager = new WorkloadGroupMgr();
+        // Ensure there is a "normal" workload group, otherwise 
WorkloadGroupMgr::get_group() will throw.
+        WorkloadGroupInfo normal_wg_info {.id = 1, .name = "normal"};
+        
_exec_env._workload_group_manager->get_or_create_workload_group(normal_wg_info);
+
+        _exec_env._fragment_mgr = new FragmentMgr(&_exec_env);
+    }
+
+    void TearDown() override {
+        if (_exec_env._fragment_mgr != nullptr) {
+            _exec_env._fragment_mgr->stop();
+        }
+        delete _exec_env._fragment_mgr;
+        _exec_env._fragment_mgr = nullptr;
+        delete _exec_env._workload_group_manager;
+        _exec_env._workload_group_manager = nullptr;
+        _exec_env.update_frontends({});
+    }
+
+protected:
+    static TDescriptorTable _make_min_desc_tbl() {
+        TDescriptorTableBuilder dtb;
+        TTupleDescriptorBuilder tuple_builder;
+        tuple_builder.add_slot(TSlotDescriptorBuilder()
+                                       .type(TYPE_INT)
+                                       .nullable(true)
+                                       .column_name("c1")
+                                       .column_pos(1)
+                                       .build());
+        tuple_builder.build(&dtb);
+        return dtb.desc_tbl();
+    }
+
+    static TQueryOptions _make_min_query_options(int64_t fe_process_uuid) {
+        TQueryOptions query_options;
+        query_options.__set_query_type(TQueryType::SELECT);
+        query_options.__set_execution_timeout(60);
+        query_options.__set_query_timeout(60);
+        query_options.__set_mem_limit(64L * 1024 * 1024);
+        query_options.__set_fe_process_uuid(fe_process_uuid);
+        return query_options;
+    }
+
+    ExecEnv _exec_env;
+};
+
+TEST_F(FragmentMgrCrossClusterCancelTest,
+       MarkQuerySourceAsExternalFrontendWhenCoordinatorNotLocal) {
+    auto* fragment_mgr = _exec_env.fragment_mgr();
+    ASSERT_NE(fragment_mgr, nullptr);
+
+    TUniqueId query_id;
+    query_id.__set_hi(1);
+    query_id.__set_lo(2);
+
+    TNetworkAddress coord;
+    coord.hostname = "fe-a";
+    coord.port = 9030;
+
+    TPipelineFragmentParams params;
+    params.__set_query_id(query_id);
+    params.__set_is_simplified_param(false);
+    params.__set_coord(coord);
+    params.__set_is_nereids(false);
+    params.__set_current_connect_fe(coord);
+    params.__set_fragment_num_on_host(1);
+    params.__set_query_options(_make_min_query_options(/*fe_process_uuid*/ 
123));
+    params.__set_desc_tbl(_make_min_desc_tbl());
+
+    std::shared_ptr<QueryContext> query_ctx;
+    TPipelineFragmentParamsList parent;
+    auto st = fragment_mgr->_get_or_create_query_ctx(params, parent, 
QuerySource::INTERNAL_FRONTEND,
+                                                     query_ctx);
+    ASSERT_TRUE(st.ok()) << st.to_string();
+    ASSERT_NE(query_ctx, nullptr);
+    EXPECT_EQ(query_ctx->get_query_source(), QuerySource::EXTERNAL_FRONTEND);
+}
+
+TEST_F(FragmentMgrCrossClusterCancelTest, 
CancelWorkerInvalidQueryDetectionSkipsExternalFrontend) {
+    auto* fragment_mgr = _exec_env.fragment_mgr();
+    ASSERT_NE(fragment_mgr, nullptr);
+
+    TUniqueId query_id;
+    query_id.__set_hi(3);
+    query_id.__set_lo(4);
+
+    TNetworkAddress coord;
+    coord.hostname = "fe-b";
+    coord.port = 9030;
+
+    TPipelineFragmentParams params;
+    params.__set_query_id(query_id);
+    params.__set_is_simplified_param(false);
+    params.__set_coord(coord);
+    params.__set_is_nereids(false);
+    params.__set_current_connect_fe(coord);
+    params.__set_fragment_num_on_host(1);
+    params.__set_query_options(_make_min_query_options(/*fe_process_uuid*/ 
456));
+    params.__set_desc_tbl(_make_min_desc_tbl());
+
+    std::shared_ptr<QueryContext> query_ctx;
+    TPipelineFragmentParamsList parent;
+    auto st = fragment_mgr->_get_or_create_query_ctx(params, parent, 
QuerySource::INTERNAL_FRONTEND,
+                                                     query_ctx);
+    ASSERT_TRUE(st.ok()) << st.to_string();
+    ASSERT_NE(query_ctx, nullptr);
+    ASSERT_EQ(query_ctx->get_query_source(), QuerySource::EXTERNAL_FRONTEND);
+
+    std::vector<TUniqueId> queries_lost_coordinator;
+    std::vector<TUniqueId> queries_pipeline_task_leak;
+    std::map<int64_t, std::unordered_set<TUniqueId>> 
running_queries_on_all_fes;
+    std::map<TNetworkAddress, FrontendInfo> running_fes;
+    timespec ts;
+    ts.tv_sec = 0;
+    ts.tv_nsec = 0;
+
+    fragment_mgr->_collect_invalid_queries(queries_lost_coordinator, 
queries_pipeline_task_leak,
+                                           running_queries_on_all_fes, 
running_fes, ts);
+    EXPECT_TRUE(queries_lost_coordinator.empty());
+    EXPECT_TRUE(queries_pipeline_task_leak.empty());
+}
+
+} // namespace doris


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to