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

haonan 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 bf36ca3a3f [IOTDB-3649] Fix stack overflow when deleting wal (#6432)
bf36ca3a3f is described below

commit bf36ca3a3f3bc034c8ef29c3594b42815c103f39
Author: Alan Choo <[email protected]>
AuthorDate: Sat Jun 25 13:30:25 2022 +0800

    [IOTDB-3649] Fix stack overflow when deleting wal (#6432)
---
 .../java/org/apache/iotdb/db/wal/node/WALNode.java | 38 +++++++++++++++-------
 1 file changed, 27 insertions(+), 11 deletions(-)

diff --git a/server/src/main/java/org/apache/iotdb/db/wal/node/WALNode.java 
b/server/src/main/java/org/apache/iotdb/db/wal/node/WALNode.java
index edb872c64b..5d85114446 100644
--- a/server/src/main/java/org/apache/iotdb/db/wal/node/WALNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/wal/node/WALNode.java
@@ -215,8 +215,11 @@ public class WALNode implements IWALNode {
   }
 
   private class DeleteOutdatedFileTask implements Runnable {
+    private static final int MAX_RECURSION_TIME = 5;
     /** .wal files whose version ids are less than first valid version id 
should be deleted */
     private long firstValidVersionId;
+    /** recursion time of calling deletion */
+    private int recursionTime = 0;
 
     @Override
     public void run() {
@@ -251,8 +254,11 @@ public class WALNode implements IWALNode {
       // calculate effective information ratio
       long costOfActiveMemTables = 
checkpointManager.getTotalCostOfActiveMemTables();
       long costOfFlushedMemTables = totalCostOfFlushedMemTables.get();
-      double effectiveInfoRatio =
-          (double) costOfActiveMemTables / (costOfActiveMemTables + 
costOfFlushedMemTables);
+      long totalCost = costOfActiveMemTables + costOfFlushedMemTables;
+      if (totalCost == 0) {
+        return;
+      }
+      double effectiveInfoRatio = (double) costOfActiveMemTables / totalCost;
       logger.debug(
           "Effective information ratio is {}, active memTables cost is {}, 
flushed memTables cost is {}",
           effectiveInfoRatio,
@@ -263,12 +269,16 @@ public class WALNode implements IWALNode {
       // then delete old .wal files again
       if (effectiveInfoRatio < config.getWalMinEffectiveInfoRatio()) {
         logger.info(
-            "Effective information ratio {} of wal node-{} is below wal min 
effective info ratio {}, some mamTables will be snapshot or flushed.",
+            "Effective information ratio {} (active memTables cost is {}, 
flushed memTables cost is {}) of wal node-{} is below wal min effective info 
ratio {}, some mamTables will be snapshot or flushed.",
             effectiveInfoRatio,
+            costOfActiveMemTables,
+            costOfFlushedMemTables,
             identifier,
             config.getWalMinEffectiveInfoRatio());
-        snapshotOrFlushMemTable();
-        run();
+        if (snapshotOrFlushMemTable() && recursionTime < MAX_RECURSION_TIME) {
+          run();
+          recursionTime++;
+        }
       }
     }
 
@@ -330,11 +340,16 @@ public class WALNode implements IWALNode {
       return toDelete;
     }
 
-    private void snapshotOrFlushMemTable() {
+    /**
+     * Snapshot or flush one memTable,
+     *
+     * @return true if snapshot or flushed
+     */
+    private boolean snapshotOrFlushMemTable() {
       // find oldest memTable
       MemTableInfo oldestMemTableInfo = 
checkpointManager.getOldestMemTableInfo();
       if (oldestMemTableInfo == null) {
-        return;
+        return false;
       }
       IMemTable oldestMemTable = oldestMemTableInfo.getMemTable();
 
@@ -356,7 +371,7 @@ public class WALNode implements IWALNode {
         }
       } catch (IllegalPathException | StorageEngineException e) {
         logger.error("Fail to get virtual storage group processor for {}", 
oldestTsFile, e);
-        return;
+        return false;
       }
 
       // snapshot or flush memTable
@@ -367,12 +382,13 @@ public class WALNode implements IWALNode {
       } else {
         snapshotMemTable(dataRegion, oldestTsFile, oldestMemTableInfo);
       }
+      return true;
     }
 
     private void flushMemTable(DataRegion dataRegion, File tsFile, IMemTable 
memTable) {
-      boolean shouldWait = true;
+      boolean submitted = true;
       if (memTable.getFlushStatus() == FlushStatus.WORKING) {
-        shouldWait =
+        submitted =
             dataRegion.submitAFlushTask(
                 TsFileUtils.getTimePartition(tsFile), 
TsFileUtils.isSequence(tsFile), memTable);
         logger.info(
@@ -384,7 +400,7 @@ public class WALNode implements IWALNode {
       }
 
       // it's fine to wait until memTable has been flushed, because deleting 
files is not urgent.
-      if (shouldWait) {
+      if (submitted || memTable.getFlushStatus() == FlushStatus.FLUSHING) {
         long sleepTime = 0;
         while (memTable.getFlushStatus() != FlushStatus.FLUSHED) {
           try {

Reply via email to