diff --git a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java index ae988b8d1c73..e7b9cff080c5 100644 --- a/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java +++ b/iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TSStatusCode.java @@ -151,6 +151,7 @@ public enum TSStatusCode { CANNOT_FETCH_FI_STATE(722), REPEATED_RPC_CALL(723), CANNOT_READ_TSFILE(724), + COPY_TO_WRITE_ERROR(725), // OBJECT OBJECT_NOT_EXISTS(740), diff --git a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java index 0e9e8158ac7b..ade27d85d09e 100644 --- a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java +++ b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java @@ -2428,6 +2428,10 @@ public final class DataNodeQueryMessages { "Duplicate tag column in TAGS clause: %s"; public static final String EXCEPTION_DUPLICATE_OPTION_IN_COPY_TO_STATEMENT_ARG_99CFE09F = "Duplicate option in COPY TO statement: %s"; + public static final String EXCEPTION_FAILED_TO_WRITE_THE_TARGET_FILE_ARG_5AC3025D = + "Failed to write the target file: %s"; + public static final String LOG_FAILED_TO_WRITE_THE_TARGET_FILE_DURING_COPY_TO_EE25EF37 = + "Failed to write the target file during COPY TO"; public static final String SIMULTANEOUS_SETTING_OF_MONTHLY_AND_NON_MONTHLY_INTERVALS_IS_NOT_SUPPORTED = "Simultaneous setting of monthly and non-monthly intervals is not supported."; public static final String DON_T_NEED_TO_SPECIFY_TIME_COLUMN_WHILE_EITHER_TIME_BOUND_OR_FILL_GROUP_PARAMETER_IS_NOT = diff --git a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java index 1ab922fa121c..31278e1e48ea 100644 --- a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java +++ b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/DataNodeQueryMessages.java @@ -2803,6 +2803,10 @@ public final class DataNodeQueryMessages { "TAGS 子句中存在重复的 TAG 列:%s"; public static final String EXCEPTION_DUPLICATE_OPTION_IN_COPY_TO_STATEMENT_ARG_99CFE09F = "COPY TO 语句中存在重复的选项:%s"; + public static final String EXCEPTION_FAILED_TO_WRITE_THE_TARGET_FILE_ARG_5AC3025D = + "写入目标文件失败:%s"; + public static final String LOG_FAILED_TO_WRITE_THE_TARGET_FILE_DURING_COPY_TO_EE25EF37 = + "COPY TO 写入目标文件失败"; public static final String SIMULTANEOUS_SETTING_OF_MONTHLY_AND_NON_MONTHLY_INTERVALS_IS_NOT_SUPPORTED = "不支持同时设置月级和非月级时间间隔。"; public static final String DON_T_NEED_TO_SPECIFY_TIME_COLUMN_WHILE_EITHER_TIME_BOUND_OR_FILL_GROUP_PARAMETER_IS_NOT = diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/copyto/TableCopyToOperator.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/copyto/TableCopyToOperator.java index 7c4ff8223139..030a5ca4ae61 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/copyto/TableCopyToOperator.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/copyto/TableCopyToOperator.java @@ -21,6 +21,7 @@ import org.apache.iotdb.calc.execution.operator.Operator; import org.apache.iotdb.calc.execution.operator.process.ProcessOperator; +import org.apache.iotdb.commons.exception.IoTDBRuntimeException; import org.apache.iotdb.commons.queryengine.execution.MemoryEstimationHelper; import org.apache.iotdb.commons.schema.column.ColumnHeader; import org.apache.iotdb.db.i18n.DataNodeQueryMessages; @@ -28,11 +29,14 @@ import org.apache.iotdb.db.queryengine.execution.operator.process.copyto.tsfile.CopyToTsFileOptions; import org.apache.iotdb.db.queryengine.execution.operator.process.copyto.tsfile.TsFileFormatCopyToWriter; import org.apache.iotdb.db.storageengine.rescon.disk.TierManager; +import org.apache.iotdb.rpc.TSStatusCode; import com.google.common.util.concurrent.ListenableFuture; import org.apache.tsfile.common.conf.TSFileDescriptor; import org.apache.tsfile.read.common.block.TsBlock; import org.apache.tsfile.utils.RamUsageEstimator; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; @@ -40,6 +44,7 @@ import java.util.List; public class TableCopyToOperator implements ProcessOperator { + private static final Logger LOGGER = LoggerFactory.getLogger(TableCopyToOperator.class); private static final long INSTANCE_SIZE = RamUsageEstimator.shallowSizeOfInstance(TableCopyToOperator.class); @@ -79,7 +84,11 @@ public OperatorContext getOperatorContext() { public TsBlock next() throws Exception { IFormatCopyToWriter formatWriter = getWriter(); if (!childOperator.hasNext()) { - formatWriter.seal(); + try { + formatWriter.seal(); + } catch (IOException e) { + throw newCopyToWriteError(e); + } isFinished = true; return formatWriter.buildResultTsBlock(); } @@ -88,10 +97,24 @@ public TsBlock next() throws Exception { return null; } hasData = true; - formatWriter.write(tsBlock); + try { + formatWriter.write(tsBlock); + } catch (IOException e) { + throw newCopyToWriteError(e); + } return null; } + private IoTDBRuntimeException newCopyToWriteError(IOException e) { + LOGGER.warn( + DataNodeQueryMessages.LOG_FAILED_TO_WRITE_THE_TARGET_FILE_DURING_COPY_TO_EE25EF37, e); + return new IoTDBRuntimeException( + String.format( + DataNodeQueryMessages.EXCEPTION_FAILED_TO_WRITE_THE_TARGET_FILE_ARG_5AC3025D, + e.getMessage()), + TSStatusCode.COPY_TO_WRITE_ERROR.getStatusCode()); + } + private IFormatCopyToWriter getWriter() throws Exception { if (writer != null) { return writer; diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/copyto/tsfile/TsFileFormatCopyToWriter.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/copyto/tsfile/TsFileFormatCopyToWriter.java index 08b8ce127baf..50600003b13c 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/copyto/tsfile/TsFileFormatCopyToWriter.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/operator/process/copyto/tsfile/TsFileFormatCopyToWriter.java @@ -136,7 +136,12 @@ public TsFileFormatCopyToWriter( @Override public void write(TsBlock tsBlock) throws Exception { - tsFileWriter.get().write(tsBlock); + try { + tsFileWriter.get().write(tsBlock); + } catch (Exception e) { + tsFileWriter = null; + throw e; + } } @Override @@ -145,11 +150,14 @@ public void seal() throws Exception { return; } TableTsBlock2TsFileWriter writer = tsFileWriter.get(); - writer.close(); - // should call these methods after writer.close() - deviceCount = writer.getDeviceCount(); - rowCount = writer.getRowCount(); - tsFileWriter = null; + try { + writer.close(); + // should call these methods after writer.close() + deviceCount = writer.getDeviceCount(); + rowCount = writer.getRowCount(); + } finally { + tsFileWriter = null; + } } @Override diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java index bbe30acba01c..5e9c1758664e 100644 --- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java +++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java @@ -135,7 +135,8 @@ public static TSStatus onQueryException(Exception e, String operation, TSStatusC || status.getCode() == TSStatusCode.PATH_ALREADY_EXIST.getStatusCode() || status.getCode() == TSStatusCode.PIPE_NOT_EXIST_ERROR.getStatusCode() || status.getCode() == TSStatusCode.QUERY_TIMEOUT.getStatusCode() - || status.getCode() == TSStatusCode.CANNOT_READ_TSFILE.getStatusCode()) { + || status.getCode() == TSStatusCode.CANNOT_READ_TSFILE.getStatusCode() + || status.getCode() == TSStatusCode.COPY_TO_WRITE_ERROR.getStatusCode()) { LOGGER.info(message); } else { LOGGER.warn(message, e); diff --git a/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/UtilMessages.java b/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/UtilMessages.java index 0fbf9a941e5f..fb5a13bbd31d 100644 --- a/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/UtilMessages.java +++ b/iotdb-core/node-commons/src/main/i18n/en/org/apache/iotdb/commons/i18n/UtilMessages.java @@ -248,6 +248,8 @@ private UtilMessages() {} public static final String MESSAGE_MEET_ERROR_CLOSE_OPERATION_1C7D0589 = "Meet error in close operation."; public static final String MESSAGE_FAIL_DO_NON_QUERY_OPERATIONS_BECAUSE_SYSTEM_READ_ONLY_10CA1ED2 = "Fail to do non-query operations because system is read-only."; public static final String MESSAGE_DISK_SPACE_INSUFFICIENT_DF6205B0 = "Disk space is insufficient."; + public static final String MESSAGE_FAILED_TO_WRITE_THE_TARGET_FILE_4C48CE25 = + "Failed to write the target file."; public static final String MESSAGE_MEET_ERROR_STARTING_UP_22A4CBFE = "Meet error while starting up."; public static final String MESSAGE_USERNAME_PASSWORD_WRONG_C44C4AF0 = "Username or password is wrong."; public static final String MESSAGE_HAS_NOT_LOGGED_A2BA0267 = "Has not logged in."; diff --git a/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/UtilMessages.java b/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/UtilMessages.java index 6cdf3ffaacb7..e58c42381e6d 100644 --- a/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/UtilMessages.java +++ b/iotdb-core/node-commons/src/main/i18n/zh/org/apache/iotdb/commons/i18n/UtilMessages.java @@ -246,6 +246,8 @@ private UtilMessages() {} public static final String MESSAGE_MEET_ERROR_CLOSE_OPERATION_1C7D0589 = "关闭操作中发生错误。"; public static final String MESSAGE_FAIL_DO_NON_QUERY_OPERATIONS_BECAUSE_SYSTEM_READ_ONLY_10CA1ED2 = "系统只读,无法执行非查询操作。"; public static final String MESSAGE_DISK_SPACE_INSUFFICIENT_DF6205B0 = "磁盘空间不足。"; + public static final String MESSAGE_FAILED_TO_WRITE_THE_TARGET_FILE_4C48CE25 = + "写入目标文件失败。"; public static final String MESSAGE_MEET_ERROR_STARTING_UP_22A4CBFE = "启动时发生错误。"; public static final String MESSAGE_USERNAME_PASSWORD_WRONG_C44C4AF0 = "用户名或密码错误。"; public static final String MESSAGE_HAS_NOT_LOGGED_A2BA0267 = "尚未登录。"; diff --git a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/StatusUtils.java b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/StatusUtils.java index f9cdb35b1188..f88844e46e69 100644 --- a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/StatusUtils.java +++ b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/utils/StatusUtils.java @@ -182,6 +182,9 @@ public static TSStatus getStatus(TSStatusCode statusCode) { case DISK_SPACE_INSUFFICIENT: status.setMessage(UtilMessages.MESSAGE_DISK_SPACE_INSUFFICIENT_DF6205B0); break; + case COPY_TO_WRITE_ERROR: + status.setMessage(UtilMessages.MESSAGE_FAILED_TO_WRITE_THE_TARGET_FILE_4C48CE25); + break; case START_UP_ERROR: status.setMessage(UtilMessages.MESSAGE_MEET_ERROR_STARTING_UP_22A4CBFE); break; diff --git a/pom.xml b/pom.xml index 94c0b3a80317..43ec486debb0 100644 --- a/pom.xml +++ b/pom.xml @@ -146,7 +146,7 @@ 0.23.0 1.9 1.5.6-3 - 2.3.2-260731-SNAPSHOT + 2.4.1-260806-SNAPSHOT en