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

jt2594838 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 7b61793d114 Fix compaction mods metrics update (#17636)
7b61793d114 is described below

commit 7b61793d1143c8b36d6038a00e883eebc96081fa
Author: Zhenyu Luo <[email protected]>
AuthorDate: Tue May 12 09:48:03 2026 +0800

    Fix compaction mods metrics update (#17636)
---
 .../dataregion/modification/ModificationFile.java  | 22 +++++---
 .../compaction/utils/CompactionUtilsTest.java      | 36 +++++++++++++
 .../modification/ModificationFileTest.java         | 62 ++++++++++++++++++++++
 3 files changed, 112 insertions(+), 8 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/ModificationFile.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/ModificationFile.java
index bc69f095642..03f44c3c295 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/ModificationFile.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/modification/ModificationFile.java
@@ -40,6 +40,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.channels.FileChannel;
 import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -334,10 +335,11 @@ public class ModificationFile implements AutoCloseable {
   public void remove() throws IOException {
     lock.writeLock().lock();
     try {
+      long sizeBeforeRemove = fileExists ? getFileLength() : 0;
       close();
       FileUtils.deleteFileOrDirectory(file);
       if (fileExists) {
-        updateModFileMetric(-1, -getFileLength());
+        updateModFileMetric(-1, -sizeBeforeRemove);
       }
       fileExists = false;
       removed = true;
@@ -394,12 +396,12 @@ public class ModificationFile implements AutoCloseable {
   public void compact() throws IOException {
     long originFileSize = getFileLength();
     if (originFileSize > COMPACT_THRESHOLD && !hasCompacted) {
+      File compactedFile = new File(getFile().getPath() + COMPACT_SUFFIX);
       try {
         Map<PartialPath, List<ModEntry>> pathModificationMap =
             
getAllMods().stream().collect(Collectors.groupingBy(ModEntry::keyOfPatternTree));
-        String newModsFileName = getFile().getPath() + COMPACT_SUFFIX;
         try (ModificationFile compactedModificationFile =
-            new ModificationFile(newModsFileName, false)) {
+            new ModificationFile(compactedFile, false)) {
           Set<Entry<PartialPath, List<ModEntry>>> modificationsEntrySet =
               pathModificationMap.entrySet();
           for (Map.Entry<PartialPath, List<ModEntry>> modificationEntry : 
modificationsEntrySet) {
@@ -408,12 +410,15 @@ public class ModificationFile implements AutoCloseable {
           }
         } catch (IOException e) {
           LOGGER.error("compact mods file exception of {}", file, e);
+          throw e;
         }
-        // remove origin mods file
-        this.remove();
-        fileExists = true;
-        // rename new mods file to origin name
-        Files.move(new File(newModsFileName).toPath(), file.toPath());
+        long compactedFileSize = compactedFile.length();
+        close();
+        Files.move(compactedFile.toPath(), file.toPath(), 
StandardCopyOption.REPLACE_EXISTING);
+        if (updateMetrics) {
+          FileMetrics.getInstance().increaseModFileSize(compactedFileSize - 
originFileSize);
+        }
+        fileExists = compactedFileSize > 0;
         LOGGER.info("{} settle successful", file);
 
         if (getFileLength() > COMPACT_THRESHOLD) {
@@ -424,6 +429,7 @@ public class ModificationFile implements AutoCloseable {
         }
       } catch (IOException e) {
         LOGGER.error("remove origin file or rename new mods file error.", e);
+        throw e;
       }
       hasCompacted = true;
     }
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionUtilsTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionUtilsTest.java
index 1fa1c733944..2972c0ee929 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionUtilsTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/utils/CompactionUtilsTest.java
@@ -20,10 +20,15 @@
 package org.apache.iotdb.db.storageengine.dataregion.compaction.utils;
 
 import org.apache.iotdb.commons.exception.MetadataException;
+import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.commons.path.PartialPath;
 import org.apache.iotdb.db.exception.StorageEngineException;
+import org.apache.iotdb.db.service.metrics.FileMetrics;
 import 
org.apache.iotdb.db.storageengine.dataregion.compaction.AbstractCompactionTest;
 import 
org.apache.iotdb.db.storageengine.dataregion.compaction.execute.utils.CompactionPathUtils;
+import 
org.apache.iotdb.db.storageengine.dataregion.compaction.execute.utils.CompactionUtils;
+import 
org.apache.iotdb.db.storageengine.dataregion.modification.ModificationFile;
+import 
org.apache.iotdb.db.storageengine.dataregion.modification.TreeDeletionEntry;
 
 import org.apache.tsfile.exception.write.WriteProcessException;
 import org.apache.tsfile.file.metadata.IDeviceID;
@@ -32,6 +37,7 @@ import org.junit.Assert;
 import org.junit.Test;
 
 import java.io.IOException;
+import java.util.ArrayList;
 
 public class CompactionUtilsTest extends AbstractCompactionTest {
   @Override
@@ -54,4 +60,34 @@ public class CompactionUtilsTest extends 
AbstractCompactionTest {
       Assert.fail();
     }
   }
+
+  @Test
+  public void testDeleteSourceTsFileUpdatesModMetrics() throws Exception {
+    int modFileNumBefore = FileMetrics.getInstance().getModFileNum();
+    long modFileSizeBefore = FileMetrics.getInstance().getModFileSize();
+
+    createFiles(2, 1, 1, 10, 0, 0, 10, 10, false, true);
+
+    long totalModFileSize = 0;
+    for (int i = 0; i < seqResources.size(); i++) {
+      try (ModificationFile modificationFile = 
seqResources.get(i).getModFileForWrite()) {
+        modificationFile.write(
+            new TreeDeletionEntry(
+                new MeasurementPath(new String[] {COMPACTION_TEST_SG, "d0", 
"s0"}),
+                Long.MIN_VALUE,
+                i + 10));
+        totalModFileSize += modificationFile.getFileLength();
+      }
+    }
+
+    Assert.assertEquals(
+        modFileNumBefore + seqResources.size(), 
FileMetrics.getInstance().getModFileNum());
+    Assert.assertEquals(
+        modFileSizeBefore + totalModFileSize, 
FileMetrics.getInstance().getModFileSize());
+
+    CompactionUtils.deleteSourceTsFileAndUpdateFileMetrics(new 
ArrayList<>(seqResources), true);
+
+    Assert.assertEquals(modFileNumBefore, 
FileMetrics.getInstance().getModFileNum());
+    Assert.assertEquals(modFileSizeBefore, 
FileMetrics.getInstance().getModFileSize());
+  }
 }
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/modification/ModificationFileTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/modification/ModificationFileTest.java
index a0a9885ecf0..fb4ce06fc33 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/modification/ModificationFileTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/modification/ModificationFileTest.java
@@ -21,6 +21,7 @@ package 
org.apache.iotdb.db.storageengine.dataregion.modification;
 
 import org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.path.MeasurementPath;
+import org.apache.iotdb.db.service.metrics.FileMetrics;
 import 
org.apache.iotdb.db.storageengine.dataregion.compaction.execute.recover.CompactionRecoverManager;
 import 
org.apache.iotdb.db.storageengine.dataregion.modification.IDPredicate.FullExactMatch;
 import 
org.apache.iotdb.db.storageengine.dataregion.modification.IDPredicate.NOP;
@@ -50,6 +51,67 @@ import static org.junit.Assert.fail;
 
 public class ModificationFileTest {
 
+  @Test
+  public void testRemoveUpdatesMetrics() throws IOException {
+    String tempFileName = 
TestConstant.BASE_OUTPUT_PATH.concat("mod.remove.metrics.temp");
+    int modFileNumBefore = FileMetrics.getInstance().getModFileNum();
+    long modFileSizeBefore = FileMetrics.getInstance().getModFileSize();
+    try (ModificationFile modificationFile = new 
ModificationFile(tempFileName, true)) {
+      modificationFile.write(
+          new TreeDeletionEntry(
+              new MeasurementPath(new String[] {"root", "sg", "d1", "s1"}), 1, 
10));
+      long fileLength = modificationFile.getFileLength();
+      assertEquals(modFileNumBefore + 1, 
FileMetrics.getInstance().getModFileNum());
+      assertEquals(modFileSizeBefore + fileLength, 
FileMetrics.getInstance().getModFileSize());
+
+      modificationFile.remove();
+      assertEquals(modFileNumBefore, 
FileMetrics.getInstance().getModFileNum());
+      assertEquals(modFileSizeBefore, 
FileMetrics.getInstance().getModFileSize());
+    } finally {
+      Files.deleteIfExists(new File(tempFileName).toPath());
+    }
+  }
+
+  @Test
+  public void testCompactUpdatesMetricsAndAllowFurtherWrite() throws 
IOException {
+    String tempFileName = 
TestConstant.BASE_OUTPUT_PATH.concat("mod.compact.metrics.temp");
+    int modFileNumBefore = FileMetrics.getInstance().getModFileNum();
+    long modFileSizeBefore = FileMetrics.getInstance().getModFileSize();
+    long time = 1000;
+    try (ModificationFile modificationFile = new 
ModificationFile(tempFileName, true)) {
+      while (modificationFile.getFileLength() < 1024 * 1024) {
+        modificationFile.write(
+            new TreeDeletionEntry(
+                new MeasurementPath(new String[] {"root", "sg", "d1", "s1"}),
+                Long.MIN_VALUE,
+                time += 5000));
+      }
+
+      assertEquals(modFileNumBefore + 1, 
FileMetrics.getInstance().getModFileNum());
+      modificationFile.compact();
+      assertEquals(modFileNumBefore + 1, 
FileMetrics.getInstance().getModFileNum());
+      assertEquals(
+          modFileSizeBefore + modificationFile.getFileLength(),
+          FileMetrics.getInstance().getModFileSize());
+
+      modificationFile.write(
+          new TreeDeletionEntry(
+              new MeasurementPath(new String[] {"root", "sg", "d1", "s2"}),
+              Long.MIN_VALUE,
+              time + 5000));
+      assertEquals(modFileNumBefore + 1, 
FileMetrics.getInstance().getModFileNum());
+      assertEquals(
+          modFileSizeBefore + modificationFile.getFileLength(),
+          FileMetrics.getInstance().getModFileSize());
+
+      modificationFile.remove();
+      assertEquals(modFileNumBefore, 
FileMetrics.getInstance().getModFileNum());
+      assertEquals(modFileSizeBefore, 
FileMetrics.getInstance().getModFileSize());
+    } finally {
+      Files.deleteIfExists(new File(tempFileName).toPath());
+    }
+  }
+
   @Test
   public void readMyWrite() {
     String tempFileName = TestConstant.BASE_OUTPUT_PATH.concat("mod.temp");

Reply via email to