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

qiaojialin 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 3f915d0  [IOTDB-2578]Fix cross space compaction recover and log read 
compatible with 0.12 (#5122)
3f915d0 is described below

commit 3f915d0c2029f71b80d56e08173e62ca509cc296
Author: 周沛辰 <[email protected]>
AuthorDate: Mon Feb 28 08:54:22 2022 +0800

    [IOTDB-2578]Fix cross space compaction recover and log read compatible with 
0.12 (#5122)
---
 .../org/apache/iotdb/db/conf/IoTDBConstant.java    |   6 +
 .../db/engine/compaction/TsFileIdentifier.java     |  22 +++
 .../RewriteCrossSpaceCompactionSelector.java       |   7 +-
 .../RewriteCrossSpaceCompactionLogAnalyzer.java    | 100 +++++++----
 .../recover/RewriteCrossSpaceCompactionLogger.java |   1 +
 .../task/RewriteCrossCompactionRecoverTask.java    | 194 +++++++++++++++++++--
 .../compaction/task/CompactionRecoverTask.java     |  27 ++-
 .../engine/storagegroup/TsFileNameGenerator.java   |   2 +-
 8 files changed, 307 insertions(+), 52 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConstant.java 
b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConstant.java
index 7d43fbc..feab1ab 100644
--- a/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConstant.java
+++ b/server/src/main/java/org/apache/iotdb/db/conf/IoTDBConstant.java
@@ -181,6 +181,12 @@ public class IoTDBConstant {
   // cross space compaction
   public static final String CROSS_COMPACTION_TMP_FILE_SUFFIX = ".cross";
 
+  // cross space compaction of previous version (<0.13)
+  public static final String CROSS_COMPACTION_TMP_FILE_SUFFIX_FROM_OLD = 
".merge";
+
+  // compaction mods of previous version (<0.13)
+  public static final String COMPACTION_MODIFICATION_FILE_NAME_FROM_OLD = 
"merge.mods";
+
   // client version number
   public enum ClientVersion {
     V_0_12,
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/compaction/TsFileIdentifier.java
 
b/server/src/main/java/org/apache/iotdb/db/engine/compaction/TsFileIdentifier.java
index a93c34e..f2cb57e 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/compaction/TsFileIdentifier.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/compaction/TsFileIdentifier.java
@@ -111,6 +111,28 @@ public class TsFileIdentifier {
         splittedFileInfo[FILE_NAME_OFFSET_IN_LOG]);
   }
 
+  /**
+   * This function generates an instance of CompactionFileIdentifier by 
parsing the old info string
+   * from previous version (<0.13) of a tsfile(usually recorded in a 
compaction.log), such as
+   * “root.test.sg 0 0 1-1-0-0.tsfile true"
+   */
+  public static TsFileIdentifier getFileIdentifierFromOldInfoString(String 
oldInfoString) {
+    String[] splittedFileInfo = oldInfoString.split(INFO_SEPARATOR);
+    int length = splittedFileInfo.length;
+    if (length != 5) {
+      throw new RuntimeException(
+          String.format(
+              "String %s is not a legal file info string from previous version 
(<0.13)",
+              oldInfoString));
+    }
+    return new TsFileIdentifier(
+        splittedFileInfo[LOGICAL_SG_OFFSET_IN_LOG],
+        splittedFileInfo[VIRTUAL_SG_OFFSET_IN_LOG],
+        splittedFileInfo[TIME_PARTITION_OFFSET_IN_LOG],
+        Boolean.parseBoolean(splittedFileInfo[FILE_NAME_OFFSET_IN_LOG]),
+        splittedFileInfo[SEQUENCE_OFFSET_IN_LOG]);
+  }
+
   @Override
   public String toString() {
     return String.format(
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/RewriteCrossSpaceCompactionSelector.java
 
b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/RewriteCrossSpaceCompactionSelector.java
index 8f3e1d1..1971e85 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/RewriteCrossSpaceCompactionSelector.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/RewriteCrossSpaceCompactionSelector.java
@@ -97,6 +97,8 @@ public class RewriteCrossSpaceCompactionSelector extends 
AbstractCrossSpaceCompa
         InnerSpaceCompactionUtils.getCrossSpaceFileSelector(budget, 
mergeResource);
     try {
       List[] mergeFiles = fileSelector.select();
+      // avoid pending tasks holds the metadata and streams
+      mergeResource.clear();
       if (mergeFiles.length == 0) {
         if (mergeResource.getUnseqFiles().size() > 0) {
           // still have unseq files but cannot be selected
@@ -111,11 +113,6 @@ public class RewriteCrossSpaceCompactionSelector extends 
AbstractCrossSpaceCompa
           "select files for cross compaction, sequence files: {}, unsequence 
files {}",
           mergeFiles[0],
           mergeFiles[1]);
-      // avoid pending tasks holds the metadata and streams
-      mergeResource.clear();
-      // do not cache metadata until true candidates are chosen, or too much 
metadata will be
-      // cached during selection
-      mergeResource.setCacheDeviceMeta(true);
 
       if (mergeFiles[0].size() > 0 && mergeFiles[1].size() > 0) {
         mergeFiles[0].forEach(x -> ((TsFileResource) 
x).setCompactionCandidate(true));
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/recover/RewriteCrossSpaceCompactionLogAnalyzer.java
 
b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/recover/RewriteCrossSpaceCompactionLogAnalyzer.java
index 60d4332..e6a884c 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/recover/RewriteCrossSpaceCompactionLogAnalyzer.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/recover/RewriteCrossSpaceCompactionLogAnalyzer.java
@@ -18,13 +18,16 @@
  */
 package org.apache.iotdb.db.engine.compaction.cross.rewrite.recover;
 
+import org.apache.iotdb.db.conf.IoTDBConstant;
 import org.apache.iotdb.db.engine.compaction.TsFileIdentifier;
+import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
 
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.InvalidPropertiesFormatException;
 import java.util.List;
 
 import static 
org.apache.iotdb.db.engine.compaction.cross.rewrite.recover.RewriteCrossSpaceCompactionLogger.MAGIC_STRING;
@@ -34,15 +37,12 @@ import static 
org.apache.iotdb.db.engine.compaction.cross.rewrite.recover.Rewrit
 
 public class RewriteCrossSpaceCompactionLogAnalyzer {
 
-  private File logFile;
-  private List<String> sourceFiles = new ArrayList<>();
-  private List<TsFileIdentifier> sourceFileInfos = new ArrayList<>();
-  private List<TsFileIdentifier> targetFileInfos = new ArrayList<>();
-  private String targetFile = null;
-  private boolean isSeq = false;
+  private final File logFile;
+  private final List<TsFileIdentifier> sourceFileInfos = new ArrayList<>();
+  private final List<TsFileIdentifier> targetFileInfos = new ArrayList<>();
   private boolean isFirstMagicStringExisted = false;
-
-  boolean isEndMagicStringExisted = false;
+  private boolean isEndMagicStringExisted = false;
+  private boolean isLogFromOld = false;
 
   public RewriteCrossSpaceCompactionLogAnalyzer(File logFile) {
     this.logFile = logFile;
@@ -51,36 +51,64 @@ public class RewriteCrossSpaceCompactionLogAnalyzer {
   /** @return analyze (source file list, target file) */
   public void analyze() throws IOException {
     String currLine;
-    boolean isTargetFile = true;
-    List<File> mergeTmpFile = new ArrayList<>();
     try (BufferedReader bufferedReader = new BufferedReader(new 
FileReader(logFile))) {
-      int magicCount = 0;
-      while ((currLine = bufferedReader.readLine()) != null) {
+      if ((currLine = bufferedReader.readLine()) != null) {
         switch (currLine) {
           case MAGIC_STRING:
-            if (magicCount == 0) {
-              isFirstMagicStringExisted = true;
-            } else {
-              isEndMagicStringExisted = true;
-            }
-            magicCount++;
-            break;
-          case STR_TARGET_FILES:
-            isTargetFile = true;
+            // compaction log of version 0.13
+            isFirstMagicStringExisted = true;
+            analyzeLog(bufferedReader);
             break;
           case STR_SEQ_FILES:
-          case STR_UNSEQ_FILES:
-            isTargetFile = false;
+            // compaction log of version < 0.13
+            isLogFromOld = true;
+            analyzeOldLog(bufferedReader);
             break;
           default:
-            analyzeFilePath(isTargetFile, currLine);
-            break;
+            throw new InvalidPropertiesFormatException(
+                "Unsupported string in cross space log :" + 
logFile.getAbsolutePath());
         }
       }
     }
   }
 
-  void analyzeFilePath(boolean isTargetFile, String filePath) {
+  /** Analyze cross space compaction log of version 0.13. */
+  private void analyzeLog(BufferedReader bufferedReader) throws IOException {
+    String currLine;
+    boolean isTargetFile = false;
+    while ((currLine = bufferedReader.readLine()) != null) {
+      switch (currLine) {
+        case MAGIC_STRING:
+          isEndMagicStringExisted = true;
+          break;
+        case STR_TARGET_FILES:
+          isTargetFile = true;
+          break;
+        case STR_SEQ_FILES:
+        case STR_UNSEQ_FILES:
+          isTargetFile = false;
+          break;
+        default:
+          analyzeFilePath(isTargetFile, currLine);
+          break;
+      }
+    }
+  }
+
+  /** Analyze cross space compaction log of previous version (<0.13). */
+  private void analyzeOldLog(BufferedReader bufferedReader) throws IOException 
{
+    String currLine;
+    boolean isSeqSource = true;
+    while ((currLine = bufferedReader.readLine()) != null) {
+      if (currLine.equals(STR_UNSEQ_FILES)) {
+        isSeqSource = false;
+        continue;
+      }
+      analyzeOldFilePath(isSeqSource, currLine);
+    }
+  }
+
+  private void analyzeFilePath(boolean isTargetFile, String filePath) {
     if (isTargetFile) {
       
targetFileInfos.add(TsFileIdentifier.getFileIdentifierFromInfoString(filePath));
     } else {
@@ -88,8 +116,16 @@ public class RewriteCrossSpaceCompactionLogAnalyzer {
     }
   }
 
-  public List<String> getSourceFiles() {
-    return sourceFiles;
+  private void analyzeOldFilePath(boolean isSeqSource, String oldFilePath) {
+    
sourceFileInfos.add(TsFileIdentifier.getFileIdentifierFromOldInfoString(oldFilePath));
+    if (isSeqSource) {
+      String targetFilePath =
+          oldFilePath.replace(
+              TsFileConstant.TSFILE_SUFFIX,
+              TsFileConstant.TSFILE_SUFFIX
+                  + IoTDBConstant.CROSS_COMPACTION_TMP_FILE_SUFFIX_FROM_OLD);
+      
targetFileInfos.add(TsFileIdentifier.getFileIdentifierFromOldInfoString(targetFilePath));
+    }
   }
 
   public List<TsFileIdentifier> getSourceFileInfos() {
@@ -108,11 +144,7 @@ public class RewriteCrossSpaceCompactionLogAnalyzer {
     return isFirstMagicStringExisted;
   }
 
-  public String getTargetFile() {
-    return targetFile;
-  }
-
-  public boolean isSeq() {
-    return isSeq;
+  public boolean isLogFromOld() {
+    return isLogFromOld;
   }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/recover/RewriteCrossSpaceCompactionLogger.java
 
b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/recover/RewriteCrossSpaceCompactionLogger.java
index bcc305e..06ded5b 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/recover/RewriteCrossSpaceCompactionLogger.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/recover/RewriteCrossSpaceCompactionLogger.java
@@ -33,6 +33,7 @@ import java.util.List;
 public class RewriteCrossSpaceCompactionLogger implements AutoCloseable {
 
   public static final String COMPACTION_LOG_NAME = "cross-compaction.log";
+  public static final String COMPACTION_LOG_NAME_FEOM_OLD = "merge.log";
 
   public static final String STR_SEQ_FILES = "seqFiles";
   public static final String STR_TARGET_FILES = "targetFiles";
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/task/RewriteCrossCompactionRecoverTask.java
 
b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/task/RewriteCrossCompactionRecoverTask.java
index 775c9b1..1cabb2e 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/task/RewriteCrossCompactionRecoverTask.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/compaction/cross/rewrite/task/RewriteCrossCompactionRecoverTask.java
@@ -25,10 +25,15 @@ import 
org.apache.iotdb.db.engine.compaction.TsFileIdentifier;
 import 
org.apache.iotdb.db.engine.compaction.cross.rewrite.recover.RewriteCrossSpaceCompactionLogAnalyzer;
 import 
org.apache.iotdb.db.engine.compaction.inner.utils.InnerSpaceCompactionUtils;
 import org.apache.iotdb.db.engine.compaction.task.AbstractCompactionTask;
+import org.apache.iotdb.db.engine.modification.Modification;
 import org.apache.iotdb.db.engine.modification.ModificationFile;
 import org.apache.iotdb.db.engine.storagegroup.TsFileManager;
+import org.apache.iotdb.db.engine.storagegroup.TsFileNameGenerator;
 import org.apache.iotdb.db.engine.storagegroup.TsFileResource;
+import org.apache.iotdb.db.utils.FileLoaderUtils;
 import org.apache.iotdb.tsfile.common.constant.TsFileConstant;
+import org.apache.iotdb.tsfile.fileSystem.FSFactoryProducer;
+import org.apache.iotdb.tsfile.read.TsFileSequenceReader;
 
 import org.apache.commons.io.FileUtils;
 import org.slf4j.Logger;
@@ -42,9 +47,7 @@ import java.util.List;
 import java.util.concurrent.atomic.AtomicInteger;
 
 public class RewriteCrossCompactionRecoverTask extends 
RewriteCrossSpaceCompactionTask {
-
-  private static final Logger LOGGER =
-      LoggerFactory.getLogger(IoTDBConstant.COMPACTION_LOGGER_NAME);
+  private final Logger LOGGER = 
LoggerFactory.getLogger(IoTDBConstant.COMPACTION_LOGGER_NAME);
   private File compactionLogFile;
 
   public RewriteCrossCompactionRecoverTask(
@@ -101,11 +104,20 @@ public class RewriteCrossCompactionRecoverTask extends 
RewriteCrossSpaceCompacti
           }
         }
         if (isAllSourcesFileExisted) {
-          handleSuccess =
-              handleWithAllSourceFilesExist(
-                  targetFileIdentifiers, sourceFileIdentifiers, 
fullStorageGroupName);
+          if (logAnalyzer.isLogFromOld()) {
+            handleSuccess = 
handleWithAllSourceFilesExistFromOld(targetFileIdentifiers);
+          } else {
+            handleSuccess =
+                handleWithAllSourceFilesExist(targetFileIdentifiers, 
sourceFileIdentifiers);
+          }
         } else {
-          handleSuccess = 
handleWithoutAllSourceFilesExist(sourceFileIdentifiers);
+          if (logAnalyzer.isLogFromOld()) {
+            handleSuccess =
+                handleWithoutAllSourceFilesExistFromOld(
+                    targetFileIdentifiers, sourceFileIdentifiers);
+          } else {
+            handleSuccess = 
handleWithoutAllSourceFilesExist(sourceFileIdentifiers);
+          }
         }
       }
     } catch (IOException e) {
@@ -142,15 +154,13 @@ public class RewriteCrossCompactionRecoverTask extends 
RewriteCrossSpaceCompacti
    * compaction mods files.
    */
   private boolean handleWithAllSourceFilesExist(
-      List<TsFileIdentifier> targetFileIdentifiers,
-      List<TsFileIdentifier> sourceFileIdentifiers,
-      String fullStorageGroupName) {
+      List<TsFileIdentifier> targetFileIdentifiers, List<TsFileIdentifier> 
sourceFileIdentifiers) {
     LOGGER.info(
         "{} [Compaction][Recover] all source files exists, delete all target 
files.",
         fullStorageGroupName);
 
     for (TsFileIdentifier targetFileIdentifier : targetFileIdentifiers) {
-      // xxx.merge
+      // xxx.cross
       File tmpTargetFile = targetFileIdentifier.getFileFromDataDirs();
       // xxx.tsfile
       File targetFile =
@@ -239,6 +249,168 @@ public class RewriteCrossCompactionRecoverTask extends 
RewriteCrossSpaceCompacti
     return handleSuccess;
   }
 
+  /** Delete tmp target file and compaction mods file. */
+  private boolean handleWithAllSourceFilesExistFromOld(
+      List<TsFileIdentifier> targetFileIdentifiers) {
+    // delete tmp target file
+    for (TsFileIdentifier targetFileIdentifier : targetFileIdentifiers) {
+      // xxx.tsfile.merge
+      File tmpTargetFile = targetFileIdentifier.getFileFromDataDirs();
+      if (tmpTargetFile != null) {
+        tmpTargetFile.delete();
+      }
+    }
+    File compactionModsFileFromOld =
+        new File(
+            tsFileManager.getStorageGroupDir()
+                + File.separator
+                + IoTDBConstant.COMPACTION_MODIFICATION_FILE_NAME_FROM_OLD);
+    if (compactionModsFileFromOld.exists() && 
!compactionModsFileFromOld.delete()) {
+      LOGGER.error(
+          "{} [Compaction][Recover] fail to delete target file {}, this may 
cause data incorrectness",
+          fullStorageGroupName,
+          compactionModsFileFromOld);
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * 1. If target file does not exist, then move .merge file to target file 
<br>
+   * 2. If target resource file does not exist, then serialize it. <br>
+   * 3. Append merging modification to target mods file and delete merging 
mods file. <br>
+   * 4. Delete source files and .merge file. <br>
+   */
+  private boolean handleWithoutAllSourceFilesExistFromOld(
+      List<TsFileIdentifier> targetFileIdentifiers, List<TsFileIdentifier> 
sourceFileIdentifiers) {
+    try {
+      File compactionModsFileFromOld =
+          new File(
+              tsFileManager.getStorageGroupDir()
+                  + File.separator
+                  + IoTDBConstant.COMPACTION_MODIFICATION_FILE_NAME_FROM_OLD);
+      List<TsFileResource> targetFileResources = new ArrayList<>();
+      for (int i = 0; i < sourceFileIdentifiers.size(); i++) {
+        TsFileIdentifier sourceFileIdentifier = sourceFileIdentifiers.get(i);
+        if (sourceFileIdentifier.isSequence()) {
+          File tmpTargetFile = 
targetFileIdentifiers.get(i).getFileFromDataDirs();
+          File targetFile = null;
+
+          // move tmp target file to target file if not exist
+          if (tmpTargetFile != null) {
+            // move tmp target file to target file
+            String sourceFilePath =
+                tmpTargetFile
+                    .getPath()
+                    .replace(
+                        TsFileConstant.TSFILE_SUFFIX
+                            + 
IoTDBConstant.CROSS_COMPACTION_TMP_FILE_SUFFIX_FROM_OLD,
+                        TsFileConstant.TSFILE_SUFFIX);
+            targetFile = TsFileNameGenerator.increaseCrossCompactionCnt(new 
File(sourceFilePath));
+            FSFactoryProducer.getFSFactory().moveFile(tmpTargetFile, 
targetFile);
+          } else {
+            // target file must exist
+            File file =
+                TsFileNameGenerator.increaseCrossCompactionCnt(
+                    new File(
+                        targetFileIdentifiers
+                            .get(i)
+                            .getFilePath()
+                            .replace(
+                                TsFileConstant.TSFILE_SUFFIX
+                                    + 
IoTDBConstant.CROSS_COMPACTION_TMP_FILE_SUFFIX_FROM_OLD,
+                                TsFileConstant.TSFILE_SUFFIX)));
+
+            targetFile = getFileFromDataDirs(file.getPath());
+          }
+          if (targetFile == null) {
+            LOGGER.error(
+                "{} [Compaction][Recover] target file of source seq file {} 
does not exist (<0.13).",
+                fullStorageGroupName,
+                sourceFileIdentifier.getFilePath());
+            return false;
+          }
+
+          // serialize target resource file if not exist
+          TsFileResource targetResource = new TsFileResource(targetFile);
+          if (!targetResource.resourceFileExists()) {
+            try (TsFileSequenceReader reader =
+                new TsFileSequenceReader(targetFile.getAbsolutePath())) {
+              FileLoaderUtils.updateTsFileResource(reader, targetResource);
+            }
+            targetResource.serialize();
+          }
+
+          targetFileResources.add(targetResource);
+
+          // append compaction modifications to target mods file and delete 
compaction mods file
+          if (compactionModsFileFromOld.exists()) {
+            ModificationFile compactionModsFile =
+                new ModificationFile(compactionModsFileFromOld.getPath());
+            appendCompactionModificationsFromOld(targetResource, 
compactionModsFile);
+          }
+
+          // delete tmp target file
+          if (tmpTargetFile != null) {
+            tmpTargetFile.delete();
+          }
+        }
+
+        // delete source tsfile
+        File sourceFile = sourceFileIdentifier.getFileFromDataDirs();
+        if (sourceFile != null) {
+          sourceFile.delete();
+        }
+
+        // delete source resource file
+        sourceFile =
+            getFileFromDataDirs(
+                sourceFileIdentifier.getFilePath() + 
TsFileResource.RESOURCE_SUFFIX);
+        if (sourceFile != null) {
+          sourceFile.delete();
+        }
+
+        // delete source mods file
+        sourceFile =
+            getFileFromDataDirs(sourceFileIdentifier.getFilePath() + 
ModificationFile.FILE_SUFFIX);
+        if (sourceFile != null) {
+          sourceFile.delete();
+        }
+      }
+
+      // delete compaction mods file
+      if (compactionModsFileFromOld.exists() && 
!compactionModsFileFromOld.delete()) {
+        LOGGER.error(
+            "{} [Compaction][Recover] fail to delete target file {}, this may 
cause data incorrectness",
+            fullStorageGroupName,
+            compactionModsFileFromOld);
+        return false;
+      }
+    } catch (Throwable e) {
+      LOGGER.error(
+          "{} [Compaction][Recover] fail to handle with some source files lost 
from old version.",
+          fullStorageGroupName,
+          e);
+      return false;
+    }
+
+    return true;
+  }
+
+  public void appendCompactionModificationsFromOld(
+      TsFileResource resource, ModificationFile compactionModsFile) throws 
IOException {
+
+    if (compactionModsFile != null) {
+      for (Modification modification : compactionModsFile.getModifications()) {
+        // we have to set modification offset to MAX_VALUE, as the offset of 
source chunk may
+        // change after compaction
+        modification.setFileOffset(Long.MAX_VALUE);
+        resource.getModFile().write(modification);
+      }
+      resource.getModFile().close();
+    }
+  }
+
   /**
    * This method find the File object of given filePath by searching it in 
every data directory. If
    * the file is not found, it will return null.
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/compaction/task/CompactionRecoverTask.java
 
b/server/src/main/java/org/apache/iotdb/db/engine/compaction/task/CompactionRecoverTask.java
index 8e1aa1e..7b6b816 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/compaction/task/CompactionRecoverTask.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/compaction/task/CompactionRecoverTask.java
@@ -18,6 +18,7 @@
  */
 package org.apache.iotdb.db.engine.compaction.task;
 
+import org.apache.iotdb.db.conf.IoTDBConstant;
 import org.apache.iotdb.db.conf.IoTDBDescriptor;
 import org.apache.iotdb.db.conf.directories.DirectoryManager;
 import 
org.apache.iotdb.db.engine.compaction.cross.rewrite.recover.RewriteCrossSpaceCompactionLogger;
@@ -35,7 +36,8 @@ import java.util.regex.Pattern;
  * InnerCompactionTask in sequence/unsequence space, CrossSpaceCompaction.
  */
 public class CompactionRecoverTask {
-  private static final Logger logger = 
LoggerFactory.getLogger(CompactionRecoverTask.class);
+  private static final Logger logger =
+      LoggerFactory.getLogger(IoTDBConstant.COMPACTION_LOGGER_NAME);
   private TsFileManager tsFileManager;
   private String logicalStorageGroupName;
   private String virtualStorageGroupId;
@@ -49,6 +51,7 @@ public class CompactionRecoverTask {
 
   public void recoverCrossSpaceCompaction() throws Exception {
     logger.info("recovering cross compaction");
+    recoverCrossCompactionFromOldVersion();
     recoverCrossCompaction();
     logger.info("try to synchronize CompactionScheduler");
   }
@@ -94,4 +97,26 @@ public class CompactionRecoverTask {
       }
     }
   }
+
+  private void recoverCrossCompactionFromOldVersion() throws Exception {
+    // check whether there is old compaction log from previous version (<0.13)
+    File mergeLogFromOldVersion =
+        new File(
+            tsFileManager.getStorageGroupDir()
+                + File.separator
+                + 
RewriteCrossSpaceCompactionLogger.COMPACTION_LOG_NAME_FEOM_OLD);
+    if (mergeLogFromOldVersion.exists()) {
+      logger.info("calling cross compaction task to recover from previous 
version.");
+      IoTDBDescriptor.getInstance()
+          .getConfig()
+          .getCrossCompactionStrategy()
+          .getCompactionRecoverTask(
+              logicalStorageGroupName,
+              virtualStorageGroupId,
+              0L,
+              mergeLogFromOldVersion,
+              tsFileManager)
+          .call();
+    }
+  }
 }
diff --git 
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileNameGenerator.java
 
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileNameGenerator.java
index 64e6912..ae6a13a 100644
--- 
a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileNameGenerator.java
+++ 
b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/TsFileNameGenerator.java
@@ -163,7 +163,7 @@ public class TsFileNameGenerator {
    * own tmp target file.
    *
    * @param seqResources
-   * @return tmp target file list, which is xxx.merge
+   * @return tmp target file list, which is xxx.cross
    * @throws IOException
    */
   public static List<TsFileResource> getCrossCompactionTargetFileResources(

Reply via email to