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

Caideyipi pushed a commit to branch hotfix/2.0.9.4-sjzt
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 3aa3c3bfd6e2301d227e550ab192e5107f90aabf
Author: 田原 <[email protected]>
AuthorDate: Sun Apr 26 05:35:37 2026 +0000

    [TIMECHODB] fix: add non-blocking getTSStatus() to prevent ClientRPC thread 
hang during query cleanup
    
    (cherry picked from commit 1a54d7a3dd20c3a864af2613b09bac157405fc6c)
---
 .../apache/iotdb/db/queryengine/plan/Coordinator.java  | 18 +++++++++---------
 .../db/queryengine/plan/execution/IQueryExecution.java |  3 +++
 .../db/queryengine/plan/execution/QueryExecution.java  |  5 +++++
 .../plan/execution/config/ConfigExecution.java         |  5 +++++
 .../execution/operator/MergeTreeSortOperatorTest.java  |  6 ++++++
 5 files changed, 28 insertions(+), 9 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/Coordinator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/Coordinator.java
index 5aec3be48c5..c86d70a521b 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/Coordinator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/Coordinator.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.db.queryengine.plan;
 
 import org.apache.iotdb.common.rpc.thrift.TEndPoint;
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.commons.audit.AuditEventType;
 import org.apache.iotdb.commons.audit.AuditLogFields;
 import org.apache.iotdb.commons.audit.AuditLogOperation;
@@ -361,8 +362,8 @@ public class Coordinator {
       if (execution != null && isWrite && executionTime >= 
CONFIG.getSlowQueryThreshold()) {
         // Audit slow write operations
         PrivilegeType curType = isTreeModel ? PrivilegeType.WRITE_DATA : 
PrivilegeType.INSERT;
-        statusString =
-            execution.getStatus().status == null ? "null" : 
execution.getStatus().status.toString();
+        TSStatus tsStatus = execution.getTSStatus();
+        statusString = tsStatus == null ? "null" : tsStatus.toString();
         AuditLogFields auditLogFields =
             new AuditLogFields(
                 execution.getContext().getUserId(),
@@ -371,10 +372,9 @@ public class Coordinator {
                 AuditEventType.SLOW_OPERATION,
                 AuditLogOperation.DML,
                 curType,
-                execution.getStatus().status != null
-                    && (execution.getStatus().status.getCode()
-                            == TSStatusCode.SUCCESS_STATUS.getStatusCode()
-                        || execution.getStatus().status.getCode()
+                tsStatus != null
+                    && (tsStatus.getCode() == 
TSStatusCode.SUCCESS_STATUS.getStatusCode()
+                        || tsStatus.getCode()
                             == 
TSStatusCode.REDIRECTION_RECOMMEND.getStatusCode()),
                 execution.getContext().getDatabaseName().orElse(""),
                 execution.getExecuteSQL().orElse(""));
@@ -928,6 +928,7 @@ public class Coordinator {
       }
       if (isUserQuery
           && queryExecution.getTotalExecutionTime() / 1_000_000 >= 
CONFIG.getSlowQueryThreshold()) {
+        TSStatus tsStatus = queryExecution.getTSStatus();
         AuditLogFields auditLogFields =
             new AuditLogFields(
                 queryExecution.getContext().getUserId(),
@@ -938,9 +939,8 @@ public class Coordinator {
                 queryExecution.getSQLDialect() == 
IClientSession.SqlDialect.TREE
                     ? PrivilegeType.READ_DATA
                     : PrivilegeType.SELECT,
-                queryExecution.getStatus().status != null
-                    && queryExecution.getStatus().status.getCode()
-                        == TSStatusCode.SUCCESS_STATUS.getStatusCode(),
+                tsStatus != null
+                    && tsStatus.getCode() == 
TSStatusCode.SUCCESS_STATUS.getStatusCode(),
                 queryExecution.getContext().getDatabaseName().orElse(""),
                 queryExecution.getExecuteSQL().orElse(""));
         DNAuditLogger.getInstance()
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/IQueryExecution.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/IQueryExecution.java
index 340030f0b6b..bea6eee5533 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/IQueryExecution.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/IQueryExecution.java
@@ -19,6 +19,7 @@
 
 package org.apache.iotdb.db.queryengine.plan.execution;
 
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.commons.exception.IoTDBException;
 import org.apache.iotdb.db.protocol.session.IClientSession;
 import org.apache.iotdb.db.queryengine.common.MPPQueryContext;
@@ -42,6 +43,8 @@ public interface IQueryExecution {
 
   ExecutionResult getStatus();
 
+  TSStatus getTSStatus();
+
   Optional<TsBlock> getBatchResult() throws IoTDBException;
 
   Optional<ByteBuffer> getByteBufferBatchResult() throws IoTDBException;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/QueryExecution.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/QueryExecution.java
index d6537a68f7a..4a402a2b330 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/QueryExecution.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/QueryExecution.java
@@ -552,6 +552,11 @@ public class QueryExecution implements IQueryExecution {
    *
    * @return ExecutionStatus. Contains the QueryId and the TSStatus.
    */
+  @Override
+  public TSStatus getTSStatus() {
+    return getExecutionResult(stateMachine.getState()).status;
+  }
+
   @Override
   public ExecutionResult getStatus() {
     // Although we monitor the state to transition to RUNNING, the future will 
return if any
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/ConfigExecution.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/ConfigExecution.java
index 9e7c960829e..28366aa3cdc 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/ConfigExecution.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/ConfigExecution.java
@@ -242,6 +242,11 @@ public class ConfigExecution implements IQueryExecution {
     throw new UnsupportedOperationException(getClass().getName());
   }
 
+  @Override
+  public TSStatus getTSStatus() {
+    return getStatus().status;
+  }
+
   @Override
   public ExecutionResult getStatus() {
     try {
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/MergeTreeSortOperatorTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/MergeTreeSortOperatorTest.java
index 8f85a7cca7c..ac0d3234fad 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/MergeTreeSortOperatorTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/operator/MergeTreeSortOperatorTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.iotdb.db.queryengine.execution.operator;
 
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.commons.concurrent.IoTDBThreadPoolFactory;
 import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.path.NonAlignedFullPath;
@@ -1877,6 +1878,11 @@ public class MergeTreeSortOperatorTest {
       return null;
     }
 
+    @Override
+    public TSStatus getTSStatus() {
+      return null;
+    }
+
     @Override
     public Optional<TsBlock> getBatchResult() {
       return Optional.empty();

Reply via email to