This is an automated email from the ASF dual-hosted git repository.
qiaojialin pushed a commit to branch rel/0.13
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/rel/0.13 by this push:
new feb24d0d10 [To rel/0.13][IOTDB-3843] Refine the using of setting
read-only (#6773)
feb24d0d10 is described below
commit feb24d0d10414fd354de1a21b1f2ce4c4a730e9f
Author: Alan Choo <[email protected]>
AuthorDate: Thu Jul 28 14:27:57 2022 +0800
[To rel/0.13][IOTDB-3843] Refine the using of setting read-only (#6773)
---
.../iotdb/db/integration/IoTDBRestartIT.java | 3 +-
.../resources/conf/iotdb-engine.properties | 4 ++
.../java/org/apache/iotdb/db/conf/IoTDBConfig.java | 44 ++++++++++++++++++--
.../org/apache/iotdb/db/conf/IoTDBDescriptor.java | 6 +++
.../org/apache/iotdb/db/conf/SystemStatus.java | 32 +++++++++++++++
.../directories/strategy/DirectoryStrategy.java | 4 +-
.../db/engine/storagegroup/TsFileProcessor.java | 43 ++++++++++++++------
.../storagegroup/VirtualStorageGroupProcessor.java | 47 +++++++++++++---------
.../iotdb/db/metadata/logfile/MLogWriter.java | 25 +++++++++---
.../apache/iotdb/db/qp/constant/SQLConstant.java | 3 +-
.../apache/iotdb/db/qp/executor/PlanExecutor.java | 5 ++-
.../apache/iotdb/db/qp/physical/sys/ShowPlan.java | 2 +-
.../db/service/thrift/impl/TSServiceImpl.java | 8 ++++
.../db/writelog/node/ExclusiveWriteLogNode.java | 5 ++-
.../apache/iotdb/db/utils/EnvironmentUtils.java | 3 +-
.../java/org/apache/iotdb/session/Session.java | 5 +++
.../apache/iotdb/session/SessionConnection.java | 20 +++++++++
.../org/apache/iotdb/session/pool/SessionPool.java | 19 +++++++++
.../apache/iotdb/session/util/SystemStatus.java | 32 +++++++++++++++
.../apache/iotdb/spark/db/EnvironmentUtils.java | 3 +-
thrift/src/main/thrift/rpc.thrift | 7 ++++
21 files changed, 268 insertions(+), 52 deletions(-)
diff --git
a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBRestartIT.java
b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBRestartIT.java
index c6984d9f23..7fe9384e0e 100644
---
a/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBRestartIT.java
+++
b/integration/src/test/java/org/apache/iotdb/db/integration/IoTDBRestartIT.java
@@ -20,6 +20,7 @@ package org.apache.iotdb.db.integration;
import org.apache.iotdb.db.conf.IoTDBConfig;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.conf.SystemStatus;
import org.apache.iotdb.db.engine.StorageEngine;
import org.apache.iotdb.db.engine.memtable.IMemTable;
import org.apache.iotdb.db.engine.storagegroup.TsFileProcessor;
@@ -423,7 +424,7 @@ public class IoTDBRestartIT {
statement.execute("flush");
}
- IoTDBDescriptor.getInstance().getConfig().setReadOnly(false);
+
IoTDBDescriptor.getInstance().getConfig().setSystemStatus(SystemStatus.NORMAL);
EnvironmentUtils.restartDaemon();
try (Connection connection =
diff --git a/server/src/assembly/resources/conf/iotdb-engine.properties
b/server/src/assembly/resources/conf/iotdb-engine.properties
index afa416c129..840a3b6ad0 100644
--- a/server/src/assembly/resources/conf/iotdb-engine.properties
+++ b/server/src/assembly/resources/conf/iotdb-engine.properties
@@ -193,6 +193,10 @@ timestamp_precision=ms
# Datatype: long
# default_ttl=36000000
+# Shutdown system or set it to read-only mode when unrecoverable error occurs.
+# Datatype: bool
+# allow_read_only_when_errors_occur=true
+
# The size of the log buffer in each log node (in bytes). Due to the double
buffer mechanism,
# if WAL is enabled and the size of the inserted plan is greater than one-half
of this parameter,
# then the insert plan will be rejected by WAL.
diff --git a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
index d33e8a0ff3..16c7151e95 100644
--- a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
+++ b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java
@@ -141,7 +141,11 @@ public class IoTDBConfig {
/** Is the write ahead log enable. */
private boolean enableWal = true;
- private volatile boolean readOnly = false;
+ /** Shutdown system or set it to read-only mode when unrecoverable error
occurs. */
+ private boolean allowReadOnlyWhenErrorsOccur = true;
+
+ /** Status of current system. */
+ private volatile SystemStatus status = SystemStatus.NORMAL;
private boolean enableDiscardOutOfOrderData = false;
@@ -1384,12 +1388,44 @@ public class IoTDBConfig {
this.sessionTimeoutThreshold = sessionTimeoutThreshold;
}
+ boolean isAllowReadOnlyWhenErrorsOccur() {
+ return allowReadOnlyWhenErrorsOccur;
+ }
+
+ void setAllowReadOnlyWhenErrorsOccur(boolean allowReadOnlyWhenErrorsOccur) {
+ this.allowReadOnlyWhenErrorsOccur = allowReadOnlyWhenErrorsOccur;
+ }
+
public boolean isReadOnly() {
- return readOnly;
+ return status == SystemStatus.READ_ONLY
+ || (status == SystemStatus.ERROR && allowReadOnlyWhenErrorsOccur);
+ }
+
+ public SystemStatus getSystemStatus() {
+ return status;
}
- public void setReadOnly(boolean readOnly) {
- this.readOnly = readOnly;
+ public void setSystemStatus(SystemStatus newStatus) {
+ if (newStatus == SystemStatus.READ_ONLY) {
+ logger.error(
+ "Change system mode to read-only! Only query statements are
permitted!",
+ new RuntimeException("System mode is set to READ_ONLY"));
+ } else if (newStatus == SystemStatus.ERROR) {
+ if (allowReadOnlyWhenErrorsOccur) {
+ logger.error(
+ "Unrecoverable error occurs! Make system read-only when
allow_read_only_when_errors_occur is true.",
+ new RuntimeException("System mode is set to READ_ONLY"));
+ newStatus = SystemStatus.READ_ONLY;
+ } else {
+ logger.error(
+ "Unrecoverable error occurs! Shutdown system directly when
allow_read_only_when_errors_occur is false.",
+ new RuntimeException("System mode is set to ERROR"));
+ System.exit(-1);
+ }
+ } else {
+ logger.warn("Set system mode from {} to {}.", status, newStatus);
+ }
+ this.status = newStatus;
}
public String getRpcImplClassName() {
diff --git a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
index 5ff5d12683..8d1f1f9b8e 100644
--- a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
+++ b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java
@@ -620,6 +620,12 @@ public class IoTDBDescriptor {
Long.parseLong(
properties.getProperty("default_ttl",
String.valueOf(conf.getDefaultTTL()))));
+ conf.setAllowReadOnlyWhenErrorsOccur(
+ Boolean.parseBoolean(
+ properties.getProperty(
+ "allow_read_only_when_errors_occur",
+ String.valueOf(conf.isAllowReadOnlyWhenErrorsOccur()))));
+
// the num of memtables in each storage group
conf.setConcurrentWritingTimePartition(
Integer.parseInt(
diff --git a/server/src/main/java/org/apache/iotdb/db/conf/SystemStatus.java
b/server/src/main/java/org/apache/iotdb/db/conf/SystemStatus.java
new file mode 100644
index 0000000000..745fbb1529
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/conf/SystemStatus.java
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+package org.apache.iotdb.db.conf;
+
+/** Status of current system */
+public enum SystemStatus {
+ /** System can read and write normally */
+ NORMAL,
+ /** Only query statements are permitted */
+ READ_ONLY,
+ /**
+ * Unrecoverable errors occur, system will be read-only or exit according to
the param
+ * allow_read_only_when_errors_occur
+ */
+ ERROR,
+}
diff --git
a/server/src/main/java/org/apache/iotdb/db/conf/directories/strategy/DirectoryStrategy.java
b/server/src/main/java/org/apache/iotdb/db/conf/directories/strategy/DirectoryStrategy.java
index b0558993b4..ddbac482d8 100644
---
a/server/src/main/java/org/apache/iotdb/db/conf/directories/strategy/DirectoryStrategy.java
+++
b/server/src/main/java/org/apache/iotdb/db/conf/directories/strategy/DirectoryStrategy.java
@@ -19,6 +19,7 @@
package org.apache.iotdb.db.conf.directories.strategy;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.conf.SystemStatus;
import org.apache.iotdb.db.exception.DiskSpaceInsufficientException;
import org.apache.iotdb.db.utils.CommonUtils;
@@ -54,7 +55,8 @@ public abstract class DirectoryStrategy {
}
}
if (!hasSpace) {
- IoTDBDescriptor.getInstance().getConfig().setReadOnly(true);
+ logger.error("Disk space is insufficient, change system mode to
read-only");
+
IoTDBDescriptor.getInstance().getConfig().setSystemStatus(SystemStatus.READ_ONLY);
throw new DiskSpaceInsufficientException(folders);
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
index 4bc9ab6ce4..e21c710c36 100644
---
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
+++
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileProcessor.java
@@ -20,6 +20,7 @@ package org.apache.iotdb.db.engine.storagegroup;
import org.apache.iotdb.db.conf.IoTDBConfig;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.conf.SystemStatus;
import org.apache.iotdb.db.conf.adapter.CompressionRatio;
import org.apache.iotdb.db.engine.StorageEngine;
import org.apache.iotdb.db.engine.flush.CloseFileListener;
@@ -1042,11 +1043,11 @@ public class TsFileProcessor {
}
} else {
logger.error(
- "{}: {} meet error when flushing a memtable, change system mode
to read-only",
+ "{}: {} meet error when flushing a memtable, change system mode
to error",
storageGroupName,
tsFileResource.getTsFile().getName(),
e);
- IoTDBDescriptor.getInstance().getConfig().setReadOnly(true);
+
IoTDBDescriptor.getInstance().getConfig().setSystemStatus(SystemStatus.ERROR);
try {
logger.error(
"{}: {} IOTask meets error, truncate the corrupted data",
@@ -1132,7 +1133,9 @@ public class TsFileProcessor {
// for sync flush
syncReleaseFlushedMemTable(memTableToFlush);
- if (shouldClose && flushingMemTables.isEmpty() && writer != null) {
+ // retry to avoid unnecessary read-only mode
+ int retryCnt = 0;
+ while (shouldClose && flushingMemTables.isEmpty() && writer != null) {
try {
writer.mark();
updateCompressionRatio(memTableToFlush);
@@ -1140,7 +1143,7 @@ public class TsFileProcessor {
logger.debug(
"{}: {} flushingMemtables is empty and will close the file",
storageGroupName,
- tsFileResource.getTsFile().getName());
+ tsFileResource.getTsFile().getAbsolutePath());
}
endFile();
if (logger.isDebugEnabled()) {
@@ -1148,36 +1151,50 @@ public class TsFileProcessor {
}
} catch (Exception e) {
logger.error(
- "{} meet error when flush FileMetadata to {}, change system mode
to read-only",
+ "{}: {} marking or ending file meet error",
storageGroupName,
tsFileResource.getTsFile().getAbsolutePath(),
e);
- IoTDBDescriptor.getInstance().getConfig().setReadOnly(true);
+ // truncate broken metadata
try {
writer.reset();
} catch (IOException e1) {
logger.error(
"{}: {} truncate corrupted data meets error",
storageGroupName,
- tsFileResource.getTsFile().getName(),
+ tsFileResource.getTsFile().getAbsolutePath(),
e1);
}
- logger.error(
- "{}: {} marking or ending file meet error",
- storageGroupName,
- tsFileResource.getTsFile().getName(),
- e);
+ // retry or set read-only
+ if (retryCnt < 3) {
+ logger.warn(
+ "{} meet error when flush FileMetadata to {}, retry it again",
+ storageGroupName,
+ tsFileResource.getTsFile().getAbsolutePath(),
+ e);
+ retryCnt++;
+ continue;
+ } else {
+ logger.error(
+ "{} meet error when flush FileMetadata to {}, change system mode
to error",
+ storageGroupName,
+ tsFileResource.getTsFile().getAbsolutePath(),
+ e);
+
IoTDBDescriptor.getInstance().getConfig().setSystemStatus(SystemStatus.ERROR);
+ break;
+ }
}
// for sync close
if (logger.isDebugEnabled()) {
logger.debug(
"{}: {} try to get flushingMemtables lock.",
storageGroupName,
- tsFileResource.getTsFile().getName());
+ tsFileResource.getTsFile().getAbsolutePath());
}
synchronized (flushingMemTables) {
flushingMemTables.notifyAll();
}
+ break;
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/VirtualStorageGroupProcessor.java
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/VirtualStorageGroupProcessor.java
index 583bc30b32..d6f9c8f5a7 100755
---
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/VirtualStorageGroupProcessor.java
+++
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/VirtualStorageGroupProcessor.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.db.concurrent.ThreadName;
import org.apache.iotdb.db.conf.IoTDBConfig;
import org.apache.iotdb.db.conf.IoTDBConstant;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.conf.SystemStatus;
import org.apache.iotdb.db.conf.directories.DirectoryManager;
import org.apache.iotdb.db.engine.StorageEngine;
import org.apache.iotdb.db.engine.compaction.CompactionScheduler;
@@ -1192,24 +1193,34 @@ public class VirtualStorageGroupProcessor {
private TsFileProcessor getOrCreateTsFileProcessor(long timeRangeId, boolean
sequence) {
TsFileProcessor tsFileProcessor = null;
- try {
- if (sequence) {
- tsFileProcessor =
- getOrCreateTsFileProcessorIntern(timeRangeId,
workSequenceTsFileProcessors, true);
- } else {
- tsFileProcessor =
- getOrCreateTsFileProcessorIntern(timeRangeId,
workUnsequenceTsFileProcessors, false);
+ int retryCnt = 0;
+ do {
+ try {
+ if (sequence) {
+ tsFileProcessor =
+ getOrCreateTsFileProcessorIntern(timeRangeId,
workSequenceTsFileProcessors, true);
+ } else {
+ tsFileProcessor =
+ getOrCreateTsFileProcessorIntern(timeRangeId,
workUnsequenceTsFileProcessors, false);
+ }
+ } catch (DiskSpaceInsufficientException e) {
+ logger.error(
+ "disk space is insufficient when creating TsFile processor, change
system mode to read-only",
+ e);
+
IoTDBDescriptor.getInstance().getConfig().setSystemStatus(SystemStatus.READ_ONLY);
+ break;
+ } catch (IOException e) {
+ if (retryCnt < 3) {
+ logger.warn("meet IOException when creating TsFileProcessor, retry
it again", e);
+ retryCnt++;
+ } else {
+ logger.error(
+ "meet IOException when creating TsFileProcessor, change system
mode to error", e);
+
IoTDBDescriptor.getInstance().getConfig().setSystemStatus(SystemStatus.ERROR);
+ break;
+ }
}
- } catch (DiskSpaceInsufficientException e) {
- logger.error(
- "disk space is insufficient when creating TsFile processor, change
system mode to read-only",
- e);
- IoTDBDescriptor.getInstance().getConfig().setReadOnly(true);
- } catch (IOException e) {
- logger.error(
- "meet IOException when creating TsFileProcessor, change system mode
to read-only", e);
- IoTDBDescriptor.getInstance().getConfig().setReadOnly(true);
- }
+ } while (tsFileProcessor == null);
return tsFileProcessor;
}
@@ -2302,7 +2313,6 @@ public class VirtualStorageGroupProcessor {
"Failed to append the tsfile {} to storage group processor {}
because the disk space is insufficient.",
tsfileToBeInserted.getAbsolutePath(),
tsfileToBeInserted.getParentFile().getName());
- IoTDBDescriptor.getInstance().getConfig().setReadOnly(true);
throw new LoadFileException(e);
} catch (IllegalPathException e) {
logger.error(
@@ -2385,7 +2395,6 @@ public class VirtualStorageGroupProcessor {
"Failed to append the tsfile {} to storage group processor {}
because the disk space is insufficient.",
tsfileToBeInserted.getAbsolutePath(),
tsfileToBeInserted.getParentFile().getName());
- IoTDBDescriptor.getInstance().getConfig().setReadOnly(true);
throw new LoadFileException(e);
} catch (IllegalPathException e) {
logger.error(
diff --git
a/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java
b/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java
index 15aa3a704c..1ec1e16d7e 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java
@@ -20,6 +20,7 @@ package org.apache.iotdb.db.metadata.logfile;
import org.apache.iotdb.db.conf.IoTDBConfig;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.conf.SystemStatus;
import org.apache.iotdb.db.engine.fileSystem.SystemFileFactory;
import org.apache.iotdb.db.metadata.mnode.IMNode;
import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
@@ -101,12 +102,24 @@ public class MLogWriter implements AutoCloseable {
}
private void sync() {
- try {
- logWriter.write(mlogBuffer);
- } catch (IOException e) {
- logger.error(
- "MLog {} sync failed, change system mode to read-only",
logFile.getAbsoluteFile(), e);
- IoTDBDescriptor.getInstance().getConfig().setReadOnly(true);
+ int retryCnt = 0;
+ mlogBuffer.mark();
+ while (true) {
+ try {
+ logWriter.write(mlogBuffer);
+ break;
+ } catch (IOException e) {
+ if (retryCnt < 3) {
+ logger.warn("MLog {} sync failed, retry it again",
logFile.getAbsoluteFile(), e);
+ mlogBuffer.reset();
+ retryCnt++;
+ } else {
+ logger.error(
+ "MLog {} sync failed, change system mode to error",
logFile.getAbsoluteFile(), e);
+
IoTDBDescriptor.getInstance().getConfig().setSystemStatus(SystemStatus.ERROR);
+ break;
+ }
+ }
}
mlogBuffer.clear();
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/qp/constant/SQLConstant.java
b/server/src/main/java/org/apache/iotdb/db/qp/constant/SQLConstant.java
index b137ddd9b2..d63595d5e9 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/constant/SQLConstant.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/constant/SQLConstant.java
@@ -197,9 +197,8 @@ public class SQLConstant {
public static final int TOK_SCHEMA_TEMPLATE_SHOW_NODES = 120;
public static final int TOK_SCHEMA_TEMPLATE_SHOW_PATHS_SET = 121;
public static final int TOK_SCHEMA_TEMPLATE_SHOW_PATHS_USING = 122;
- public static final int TOK_SCHEMA_TEMPLATE_DEACTIVATE = 124;
-
public static final int TOK_SHOW_QUERY_RESOURCE = 123;
+ public static final int TOK_SCHEMA_TEMPLATE_DEACTIVATE = 124;
public static final Map<Integer, String> tokenNames = new HashMap<>();
diff --git
a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
index 5b8a0bcbfe..ab2a539aed 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
@@ -30,6 +30,7 @@ import org.apache.iotdb.db.concurrent.IoTDBThreadPoolFactory;
import org.apache.iotdb.db.concurrent.ThreadName;
import org.apache.iotdb.db.conf.IoTDBConstant;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.conf.SystemStatus;
import org.apache.iotdb.db.engine.StorageEngine;
import org.apache.iotdb.db.engine.cache.BloomFilterCache;
import org.apache.iotdb.db.engine.cache.ChunkCache;
@@ -601,7 +602,9 @@ public class PlanExecutor implements IPlanExecutor {
}
private void operateSetSystemMode(SetSystemModePlan plan) {
- IoTDBDescriptor.getInstance().getConfig().setReadOnly(plan.isReadOnly());
+ IoTDBDescriptor.getInstance()
+ .getConfig()
+ .setSystemStatus(plan.isReadOnly() ? SystemStatus.READ_ONLY :
SystemStatus.NORMAL);
}
private void operateFlush(FlushPlan plan) throws StorageGroupNotSetException
{
diff --git
a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowPlan.java
b/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowPlan.java
index 8cf733739b..021814e1b8 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/sys/ShowPlan.java
@@ -126,6 +126,6 @@ public class ShowPlan extends PhysicalPlan {
SCHEMA_TEMPLATE,
NODES_IN_SCHEMA_TEMPLATE,
PATHS_SET_SCHEMA_TEMPLATE,
- PATHS_USING_SCHEMA_TEMPLATE
+ PATHS_USING_SCHEMA_TEMPLATE,
}
}
diff --git
a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java
b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java
index 534ac9915b..0d44a4785a 100644
---
a/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java
+++
b/server/src/main/java/org/apache/iotdb/db/service/thrift/impl/TSServiceImpl.java
@@ -101,6 +101,7 @@ import
org.apache.iotdb.service.rpc.thrift.TSFetchMetadataReq;
import org.apache.iotdb.service.rpc.thrift.TSFetchMetadataResp;
import org.apache.iotdb.service.rpc.thrift.TSFetchResultsReq;
import org.apache.iotdb.service.rpc.thrift.TSFetchResultsResp;
+import org.apache.iotdb.service.rpc.thrift.TSGetSystemStatusResp;
import org.apache.iotdb.service.rpc.thrift.TSGetTimeZoneResp;
import org.apache.iotdb.service.rpc.thrift.TSIService;
import org.apache.iotdb.service.rpc.thrift.TSInsertRecordReq;
@@ -1132,6 +1133,13 @@ public class TSServiceImpl implements TSIService.Iface {
}
}
+ @Override
+ public TSGetSystemStatusResp getSystemStatus(long sessionId) {
+ return new TSGetSystemStatusResp(
+ RpcUtils.getStatus(TSStatusCode.SUCCESS_STATUS),
+
IoTDBDescriptor.getInstance().getConfig().getSystemStatus().toString());
+ }
+
@Override
public TSGetTimeZoneResp getTimeZone(long sessionId) {
try {
diff --git
a/server/src/main/java/org/apache/iotdb/db/writelog/node/ExclusiveWriteLogNode.java
b/server/src/main/java/org/apache/iotdb/db/writelog/node/ExclusiveWriteLogNode.java
index 79e12b82d9..4dfcc3406c 100644
---
a/server/src/main/java/org/apache/iotdb/db/writelog/node/ExclusiveWriteLogNode.java
+++
b/server/src/main/java/org/apache/iotdb/db/writelog/node/ExclusiveWriteLogNode.java
@@ -21,6 +21,7 @@ package org.apache.iotdb.db.writelog.node;
import org.apache.iotdb.db.concurrent.IoTDBThreadPoolFactory;
import org.apache.iotdb.db.conf.IoTDBConfig;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.conf.SystemStatus;
import org.apache.iotdb.db.conf.directories.DirectoryManager;
import org.apache.iotdb.db.engine.fileSystem.SystemFileFactory;
import org.apache.iotdb.db.qp.physical.PhysicalPlan;
@@ -316,8 +317,8 @@ public class ExclusiveWriteLogNode implements WriteLogNode,
Comparable<Exclusive
try {
writer.write(logBufferFlushing);
} catch (Throwable e) {
- logger.error("Log node {} sync failed, change system mode to read-only",
identifier, e);
- IoTDBDescriptor.getInstance().getConfig().setReadOnly(true);
+ logger.error("Log node {} sync failed, change system mode to error",
identifier, e);
+
IoTDBDescriptor.getInstance().getConfig().setSystemStatus(SystemStatus.ERROR);
} finally {
// switch buffer flushing to idle and notify the sync thread
synchronized (switchBufferCondition) {
diff --git
a/server/src/test/java/org/apache/iotdb/db/utils/EnvironmentUtils.java
b/server/src/test/java/org/apache/iotdb/db/utils/EnvironmentUtils.java
index f60c73e85f..f41ca37f9b 100644
--- a/server/src/test/java/org/apache/iotdb/db/utils/EnvironmentUtils.java
+++ b/server/src/test/java/org/apache/iotdb/db/utils/EnvironmentUtils.java
@@ -22,6 +22,7 @@ import org.apache.iotdb.db.auth.AuthException;
import org.apache.iotdb.db.auth.authorizer.BasicAuthorizer;
import org.apache.iotdb.db.conf.IoTDBConfig;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.conf.SystemStatus;
import org.apache.iotdb.db.conf.directories.DirectoryManager;
import org.apache.iotdb.db.constant.TestConstant;
import org.apache.iotdb.db.engine.StorageEngine;
@@ -141,7 +142,7 @@ public class EnvironmentUtils {
fail();
}
- IoTDBDescriptor.getInstance().getConfig().setReadOnly(false);
+
IoTDBDescriptor.getInstance().getConfig().setSystemStatus(SystemStatus.NORMAL);
// We must disable MQTT service as it will cost a lot of time to be
shutdown, which may slow our
// unit tests.
IoTDBDescriptor.getInstance().getConfig().setEnableMQTTService(false);
diff --git a/session/src/main/java/org/apache/iotdb/session/Session.java
b/session/src/main/java/org/apache/iotdb/session/Session.java
index 5025a8f230..828540fe57 100644
--- a/session/src/main/java/org/apache/iotdb/session/Session.java
+++ b/session/src/main/java/org/apache/iotdb/session/Session.java
@@ -50,6 +50,7 @@ import org.apache.iotdb.session.template.MeasurementNode;
import org.apache.iotdb.session.template.Template;
import org.apache.iotdb.session.template.TemplateQueryType;
import org.apache.iotdb.session.util.SessionUtils;
+import org.apache.iotdb.session.util.SystemStatus;
import org.apache.iotdb.session.util.ThreadUtils;
import org.apache.iotdb.session.util.Version;
import org.apache.iotdb.tsfile.exception.write.UnSupportedDataTypeException;
@@ -421,6 +422,10 @@ public class Session {
return new SessionConnection(session, endpoint, zoneId);
}
+ public SystemStatus getSystemStatus() throws IoTDBConnectionException {
+ return defaultSessionConnection.getSystemStatus();
+ }
+
public synchronized String getTimeZone() {
return defaultSessionConnection.getTimeZone();
}
diff --git
a/session/src/main/java/org/apache/iotdb/session/SessionConnection.java
b/session/src/main/java/org/apache/iotdb/session/SessionConnection.java
index 06a960b21a..ed6cf16ebb 100644
--- a/session/src/main/java/org/apache/iotdb/session/SessionConnection.java
+++ b/session/src/main/java/org/apache/iotdb/session/SessionConnection.java
@@ -36,6 +36,7 @@ import org.apache.iotdb.service.rpc.thrift.TSDeleteDataReq;
import org.apache.iotdb.service.rpc.thrift.TSDropSchemaTemplateReq;
import org.apache.iotdb.service.rpc.thrift.TSExecuteStatementReq;
import org.apache.iotdb.service.rpc.thrift.TSExecuteStatementResp;
+import org.apache.iotdb.service.rpc.thrift.TSGetSystemStatusResp;
import org.apache.iotdb.service.rpc.thrift.TSIService;
import org.apache.iotdb.service.rpc.thrift.TSInsertRecordReq;
import org.apache.iotdb.service.rpc.thrift.TSInsertRecordsOfOneDeviceReq;
@@ -59,6 +60,7 @@ import
org.apache.iotdb.service.rpc.thrift.TSSetUsingTemplateReq;
import org.apache.iotdb.service.rpc.thrift.TSStatus;
import org.apache.iotdb.service.rpc.thrift.TSUnsetSchemaTemplateReq;
import org.apache.iotdb.session.util.SessionUtils;
+import org.apache.iotdb.session.util.SystemStatus;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
@@ -200,6 +202,24 @@ public class SessionConnection {
return client;
}
+ protected SystemStatus getSystemStatus() throws IoTDBConnectionException {
+ TSGetSystemStatusResp resp;
+ try {
+ resp = client.getSystemStatus(sessionId);
+ } catch (TException e) {
+ if (reconnect()) {
+ try {
+ resp = client.getSystemStatus(sessionId);
+ } catch (TException tException) {
+ throw new IoTDBConnectionException(tException);
+ }
+ } else {
+ throw new IoTDBConnectionException(logForReconnectionFailure());
+ }
+ }
+ return SystemStatus.valueOf(resp.getSystemStatus());
+ }
+
protected void setTimeZone(String zoneId)
throws StatementExecutionException, IoTDBConnectionException {
TSSetTimeZoneReq req = new TSSetTimeZoneReq(sessionId, zoneId);
diff --git
a/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java
b/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java
index 82fc8107aa..326f6c4030 100644
--- a/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java
+++ b/session/src/main/java/org/apache/iotdb/session/pool/SessionPool.java
@@ -24,6 +24,7 @@ import org.apache.iotdb.session.Config;
import org.apache.iotdb.session.Session;
import org.apache.iotdb.session.SessionDataSet;
import org.apache.iotdb.session.template.Template;
+import org.apache.iotdb.session.util.SystemStatus;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
@@ -2322,6 +2323,24 @@ public class SessionPool {
return false;
}
+ public SystemStatus getSystemStatus() throws IoTDBConnectionException {
+ for (int i = 0; i < RETRY; i++) {
+ Session session = getSession();
+ try {
+ SystemStatus status = session.getSystemStatus();
+ putBack(session);
+ return status;
+ } catch (IoTDBConnectionException e) {
+ // TException means the connection is broken, remove it and get a new
one.
+ cleanSessionAndMayThrowConnectionException(session, i, e);
+ } catch (RuntimeException e) {
+ putBack(session);
+ throw e;
+ }
+ }
+ return null;
+ }
+
public int getMaxSize() {
return maxSize;
}
diff --git
a/session/src/main/java/org/apache/iotdb/session/util/SystemStatus.java
b/session/src/main/java/org/apache/iotdb/session/util/SystemStatus.java
new file mode 100644
index 0000000000..ad383dbfcb
--- /dev/null
+++ b/session/src/main/java/org/apache/iotdb/session/util/SystemStatus.java
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+package org.apache.iotdb.session.util;
+
+/** Status of current system */
+public enum SystemStatus {
+ /** System can read and write normally */
+ NORMAL,
+ /** Only query statements are permitted */
+ READ_ONLY,
+ /**
+ * Unrecoverable errors occur, system will be read-only or exit according to
the param
+ * allow_read_only_when_errors_occur
+ */
+ ERROR,
+}
diff --git
a/spark-iotdb-connector/src/test/scala/org/apache/iotdb/spark/db/EnvironmentUtils.java
b/spark-iotdb-connector/src/test/scala/org/apache/iotdb/spark/db/EnvironmentUtils.java
index 5f54ad3b46..a7845851da 100644
---
a/spark-iotdb-connector/src/test/scala/org/apache/iotdb/spark/db/EnvironmentUtils.java
+++
b/spark-iotdb-connector/src/test/scala/org/apache/iotdb/spark/db/EnvironmentUtils.java
@@ -31,6 +31,7 @@ import org.apache.iotdb.db.auth.authorizer.BasicAuthorizer;
import org.apache.iotdb.db.auth.authorizer.IAuthorizer;
import org.apache.iotdb.db.conf.IoTDBConfig;
import org.apache.iotdb.db.conf.IoTDBDescriptor;
+import org.apache.iotdb.db.conf.SystemStatus;
import org.apache.iotdb.db.conf.directories.DirectoryManager;
import org.apache.iotdb.db.engine.StorageEngine;
import org.apache.iotdb.db.engine.cache.BloomFilterCache;
@@ -111,7 +112,7 @@ public class EnvironmentUtils {
Assert.fail();
}
StorageEngine.getInstance().reset();
- IoTDBDescriptor.getInstance().getConfig().setReadOnly(false);
+
IoTDBDescriptor.getInstance().getConfig().setSystemStatus(SystemStatus.NORMAL);
// clean wal
MultiFileLogNodeManager.getInstance().stop();
diff --git a/thrift/src/main/thrift/rpc.thrift
b/thrift/src/main/thrift/rpc.thrift
index 797270e180..fbcabef7f2 100644
--- a/thrift/src/main/thrift/rpc.thrift
+++ b/thrift/src/main/thrift/rpc.thrift
@@ -200,6 +200,11 @@ struct TSFetchMetadataReq{
3: optional string columnPath
}
+struct TSGetSystemStatusResp {
+ 1: required TSStatus status
+ 2: required string systemStatus
+}
+
struct TSGetTimeZoneResp {
1: required TSStatus status
2: required string timeZone
@@ -448,6 +453,8 @@ service TSIService {
TSStatus closeOperation(1:TSCloseOperationReq req);
+ TSGetSystemStatusResp getSystemStatus(1:i64 sessionId);
+
TSGetTimeZoneResp getTimeZone(1:i64 sessionId);
TSStatus setTimeZone(1:TSSetTimeZoneReq req);