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

JackieTien97 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/master by this push:
     new 3f36587d7c4 Downgrade the level of log when auto sync column schema 
(#19060)
3f36587d7c4 is described below

commit 3f36587d7c4a775ca215fd45ff29d2a7b788944a
Author: alpass163 <[email protected]>
AuthorDate: Fri Oct 30 12:46:16 2026 +0800

    Downgrade the level of log when auto sync column schema (#19060)
---
 .../iotdb/confignode/i18n/ConfigNodeMessages.java  |  2 +
 .../iotdb/confignode/i18n/ProcedureMessages.java   |  3 +-
 .../iotdb/confignode/i18n/ConfigNodeMessages.java  |  1 +
 .../iotdb/confignode/i18n/ProcedureMessages.java   |  3 +-
 .../rpc/TreeDeviceViewFieldDetectionHandler.java   | 56 ++++++++++++++++++++++
 .../manager/schema/ClusterSchemaManager.java       |  2 -
 .../impl/schema/table/AddTableColumnProcedure.java |  2 +-
 .../iotdb/db/i18n/DataNodeSchemaMessages.java      |  2 +-
 .../iotdb/db/i18n/DataNodeSchemaMessages.java      |  2 +-
 .../table/ViewColumnAutoSyncTrigger.java           | 32 ++++++++-----
 10 files changed, 86 insertions(+), 19 deletions(-)

diff --git 
a/iotdb-core/confignode/src/main/i18n/en/org/apache/iotdb/confignode/i18n/ConfigNodeMessages.java
 
b/iotdb-core/confignode/src/main/i18n/en/org/apache/iotdb/confignode/i18n/ConfigNodeMessages.java
index cfde56c6419..6d4ef566731 100644
--- 
a/iotdb-core/confignode/src/main/i18n/en/org/apache/iotdb/confignode/i18n/ConfigNodeMessages.java
+++ 
b/iotdb-core/confignode/src/main/i18n/en/org/apache/iotdb/confignode/i18n/ConfigNodeMessages.java
@@ -312,6 +312,8 @@ public final class ConfigNodeMessages {
       "Failed to {} on DataNode: {}, exception: {}";
   public static final String FAILED_TO_ON_DATANODE_RESPONSE =
       "Failed to {} on DataNode: {}, response: {}";
+  public static final String FAILED_TO_ON_DATANODE_WITH_STATUS =
+      "Failed to {} on DataNode: {}, code: {}, message: {}";
   public static final String FAILED_TO_OPERATE_PIPE = "Failed to operate pipe";
   public static final String FAILED_TO_SET_PIPE_STATUS = "Failed to set pipe 
status";
   public static final String 
FAILED_TO_SET_PIPE_STATUS_WITH_STOPPED_BY_RUNTIME_EXCEPTION =
diff --git 
a/iotdb-core/confignode/src/main/i18n/en/org/apache/iotdb/confignode/i18n/ProcedureMessages.java
 
b/iotdb-core/confignode/src/main/i18n/en/org/apache/iotdb/confignode/i18n/ProcedureMessages.java
index 488e7cc7598..46a278848c9 100644
--- 
a/iotdb-core/confignode/src/main/i18n/en/org/apache/iotdb/confignode/i18n/ProcedureMessages.java
+++ 
b/iotdb-core/confignode/src/main/i18n/en/org/apache/iotdb/confignode/i18n/ProcedureMessages.java
@@ -873,9 +873,10 @@ public final class ProcedureMessages {
       "Retrievable error trying to drop pipe plugin [{}], state: {}";
   public static final String RETRIEVABLE_ERROR_TRYING_TO_REMOVE_AINODE_STATE =
       "Retrievable error trying to remove AINode [{}], state [{}]";
+  public static final String ROLLBACK_ADDTABLECOLUMN_COSTS_MS =
+      "Rollback AddTableColumn-{} costs {}ms.";
   public static final String ROLLBACK_CREATETABLE_COSTS_MS = "Rollback 
CreateTable-{} costs {}ms.";
   public static final String ROLLBACK_CREATE_TABLE_FAILED = "Rollback create 
table failed";
-  public static final String ROLLBACK_DROPTABLE_COSTS_MS = "Rollback 
DropTable-{} costs {}ms.";
   public static final String ROLLBACK_PRE_DELETE_TABLE_FAILED =
       "Rollback pre-delete table %s.%s failed, please manually drop the table 
by entering sql";
   public static final String ROLLBACK_PRE_RELEASE = "Rollback pre-release ";
diff --git 
a/iotdb-core/confignode/src/main/i18n/zh/org/apache/iotdb/confignode/i18n/ConfigNodeMessages.java
 
b/iotdb-core/confignode/src/main/i18n/zh/org/apache/iotdb/confignode/i18n/ConfigNodeMessages.java
index ddf8be67cef..24ac3abb074 100644
--- 
a/iotdb-core/confignode/src/main/i18n/zh/org/apache/iotdb/confignode/i18n/ConfigNodeMessages.java
+++ 
b/iotdb-core/confignode/src/main/i18n/zh/org/apache/iotdb/confignode/i18n/ConfigNodeMessages.java
@@ -290,6 +290,7 @@ public final class ConfigNodeMessages {
   public static final String FAILED_TO_ON_DATANODE = "在 DataNode {} 上执行 {} 
失败,{}";
   public static final String FAILED_TO_ON_DATANODE_EXCEPTION = "在 DataNode: {} 
上执行 {} 失败,异常:{}";
   public static final String FAILED_TO_ON_DATANODE_RESPONSE = "在 DataNode: {} 
上执行 {} 失败,响应:{}";
+  public static final String FAILED_TO_ON_DATANODE_WITH_STATUS = "执行 {} 
失败(DataNode: {}),状态码:{},信息:{}";
   public static final String FAILED_TO_OPERATE_PIPE = "操作 pipe 失败";
   public static final String FAILED_TO_SET_PIPE_STATUS = "设置 pipe 状态失败";
   public static final String 
FAILED_TO_SET_PIPE_STATUS_WITH_STOPPED_BY_RUNTIME_EXCEPTION =
diff --git 
a/iotdb-core/confignode/src/main/i18n/zh/org/apache/iotdb/confignode/i18n/ProcedureMessages.java
 
b/iotdb-core/confignode/src/main/i18n/zh/org/apache/iotdb/confignode/i18n/ProcedureMessages.java
index d65ee58ec53..e972e688ae6 100644
--- 
a/iotdb-core/confignode/src/main/i18n/zh/org/apache/iotdb/confignode/i18n/ProcedureMessages.java
+++ 
b/iotdb-core/confignode/src/main/i18n/zh/org/apache/iotdb/confignode/i18n/ProcedureMessages.java
@@ -830,9 +830,10 @@ public final class ProcedureMessages {
       "尝试删除 pipe plugin [{}] 时发生可重试错误,状态:{}";
   public static final String RETRIEVABLE_ERROR_TRYING_TO_REMOVE_AINODE_STATE =
       "尝试移除 AINode [{}] 时发生可重试错误,状态 [{}]";
+  public static final String ROLLBACK_ADDTABLECOLUMN_COSTS_MS =
+      "Rollback AddTableColumn-{} costs {}ms.";
   public static final String ROLLBACK_CREATETABLE_COSTS_MS = "Rollback 
CreateTable-{} costs {}ms.";
   public static final String ROLLBACK_CREATE_TABLE_FAILED = "回滚创建表失败";
-  public static final String ROLLBACK_DROPTABLE_COSTS_MS = "Rollback 
DropTable-{} costs {}ms.";
   public static final String ROLLBACK_PRE_RELEASE = "回滚预释放 ";
   public static final String ROLLBACK_PRE_DELETE_TABLE_FAILED = "回滚预删除表 %s.%s 
操作失败, 请手动输入sql删除";
   public static final String ROLLBACK_PRE_RELEASE_TEMPLATE_FAILED = 
"回滚预释放模板失败";
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/TreeDeviceViewFieldDetectionHandler.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/TreeDeviceViewFieldDetectionHandler.java
index 71bc289ccb4..2471eff8744 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/TreeDeviceViewFieldDetectionHandler.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/handlers/rpc/TreeDeviceViewFieldDetectionHandler.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.confignode.client.async.handlers.rpc;
 
 import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
+import org.apache.iotdb.common.rpc.thrift.TSStatus;
 import org.apache.iotdb.confignode.client.async.CnToDnAsyncRequestType;
 import org.apache.iotdb.confignode.i18n.ConfigNodeMessages;
 import org.apache.iotdb.mpp.rpc.thrift.TDeviceViewResp;
@@ -31,6 +32,7 @@ import org.slf4j.LoggerFactory;
 
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 
 public class TreeDeviceViewFieldDetectionHandler
@@ -39,6 +41,12 @@ public class TreeDeviceViewFieldDetectionHandler
   private static final Logger LOGGER =
       LoggerFactory.getLogger(TreeDeviceViewFieldDetectionHandler.class);
 
+  private static final Set<Integer> EXPECTED_FAILURE_CODES =
+      Set.of(
+          TSStatusCode.DATA_TYPE_MISMATCH.getStatusCode(),
+          TSStatusCode.COLUMN_ALREADY_EXISTS.getStatusCode(),
+          TSStatusCode.COLUMN_CATEGORY_MISMATCH.getStatusCode());
+
   protected TreeDeviceViewFieldDetectionHandler(
       final CnToDnAsyncRequestType requestType,
       final int requestId,
@@ -63,6 +71,14 @@ public class TreeDeviceViewFieldDetectionHandler
     if (response.getStatus().getCode() == 
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
       LOGGER.info(
           ConfigNodeMessages.SUCCESSFULLY_ON_DATANODE, requestType, 
formattedTargetLocation);
+    } else if (isExpectedFailure(response.getStatus())) {
+      // The response is not logged, as it carries the detected fields and is 
of no use here.
+      LOGGER.info(
+          ConfigNodeMessages.FAILED_TO_ON_DATANODE_WITH_STATUS,
+          requestType,
+          formattedTargetLocation,
+          response.getStatus().getCode(),
+          failureMessage(response.getStatus()));
     } else {
       LOGGER.error(
           ConfigNodeMessages.FAILED_TO_ON_DATANODE_RESPONSE,
@@ -78,6 +94,46 @@ public class TreeDeviceViewFieldDetectionHandler
     countDownLatch.countDown();
   }
 
+  /**
+   * Whether every failure the status carries is decided by the input of the 
client. The DataNodes
+   * aggregate the failures of their regions into MULTIPLE_ERROR, so the sub 
statuses are checked
+   * instead of the code of the status itself.
+   */
+  private static boolean isExpectedFailure(final TSStatus status) {
+    if (status.getCode() != TSStatusCode.MULTIPLE_ERROR.getStatusCode()) {
+      return EXPECTED_FAILURE_CODES.contains(status.getCode());
+    }
+    if (!status.isSetSubStatus() || status.getSubStatus().isEmpty()) {
+      return false;
+    }
+    for (final TSStatus subStatus : status.getSubStatus()) {
+      if (subStatus.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()
+          && !EXPECTED_FAILURE_CODES.contains(subStatus.getCode())) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  /**
+   * The message of the status, or of its first failing sub status when the 
status only aggregates
+   * the failures of several regions and carries no message of its own.
+   */
+  private static String failureMessage(final TSStatus status) {
+    if (status.getMessage() != null && !status.getMessage().isEmpty()) {
+      return status.getMessage();
+    }
+    if (status.isSetSubStatus()) {
+      for (final TSStatus subStatus : status.getSubStatus()) {
+        if (subStatus.getCode() != TSStatusCode.SUCCESS_STATUS.getStatusCode()
+            && subStatus.getMessage() != null) {
+          return subStatus.getMessage();
+        }
+      }
+    }
+    return "";
+  }
+
   @Override
   public void onError(final Exception e) {
     final String errorMsg =
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
index 88121ed6ae6..2fd89ea32df 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
@@ -1730,14 +1730,12 @@ public class ClusterSchemaManager {
     columnSchemaList.removeIf(
         columnSchema -> {
           if (existingColumnNames.contains(columnSchema.getColumnName())) {
-            // todo log
             return true;
           }
 
           // The original time series can only be referenced once.
           final String originalName = 
TreeViewSchema.getSourceName(columnSchema);
           if (originalNames.contains(originalName)) {
-            // todo log
             return true;
           }
 
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/AddTableColumnProcedure.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/AddTableColumnProcedure.java
index 61d35137cf8..0a074e9b740 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/AddTableColumnProcedure.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/AddTableColumnProcedure.java
@@ -194,7 +194,7 @@ public class AddTableColumnProcedure
       }
     } finally {
       LOGGER.info(
-          ProcedureMessages.ROLLBACK_DROPTABLE_COSTS_MS,
+          ProcedureMessages.ROLLBACK_ADDTABLECOLUMN_COSTS_MS,
           state,
           (System.currentTimeMillis() - startTime));
     }
diff --git 
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
index 3e89ec3e4b0..3535a0c9579 100644
--- 
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
@@ -744,8 +744,8 @@ public final class DataNodeSchemaMessages {
   public static final String EXCEPTION_COMMA_50AD1C01 = ", ";
   public static final String 
MESSAGE_SKIP_ROLLBACK_RENAMING_OLD_TABLE_ARG_ARG_BECAUSE_IT_HAS_BEEN_HANDLED_664F2456
 = "Skip rollback renaming old table {}.{} because it has been handled.";
   public static final String 
MESSAGE_SKIP_COMMIT_UPDATE_TABLE_ARG_ARG_BECAUSE_IT_HAS_BEEN_HANDLED_31362A1C = 
"Skip commit-update table {}.{} because it has been handled.";
-  public static final String LOG_ADD_VIEW_COLUMN_CN_FAILED_FE4F10AC = "Failed 
to add columns to the tree to table views for operation {}, ConfigNode returned 
{}.";
   public static final String LOG_ADD_VIEW_COLUMN_FAILED_FOR_VIEW_B3EB8144 = 
"Failed to add a column to the view {}.{} for operation {}, ConfigNode returned 
{}.";
+  public static final String 
LOG_ADD_VIEW_COLUMN_ALREADY_EXISTS_FOR_VIEW_EDFF86E8 = "The columns to be added 
to the view {}.{} for operation {} already exist and are skipped, ConfigNode 
returned {}.";
   public static final String LOG_ADD_VIEW_COLUMN_EMPTY_RESPONSE_B9502E26 = 
"Failed to add columns to the tree to table views for operation {}, ConfigNode 
returned an empty response.";
   public static final String LOG_ADD_VIEW_COLUMN_CN_UNREACHABLE_E9BC7652 = 
"Failed to add columns to the tree to table views for operation {}, because 
ConfigNode is not reachable.";
   public static final String LOG_TRIGGER_ADD_VIEW_COLUMN_FAILED_B909817F = 
"Failed to trigger the view column addition of the tree to table views for plan 
node {}, the schema write is not affected.";
diff --git 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
index 366ba2cfbd4..94f0a72df99 100644
--- 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeSchemaMessages.java
@@ -732,8 +732,8 @@ public final class DataNodeSchemaMessages {
   public static final String EXCEPTION_COMMA_50AD1C01 = ", ";
   public static final String 
MESSAGE_SKIP_ROLLBACK_RENAMING_OLD_TABLE_ARG_ARG_BECAUSE_IT_HAS_BEEN_HANDLED_664F2456
 = "跳过回滚重命名旧表 {}.{},因为该操作已被处理。";
   public static final String 
MESSAGE_SKIP_COMMIT_UPDATE_TABLE_ARG_ARG_BECAUSE_IT_HAS_BEEN_HANDLED_31362A1C = 
"跳过提交更新表 {}.{},因为该操作已被处理。";
-  public static final String LOG_ADD_VIEW_COLUMN_CN_FAILED_FE4F10AC = "为操作 {} 
的树转表视图加列失败,ConfigNode 返回 {}。";
   public static final String LOG_ADD_VIEW_COLUMN_FAILED_FOR_VIEW_B3EB8144 = 
"为视图 {}.{} 加列失败(操作 {}),ConfigNode 返回 {}。";
+  public static final String 
LOG_ADD_VIEW_COLUMN_ALREADY_EXISTS_FOR_VIEW_EDFF86E8 = "为视图 {}.{} 加列时(操作 
{}),待新增的列均已存在,已跳过,ConfigNode 返回 {}。";
   public static final String LOG_ADD_VIEW_COLUMN_EMPTY_RESPONSE_B9502E26 = 
"为操作 {} 的树转表视图加列失败,ConfigNode 返回了空响应。";
   public static final String LOG_ADD_VIEW_COLUMN_CN_UNREACHABLE_E9BC7652 = 
"为操作 {} 的树转表视图加列失败,因为无法访问 ConfigNode。";
   public static final String LOG_TRIGGER_ADD_VIEW_COLUMN_FAILED_B909817F = 
"计划节点 {} 触发树转表视图加列失败,本次 schema 写入不受影响。";
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/ViewColumnAutoSyncTrigger.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/ViewColumnAutoSyncTrigger.java
index 9a937fcd315..362691aef6d 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/ViewColumnAutoSyncTrigger.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/ViewColumnAutoSyncTrigger.java
@@ -137,21 +137,29 @@ public class ViewColumnAutoSyncTrigger {
             
DataNodeSchemaMessages.LOG_ADD_VIEW_COLUMN_EMPTY_RESPONSE_B9502E26, 
operationId);
         return;
       }
-      if (resp.getStatus().getCode() != 
TSStatusCode.SUCCESS_STATUS.getStatusCode()) {
-        LOGGER.error(
-            DataNodeSchemaMessages.LOG_ADD_VIEW_COLUMN_CN_FAILED_FE4F10AC,
-            operationId,
-            resp.getStatus());
-      }
       // the views are updated one by one in ConfigNode, so the failed ones 
are reported one by one
       if (resp.getFailedViews() != null) {
         for (TAutoSyncViewColumnsFailure failedView : resp.getFailedViews()) {
-          LOGGER.error(
-              
DataNodeSchemaMessages.LOG_ADD_VIEW_COLUMN_FAILED_FOR_VIEW_B3EB8144,
-              failedView.getDatabase(),
-              failedView.getTableName(),
-              operationId,
-              failedView.getStatus());
+          // Every replica applies the same schema log and asks for the same 
columns, so the ones
+          // which lose the race get COLUMN_ALREADY_EXISTS: the columns they 
ask for have already
+          // been added by the first replica, which is the expected result 
rather than a failure.
+          if (failedView.getStatus() != null
+              && failedView.getStatus().getCode()
+                  == TSStatusCode.COLUMN_ALREADY_EXISTS.getStatusCode()) {
+            LOGGER.info(
+                
DataNodeSchemaMessages.LOG_ADD_VIEW_COLUMN_ALREADY_EXISTS_FOR_VIEW_EDFF86E8,
+                failedView.getDatabase(),
+                failedView.getTableName(),
+                operationId,
+                failedView.getStatus());
+          } else {
+            LOGGER.error(
+                
DataNodeSchemaMessages.LOG_ADD_VIEW_COLUMN_FAILED_FOR_VIEW_B3EB8144,
+                failedView.getDatabase(),
+                failedView.getTableName(),
+                operationId,
+                failedView.getStatus());
+          }
         }
       }
     } catch (ClientManagerException | TException e) {

Reply via email to