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 d1302398148 Extend suspicious disk exception recording to
SyncFailedException and disk-error IOExceptions (#18572)
d1302398148 is described below
commit d1302398148156bb2968692c75d02da641064a3b
Author: shuwenwei <[email protected]>
AuthorDate: Wed Sep 2 19:37:01 2026 +0800
Extend suspicious disk exception recording to SyncFailedException and
disk-error IOExceptions (#18572)
---
.../service/metrics/DataNodeExceptionMetrics.java | 44 +++++++++++++++++++---
1 file changed, 38 insertions(+), 6 deletions(-)
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/DataNodeExceptionMetrics.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/DataNodeExceptionMetrics.java
index 42035ca0c09..8e43753534d 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/DataNodeExceptionMetrics.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/service/metrics/DataNodeExceptionMetrics.java
@@ -27,9 +27,15 @@ import org.apache.iotdb.metrics.type.Counter;
import org.apache.iotdb.metrics.utils.MetricLevel;
import org.apache.iotdb.metrics.utils.MetricType;
+import java.io.IOException;
+import java.io.SyncFailedException;
import java.nio.file.FileSystemException;
-/** Records DataNode exceptions whose cause chain contains a {@link
FileSystemException}. */
+/**
+ * Records DataNode exceptions whose cause chain contains a suspicious disk
I/O exception, i.e. an
+ * exact {@link FileSystemException}, a {@link SyncFailedException}, or an
{@link IOException}
+ * carrying a well-known disk-error message.
+ */
public class DataNodeExceptionMetrics implements IMetricSet {
private static final DataNodeExceptionMetrics INSTANCE = new
DataNodeExceptionMetrics();
@@ -54,18 +60,44 @@ public class DataNodeExceptionMetrics implements IMetricSet
{
}
public void recordSuspiciousDiskException(Throwable throwable) {
- // Uses exact type matching instead of instanceof because subclasses of
- // FileSystemException (e.g. NoSuchFileException, NotDirectoryException,
- // AccessDeniedException) usually indicate logical file-state errors rather
- // than real disk failures, so they should not be counted here.
for (Throwable current = throwable; current != null; current =
current.getCause()) {
- if (current.getClass() == FileSystemException.class) {
+ if (isSuspiciousDiskException(current)) {
suspiciousDiskExceptionCounter.inc();
return;
}
}
}
+ private static boolean isSuspiciousDiskException(Throwable throwable) {
+ // 1) exact FileSystemException. Subclasses (e.g. NoSuchFileException,
+ // NotDirectoryException, AccessDeniedException) usually indicate logical
+ // file-state errors rather than real disk failures, so they are not
counted here.
+ if (throwable.getClass() == FileSystemException.class) {
+ return true;
+ }
+ // 2) SyncFailedException: fsync/force failure is almost always a real
disk problem.
+ // Its message is fixed to "Sync failed" without the errno text, so it can
only be
+ // recognized by its type.
+ if (throwable instanceof SyncFailedException) {
+ return true;
+ }
+ // 3) Plain IOException thrown by reads/writes/force on already-open
channels carries
+ // the errno text in its message. Match the well-known disk-error messages
instead of
+ // counting every IOException (EOF, closed stream, etc. are not disk
problems).
+ if (throwable instanceof IOException) {
+ String message = throwable.getMessage();
+ if (message != null) {
+ return message.contains("Input/output error")
+ || message.contains("No space left on device")
+ || message.contains("Read-only file system")
+ || message.contains("Structure needs cleaning")
+ || message.contains("No such device or address")
+ || message.contains("Disk quota exceeded");
+ }
+ }
+ return false;
+ }
+
public static DataNodeExceptionMetrics getInstance() {
return INSTANCE;
}