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

jt2594838 pushed a commit to branch dev/1.3
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/dev/1.3 by this push:
     new 8915a2e94c8 [Load] Isolate reused TsFile parser memory from Pipe pool 
(#18419) (#18436)
8915a2e94c8 is described below

commit 8915a2e94c8f95cd568196c795e449ce32fc667c
Author: Caideyipi <[email protected]>
AuthorDate: Tue Aug 11 17:10:46 2026 +0800

    [Load] Isolate reused TsFile parser memory from Pipe pool (#18419) (#18436)
    
    * fix(load): isolate reused tsfile parser memory from pipe pool
    
    * test(load): cover repeated zero-size parser resize
    
    (cherry picked from commit 85442f00f85ecab9bfaf903568ceb97712d1fc59)
---
 .../container/TsFileInsertionDataContainer.java    |  40 +++++--
 .../query/TsFileInsertionQueryDataContainer.java   |  65 ++++++++++--
 .../TsFileInsertionQueryDataTabletIterator.java    |  10 +-
 .../scan/TsFileInsertionScanDataContainer.java     |  94 +++++++++++++----
 .../TsFileInsertionEventParserMemoryBlock.java     |  37 +++++++
 .../TsFileInsertionEventParserMemoryManager.java   |  75 +++++++++++++
 .../converter/LoadTreeTsFileTabletIterator.java    |  23 +++-
 .../load/memory/LoadTsFileMemoryBlock.java         |  22 +++-
 .../load/memory/LoadTsFileMemoryManager.java       |  44 ++++++++
 .../load/memory/LoadTsFileParserMemoryManager.java | 116 +++++++++++++++++++++
 .../event/TsFileInsertionDataContainerTest.java    |  55 +++++++---
 .../LoadTsFileParserPipeMemoryIsolationTest.java   |  66 ++++++++++++
 .../load/memory/LoadTsFileMemoryManagerTest.java   |  20 ++++
 13 files changed, 605 insertions(+), 62 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/TsFileInsertionDataContainer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/TsFileInsertionDataContainer.java
index 57757ec1f62..a02f82cd33e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/TsFileInsertionDataContainer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/TsFileInsertionDataContainer.java
@@ -23,9 +23,9 @@ import org.apache.iotdb.commons.path.PatternTreeMap;
 import org.apache.iotdb.commons.pipe.agent.task.meta.PipeTaskMeta;
 import org.apache.iotdb.commons.pipe.datastructure.pattern.PipePattern;
 import org.apache.iotdb.commons.pipe.event.EnrichedEvent;
+import 
org.apache.iotdb.db.pipe.event.common.tsfile.parser.TsFileInsertionEventParserMemoryBlock;
+import 
org.apache.iotdb.db.pipe.event.common.tsfile.parser.TsFileInsertionEventParserMemoryManager;
 import org.apache.iotdb.db.pipe.metric.overview.PipeTsFileToTabletsMetrics;
-import org.apache.iotdb.db.pipe.resource.PipeDataNodeResourceManager;
-import org.apache.iotdb.db.pipe.resource.memory.PipeMemoryBlock;
 import org.apache.iotdb.db.pipe.resource.memory.PipeMemoryWeightUtil;
 import org.apache.iotdb.db.storageengine.dataregion.modification.Modification;
 import org.apache.iotdb.db.utils.datastructure.PatternTreeMapFactory;
@@ -55,14 +55,16 @@ public abstract class TsFileInsertionDataContainer 
implements AutoCloseable {
   protected final EnrichedEvent sourceEvent; // used to report progress
 
   // mods entry
-  protected PipeMemoryBlock allocatedMemoryBlockForModifications;
+  protected TsFileInsertionEventParserMemoryBlock 
allocatedMemoryBlockForModifications;
   protected PatternTreeMap<Modification, PatternTreeMapFactory.ModsSerializer> 
currentModifications;
 
   protected long parseStartTimeNano = -1;
   protected boolean parseStartTimeRecorded = false;
   protected boolean parseEndTimeRecorded = false;
 
-  protected final PipeMemoryBlock allocatedMemoryBlockForTablet;
+  protected final TsFileInsertionEventParserMemoryBlock 
allocatedMemoryBlockForTablet;
+
+  protected final TsFileInsertionEventParserMemoryManager memoryManager;
 
   protected TsFileSequenceReader tsFileSequenceReader;
 
@@ -78,6 +80,30 @@ public abstract class TsFileInsertionDataContainer 
implements AutoCloseable {
       final PipeTaskMeta pipeTaskMeta,
       final EnrichedEvent sourceEvent,
       final boolean isWithMod) {
+    this(
+        tsFile,
+        pipeName,
+        creationTime,
+        pattern,
+        startTime,
+        endTime,
+        pipeTaskMeta,
+        sourceEvent,
+        isWithMod,
+        TsFileInsertionEventParserMemoryManager.pipe());
+  }
+
+  protected TsFileInsertionDataContainer(
+      final File tsFile,
+      final String pipeName,
+      final long creationTime,
+      final PipePattern pattern,
+      final long startTime,
+      final long endTime,
+      final PipeTaskMeta pipeTaskMeta,
+      final EnrichedEvent sourceEvent,
+      final boolean isWithMod,
+      final TsFileInsertionEventParserMemoryManager memoryManager) {
     this.pipeName = pipeName;
     this.creationTime = creationTime;
 
@@ -89,10 +115,10 @@ public abstract class TsFileInsertionDataContainer 
implements AutoCloseable {
 
     this.pipeTaskMeta = pipeTaskMeta;
     this.sourceEvent = sourceEvent;
+    this.memoryManager = memoryManager;
 
     // Allocate empty memory block, will be resized later.
-    this.allocatedMemoryBlockForTablet =
-        
PipeDataNodeResourceManager.memory().forceAllocateForTabletWithRetry(0);
+    this.allocatedMemoryBlockForTablet = 
memoryManager.forceAllocateForTabletWithRetry(0);
 
     if (LOGGER.isDebugEnabled()) {
       LOGGER.debug(
@@ -166,7 +192,7 @@ public abstract class TsFileInsertionDataContainer 
implements AutoCloseable {
   protected void releaseTabletMemoryBlock() {
     if (allocatedMemoryBlockForTablet != null
         && allocatedMemoryBlockForTablet.getMemoryUsageInBytes() > 0) {
-      
PipeDataNodeResourceManager.memory().forceResize(allocatedMemoryBlockForTablet, 
0);
+      allocatedMemoryBlockForTablet.forceResize(0);
     }
   }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/query/TsFileInsertionQueryDataContainer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/query/TsFileInsertionQueryDataContainer.java
index 7659c3c5555..1754b7a222e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/query/TsFileInsertionQueryDataContainer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/query/TsFileInsertionQueryDataContainer.java
@@ -27,9 +27,10 @@ import org.apache.iotdb.commons.utils.TestOnly;
 import 
org.apache.iotdb.db.pipe.event.common.tablet.PipeRawTabletInsertionEvent;
 import 
org.apache.iotdb.db.pipe.event.common.tablet.PipeTabletUtils.TabletStringInternPool;
 import 
org.apache.iotdb.db.pipe.event.common.tsfile.container.TsFileInsertionDataContainer;
+import 
org.apache.iotdb.db.pipe.event.common.tsfile.parser.TsFileInsertionEventParserMemoryBlock;
+import 
org.apache.iotdb.db.pipe.event.common.tsfile.parser.TsFileInsertionEventParserMemoryManager;
 import 
org.apache.iotdb.db.pipe.event.common.tsfile.parser.util.ModsOperationUtil;
 import org.apache.iotdb.db.pipe.resource.PipeDataNodeResourceManager;
-import org.apache.iotdb.db.pipe.resource.memory.PipeMemoryBlock;
 import org.apache.iotdb.db.pipe.resource.memory.PipeMemoryWeightUtil;
 import org.apache.iotdb.db.pipe.resource.tsfile.PipeTsFileResourceManager;
 import org.apache.iotdb.db.utils.datastructure.PatternTreeMapFactory;
@@ -65,7 +66,7 @@ public class TsFileInsertionQueryDataContainer extends 
TsFileInsertionDataContai
   private static final Logger LOGGER =
       LoggerFactory.getLogger(TsFileInsertionQueryDataContainer.class);
 
-  private final PipeMemoryBlock allocatedMemoryBlock;
+  private final TsFileInsertionEventParserMemoryBlock allocatedMemoryBlock;
   private final TsFileReader tsFileReader;
 
   private final Iterator<Map.Entry<IDeviceID, List<String>>> 
deviceMeasurementsMapIterator;
@@ -145,6 +146,35 @@ public class TsFileInsertionQueryDataContainer extends 
TsFileInsertionDataContai
       final Map<IDeviceID, List<String>> deviceMeasurementsMapOverride,
       final boolean isWithMod)
       throws IOException {
+    this(
+        pipeName,
+        creationTime,
+        tsFile,
+        pattern,
+        startTime,
+        endTime,
+        pipeTaskMeta,
+        sourceEvent,
+        deviceIsAlignedMap,
+        deviceMeasurementsMapOverride,
+        isWithMod,
+        TsFileInsertionEventParserMemoryManager.pipe());
+  }
+
+  public TsFileInsertionQueryDataContainer(
+      final String pipeName,
+      final long creationTime,
+      final File tsFile,
+      final PipePattern pattern,
+      final long startTime,
+      final long endTime,
+      final PipeTaskMeta pipeTaskMeta,
+      final EnrichedEvent sourceEvent,
+      final Map<IDeviceID, Boolean> deviceIsAlignedMap,
+      final Map<IDeviceID, List<String>> deviceMeasurementsMapOverride,
+      final boolean isWithMod,
+      final TsFileInsertionEventParserMemoryManager memoryManager)
+      throws IOException {
     super(
         tsFile,
         pipeName,
@@ -154,7 +184,8 @@ public class TsFileInsertionQueryDataContainer extends 
TsFileInsertionDataContai
         endTime,
         pipeTaskMeta,
         sourceEvent,
-        isWithMod);
+        isWithMod,
+        memoryManager);
 
     try {
       currentModifications =
@@ -162,8 +193,7 @@ public class TsFileInsertionQueryDataContainer extends 
TsFileInsertionDataContai
               ? ModsOperationUtil.loadModificationsFromTsFile(tsFile)
               : PatternTreeMapFactory.getModsPatternTreeMap();
       allocatedMemoryBlockForModifications =
-          PipeDataNodeResourceManager.memory()
-              
.forceAllocateForTabletWithRetry(currentModifications.ramBytesUsed());
+          
memoryManager.forceAllocateForTabletWithRetry(currentModifications.ramBytesUsed());
 
       final PipeTsFileResourceManager tsFileResourceManager = 
PipeDataNodeResourceManager.tsfile();
       final Map<IDeviceID, List<String>> deviceMeasurementsMap;
@@ -224,8 +254,7 @@ public class TsFileInsertionQueryDataContainer extends 
TsFileInsertionDataContai
         memoryRequiredInBytes +=
             
PipeMemoryWeightUtil.memoryOfIDeviceID2StrList(deviceMeasurementsMap);
       }
-      allocatedMemoryBlock =
-          
PipeDataNodeResourceManager.memory().forceAllocate(memoryRequiredInBytes);
+      allocatedMemoryBlock = 
memoryManager.forceAllocate(memoryRequiredInBytes);
 
       final Iterator<Map.Entry<IDeviceID, List<String>>> iterator =
           deviceMeasurementsMap.entrySet().iterator();
@@ -301,6 +330,25 @@ public class TsFileInsertionQueryDataContainer extends 
TsFileInsertionDataContai
       final Map<IDeviceID, List<String>> deviceMeasurementsMapOverride,
       final boolean isWithMod)
       throws IOException {
+    this(
+        tsFile,
+        pattern,
+        startTime,
+        endTime,
+        deviceMeasurementsMapOverride,
+        isWithMod,
+        TsFileInsertionEventParserMemoryManager.pipe());
+  }
+
+  public TsFileInsertionQueryDataContainer(
+      final File tsFile,
+      final PipePattern pattern,
+      final long startTime,
+      final long endTime,
+      final Map<IDeviceID, List<String>> deviceMeasurementsMapOverride,
+      final boolean isWithMod,
+      final TsFileInsertionEventParserMemoryManager memoryManager)
+      throws IOException {
     this(
         null,
         0,
@@ -312,7 +360,8 @@ public class TsFileInsertionQueryDataContainer extends 
TsFileInsertionDataContai
         null,
         null,
         deviceMeasurementsMapOverride,
-        isWithMod);
+        isWithMod,
+        memoryManager);
   }
 
   private Map<IDeviceID, List<String>> filterDeviceMeasurementsMapByPattern(
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/query/TsFileInsertionQueryDataTabletIterator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/query/TsFileInsertionQueryDataTabletIterator.java
index 2e81f4aa335..a763b45976e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/query/TsFileInsertionQueryDataTabletIterator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/query/TsFileInsertionQueryDataTabletIterator.java
@@ -22,9 +22,8 @@ package 
org.apache.iotdb.db.pipe.event.common.tsfile.container.query;
 import org.apache.iotdb.commons.path.PatternTreeMap;
 import org.apache.iotdb.db.pipe.event.common.tablet.PipeTabletUtils;
 import 
org.apache.iotdb.db.pipe.event.common.tablet.PipeTabletUtils.TabletStringInternPool;
+import 
org.apache.iotdb.db.pipe.event.common.tsfile.parser.TsFileInsertionEventParserMemoryBlock;
 import 
org.apache.iotdb.db.pipe.event.common.tsfile.parser.util.ModsOperationUtil;
-import org.apache.iotdb.db.pipe.resource.PipeDataNodeResourceManager;
-import org.apache.iotdb.db.pipe.resource.memory.PipeMemoryBlock;
 import org.apache.iotdb.db.pipe.resource.memory.PipeMemoryWeightUtil;
 import org.apache.iotdb.db.storageengine.dataregion.modification.Modification;
 import org.apache.iotdb.db.utils.datastructure.PatternTreeMapFactory;
@@ -66,7 +65,7 @@ public class TsFileInsertionQueryDataTabletIterator 
implements Iterator<Tablet>
 
   private final QueryDataSet queryDataSet;
 
-  private final PipeMemoryBlock allocatedBlockForTablet;
+  private final TsFileInsertionEventParserMemoryBlock allocatedBlockForTablet;
 
   // Maintain sorted mods list and current index for each measurement
   private final List<ModsOperationUtil.ModsInfo> measurementModsList;
@@ -79,7 +78,7 @@ public class TsFileInsertionQueryDataTabletIterator 
implements Iterator<Tablet>
       final String deviceId,
       final List<String> measurements,
       final IExpression timeFilterExpression,
-      final PipeMemoryBlock allocatedBlockForTablet,
+      final TsFileInsertionEventParserMemoryBlock allocatedBlockForTablet,
       final PatternTreeMap<Modification, PatternTreeMapFactory.ModsSerializer> 
currentModifications,
       final TabletStringInternPool tabletStringInternPool)
       throws IOException {
@@ -160,8 +159,7 @@ public class TsFileInsertionQueryDataTabletIterator 
implements Iterator<Tablet>
             PipeMemoryWeightUtil.calculateTabletRowCountAndMemory(rowRecord);
         tablet = new Tablet(deviceId, schemas, 
rowCountAndMemorySize.getLeft());
         if (allocatedBlockForTablet.getMemoryUsageInBytes() < 
rowCountAndMemorySize.getRight()) {
-          PipeDataNodeResourceManager.memory()
-              .forceResize(allocatedBlockForTablet, 
rowCountAndMemorySize.getRight());
+          
allocatedBlockForTablet.forceResize(rowCountAndMemorySize.getRight());
         }
         this.rowRecord = null; // Clear the saved first row
         isFirstRow = false;
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/scan/TsFileInsertionScanDataContainer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/scan/TsFileInsertionScanDataContainer.java
index 17d11c7ee7a..6572c92eb9a 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/scan/TsFileInsertionScanDataContainer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/container/scan/TsFileInsertionScanDataContainer.java
@@ -29,9 +29,9 @@ import 
org.apache.iotdb.db.pipe.event.common.tablet.PipeRawTabletInsertionEvent;
 import org.apache.iotdb.db.pipe.event.common.tablet.PipeTabletUtils;
 import 
org.apache.iotdb.db.pipe.event.common.tablet.PipeTabletUtils.TabletStringInternPool;
 import 
org.apache.iotdb.db.pipe.event.common.tsfile.container.TsFileInsertionDataContainer;
+import 
org.apache.iotdb.db.pipe.event.common.tsfile.parser.TsFileInsertionEventParserMemoryBlock;
+import 
org.apache.iotdb.db.pipe.event.common.tsfile.parser.TsFileInsertionEventParserMemoryManager;
 import 
org.apache.iotdb.db.pipe.event.common.tsfile.parser.util.ModsOperationUtil;
-import org.apache.iotdb.db.pipe.resource.PipeDataNodeResourceManager;
-import org.apache.iotdb.db.pipe.resource.memory.PipeMemoryBlock;
 import org.apache.iotdb.db.pipe.resource.memory.PipeMemoryWeightUtil;
 import 
org.apache.iotdb.db.storageengine.dataregion.compaction.execute.utils.CompactionPathUtils;
 import org.apache.iotdb.db.utils.datastructure.PatternTreeMapFactory;
@@ -90,8 +90,8 @@ public class TsFileInsertionScanDataContainer extends 
TsFileInsertionDataContain
 
   private IChunkReader chunkReader;
   private BatchData data;
-  private final PipeMemoryBlock allocatedMemoryBlockForBatchData;
-  private final PipeMemoryBlock allocatedMemoryBlockForChunk;
+  private final TsFileInsertionEventParserMemoryBlock 
allocatedMemoryBlockForBatchData;
+  private final TsFileInsertionEventParserMemoryBlock 
allocatedMemoryBlockForChunk;
 
   private boolean currentIsMultiPage;
   private String currentDevice;
@@ -123,6 +123,31 @@ public class TsFileInsertionScanDataContainer extends 
TsFileInsertionDataContain
       final EnrichedEvent sourceEvent,
       final boolean isWithMod)
       throws IOException {
+    this(
+        pipeName,
+        creationTime,
+        tsFile,
+        pattern,
+        startTime,
+        endTime,
+        pipeTaskMeta,
+        sourceEvent,
+        isWithMod,
+        TsFileInsertionEventParserMemoryManager.pipe());
+  }
+
+  public TsFileInsertionScanDataContainer(
+      final String pipeName,
+      final long creationTime,
+      final File tsFile,
+      final PipePattern pattern,
+      final long startTime,
+      final long endTime,
+      final PipeTaskMeta pipeTaskMeta,
+      final EnrichedEvent sourceEvent,
+      final boolean isWithMod,
+      final TsFileInsertionEventParserMemoryManager memoryManager)
+      throws IOException {
     super(
         tsFile,
         pipeName,
@@ -132,16 +157,15 @@ public class TsFileInsertionScanDataContainer extends 
TsFileInsertionDataContain
         endTime,
         pipeTaskMeta,
         sourceEvent,
-        isWithMod);
+        isWithMod,
+        memoryManager);
 
     this.startTime = startTime;
     this.endTime = endTime;
     filter = Objects.nonNull(timeFilterExpression) ? 
timeFilterExpression.getFilter() : null;
 
-    this.allocatedMemoryBlockForBatchData =
-        
PipeDataNodeResourceManager.memory().forceAllocateForTabletWithRetry(0);
-    this.allocatedMemoryBlockForChunk =
-        
PipeDataNodeResourceManager.memory().forceAllocateForTabletWithRetry(0);
+    this.allocatedMemoryBlockForBatchData = 
memoryManager.forceAllocateForTabletWithRetry(0);
+    this.allocatedMemoryBlockForChunk = 
memoryManager.forceAllocateForTabletWithRetry(0);
 
     try {
       currentModifications =
@@ -149,8 +173,7 @@ public class TsFileInsertionScanDataContainer extends 
TsFileInsertionDataContain
               ? ModsOperationUtil.loadModificationsFromTsFile(tsFile)
               : PatternTreeMapFactory.getModsPatternTreeMap();
       allocatedMemoryBlockForModifications =
-          PipeDataNodeResourceManager.memory()
-              
.forceAllocateForTabletWithRetry(currentModifications.ramBytesUsed());
+          
memoryManager.forceAllocateForTabletWithRetry(currentModifications.ramBytesUsed());
 
       tsFileSequenceReader =
           new TsFileSequenceReader(
@@ -178,7 +201,38 @@ public class TsFileInsertionScanDataContainer extends 
TsFileInsertionDataContain
       final EnrichedEvent sourceEvent,
       final boolean isWithMod)
       throws IOException {
-    this(null, 0, tsFile, pattern, startTime, endTime, pipeTaskMeta, 
sourceEvent, isWithMod);
+    this(
+        tsFile,
+        pattern,
+        startTime,
+        endTime,
+        pipeTaskMeta,
+        sourceEvent,
+        isWithMod,
+        TsFileInsertionEventParserMemoryManager.pipe());
+  }
+
+  public TsFileInsertionScanDataContainer(
+      final File tsFile,
+      final PipePattern pattern,
+      final long startTime,
+      final long endTime,
+      final PipeTaskMeta pipeTaskMeta,
+      final EnrichedEvent sourceEvent,
+      final boolean isWithMod,
+      final TsFileInsertionEventParserMemoryManager memoryManager)
+      throws IOException {
+    this(
+        null,
+        0,
+        tsFile,
+        pattern,
+        startTime,
+        endTime,
+        pipeTaskMeta,
+        sourceEvent,
+        isWithMod,
+        memoryManager);
   }
 
   @Override
@@ -303,7 +357,7 @@ public class TsFileInsertionScanDataContainer extends 
TsFileInsertionDataContain
       if (!data.hasCurrent()) {
         tablet = new Tablet(currentDevice, currentMeasurements, 1);
         // Ignore the memory cost of tablet
-        
PipeDataNodeResourceManager.memory().forceResize(allocatedMemoryBlockForTablet, 
0);
+        allocatedMemoryBlockForTablet.forceResize(0);
         return tablet;
       }
 
@@ -319,8 +373,7 @@ public class TsFileInsertionScanDataContainer extends 
TsFileInsertionDataContain
                 new Tablet(currentDevice, currentMeasurements, 
rowCountAndMemorySize.getLeft());
             if (allocatedMemoryBlockForTablet.getMemoryUsageInBytes()
                 < rowCountAndMemorySize.getRight()) {
-              PipeDataNodeResourceManager.memory()
-                  .forceResize(allocatedMemoryBlockForTablet, 
rowCountAndMemorySize.getRight());
+              
allocatedMemoryBlockForTablet.forceResize(rowCountAndMemorySize.getRight());
             }
             isFirstRow = false;
           }
@@ -422,8 +475,7 @@ public class TsFileInsertionScanDataContainer extends 
TsFileInsertionDataContain
 
   private void resizePageDataMemoryIfNeeded(final long 
estimatedMemoryUsageInBytes) {
     if (allocatedMemoryBlockForBatchData.getMemoryUsageInBytes() < 
estimatedMemoryUsageInBytes) {
-      PipeDataNodeResourceManager.memory()
-          .forceResize(allocatedMemoryBlockForBatchData, 
estimatedMemoryUsageInBytes);
+      
allocatedMemoryBlockForBatchData.forceResize(estimatedMemoryUsageInBytes);
     }
   }
 
@@ -569,8 +621,7 @@ public class TsFileInsertionScanDataContainer extends 
TsFileInsertionDataContain
             }
 
             if (chunkHeader.getDataSize() > 
allocatedMemoryBlockForChunk.getMemoryUsageInBytes()) {
-              PipeDataNodeResourceManager.memory()
-                  .forceResize(allocatedMemoryBlockForChunk, 
chunkHeader.getDataSize());
+              
allocatedMemoryBlockForChunk.forceResize(chunkHeader.getDataSize());
             }
 
             final Chunk chunk =
@@ -927,7 +978,7 @@ public class TsFileInsertionScanDataContainer extends 
TsFileInsertionDataContain
 
     final long chunkSize = pendingAlignedChunkGroup.chunkSize + 
valueChunk.valueChunkSize;
     if (chunkSize > allocatedMemoryBlockForChunk.getMemoryUsageInBytes()) {
-      
PipeDataNodeResourceManager.memory().forceResize(allocatedMemoryBlockForChunk, 
chunkSize);
+      allocatedMemoryBlockForChunk.forceResize(chunkSize);
     }
   }
 
@@ -943,8 +994,7 @@ public class TsFileInsertionScanDataContainer extends 
TsFileInsertionDataContain
         calculateMaxAlignedPageMemorySizeWithBatchData(
             pendingAlignedChunkGroup.timeChunkIndex, pendingAlignedChunkGroup, 
valueChunk);
     if (pageMemorySize > getPageDataMemoryLimitInBytes()) {
-      PipeDataNodeResourceManager.memory()
-          .forceResize(allocatedMemoryBlockForBatchData, pageMemorySize);
+      allocatedMemoryBlockForBatchData.forceResize(pageMemorySize);
     }
   }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/TsFileInsertionEventParserMemoryBlock.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/TsFileInsertionEventParserMemoryBlock.java
new file mode 100644
index 00000000000..84a458028e0
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/TsFileInsertionEventParserMemoryBlock.java
@@ -0,0 +1,37 @@
+/*
+ * 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.pipe.event.common.tsfile.parser;
+
+/**
+ * Memory block used by a tsfile parser.
+ *
+ * <p>The parser is shared by Pipe and Load. Keeping the block behind this 
small interface allows
+ * the same parsing code to use the owning subsystem's memory pool instead of 
hard-coding the Pipe
+ * pool.
+ */
+public interface TsFileInsertionEventParserMemoryBlock extends AutoCloseable {
+
+  long getMemoryUsageInBytes();
+
+  void forceResize(long newSizeInBytes);
+
+  @Override
+  void close();
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/TsFileInsertionEventParserMemoryManager.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/TsFileInsertionEventParserMemoryManager.java
new file mode 100644
index 00000000000..68669ce4b55
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/pipe/event/common/tsfile/parser/TsFileInsertionEventParserMemoryManager.java
@@ -0,0 +1,75 @@
+/*
+ * 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.pipe.event.common.tsfile.parser;
+
+import org.apache.iotdb.db.pipe.resource.PipeDataNodeResourceManager;
+import org.apache.iotdb.db.pipe.resource.memory.PipeMemoryBlock;
+
+/** Allocates parser working memory from the pool owned by the caller. */
+public interface TsFileInsertionEventParserMemoryManager {
+
+  TsFileInsertionEventParserMemoryBlock forceAllocateForTabletWithRetry(long 
sizeInBytes);
+
+  TsFileInsertionEventParserMemoryBlock forceAllocate(long sizeInBytes);
+
+  static TsFileInsertionEventParserMemoryManager pipe() {
+    return PipeHolder.INSTANCE;
+  }
+
+  final class PipeHolder {
+    private static final TsFileInsertionEventParserMemoryManager INSTANCE =
+        new TsFileInsertionEventParserMemoryManager() {
+          @Override
+          public TsFileInsertionEventParserMemoryBlock 
forceAllocateForTabletWithRetry(
+              final long sizeInBytes) {
+            return new PipeBlock(
+                
PipeDataNodeResourceManager.memory().forceAllocateForTabletWithRetry(sizeInBytes));
+          }
+
+          @Override
+          public TsFileInsertionEventParserMemoryBlock forceAllocate(final 
long sizeInBytes) {
+            return new 
PipeBlock(PipeDataNodeResourceManager.memory().forceAllocate(sizeInBytes));
+          }
+        };
+  }
+
+  final class PipeBlock implements TsFileInsertionEventParserMemoryBlock {
+    private final PipeMemoryBlock delegate;
+
+    private PipeBlock(final PipeMemoryBlock delegate) {
+      this.delegate = delegate;
+    }
+
+    @Override
+    public long getMemoryUsageInBytes() {
+      return delegate.getMemoryUsageInBytes();
+    }
+
+    @Override
+    public void forceResize(final long newSizeInBytes) {
+      PipeDataNodeResourceManager.memory().forceResize(delegate, 
newSizeInBytes);
+    }
+
+    @Override
+    public void close() {
+      delegate.close();
+    }
+  }
+}
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/converter/LoadTreeTsFileTabletIterator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/converter/LoadTreeTsFileTabletIterator.java
index 70ea903baf5..e65ba74244b 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/converter/LoadTreeTsFileTabletIterator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/converter/LoadTreeTsFileTabletIterator.java
@@ -22,9 +22,11 @@ package org.apache.iotdb.db.storageengine.load.converter;
 import 
org.apache.iotdb.commons.exception.pipe.PipeRuntimeOutOfMemoryCriticalException;
 import org.apache.iotdb.commons.pipe.datastructure.pattern.IoTDBPipePattern;
 import org.apache.iotdb.commons.pipe.datastructure.pattern.PipePattern;
+import org.apache.iotdb.db.exception.load.LoadRuntimeOutOfMemoryException;
 import 
org.apache.iotdb.db.pipe.event.common.tablet.PipeRawTabletInsertionEvent;
 import 
org.apache.iotdb.db.pipe.event.common.tsfile.container.query.TsFileInsertionQueryDataContainer;
 import 
org.apache.iotdb.db.pipe.event.common.tsfile.container.scan.TsFileInsertionScanDataContainer;
+import 
org.apache.iotdb.db.storageengine.load.memory.LoadTsFileParserMemoryManager;
 import org.apache.iotdb.pipe.api.event.dml.insertion.TabletInsertionEvent;
 
 import org.apache.tsfile.file.metadata.IDeviceID;
@@ -153,10 +155,20 @@ class LoadTreeTsFileTabletIterator
       try {
         scanParser =
             new TsFileInsertionScanDataContainer(
-                file, LOAD_TREE_PATTERN, Long.MIN_VALUE, Long.MAX_VALUE, null, 
null, isWithMod);
+                file,
+                LOAD_TREE_PATTERN,
+                Long.MIN_VALUE,
+                Long.MAX_VALUE,
+                null,
+                null,
+                isWithMod,
+                LoadTsFileParserMemoryManager.getInstance());
         activeIterator = scanParser.toTabletWithIsAligneds().iterator();
         return;
       } catch (final Exception e) {
+        if (shouldRethrow(e)) {
+          throw toRuntimeException(e);
+        }
         if (!switchFromScanToQuery(e)) {
           throw toRuntimeException(e);
         }
@@ -323,7 +335,8 @@ class LoadTreeTsFileTabletIterator
                 activeQueryTask.startTime,
                 activeQueryTask.endTime,
                 activeQueryTask.toDeviceMeasurementsMap(),
-                isWithMod);
+                isWithMod,
+                LoadTsFileParserMemoryManager.getInstance());
         final Iterator<TabletInsertionEvent> tabletIterator =
             activeQueryParser.toTabletInsertionEvents().iterator();
         activeIterator =
@@ -349,6 +362,9 @@ class LoadTreeTsFileTabletIterator
             };
         return true;
       } catch (final Exception e) {
+        if (shouldRethrow(e)) {
+          throw toRuntimeException(e);
+        }
         LOGGER.warn(
             "Load: Failed to initialize query fallback for device {} 
measurements {} in TsFile {}. "
                 + "Split or skip this query task and continue.",
@@ -386,7 +402,8 @@ class LoadTreeTsFileTabletIterator
     Throwable current = e;
     while (Objects.nonNull(current)) {
       if (current instanceof InterruptedException
-          || current instanceof PipeRuntimeOutOfMemoryCriticalException) {
+          || current instanceof PipeRuntimeOutOfMemoryCriticalException
+          || current instanceof LoadRuntimeOutOfMemoryException) {
         return true;
       }
       current = current.getCause();
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryBlock.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryBlock.java
index 623234859b9..2ba1fd7554e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryBlock.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryBlock.java
@@ -33,7 +33,7 @@ import java.util.concurrent.atomic.AtomicLong;
 public class LoadTsFileMemoryBlock extends LoadTsFileAbstractMemoryBlock {
   private static final Logger LOGGER = 
LoggerFactory.getLogger(LoadTsFileMemoryBlock.class);
 
-  private final long totalMemorySizeInBytes;
+  private long totalMemorySizeInBytes;
   private final AtomicLong memoryUsageInBytes;
 
   LoadTsFileMemoryBlock(long totalMemorySizeInBytes) {
@@ -79,13 +79,31 @@ public class LoadTsFileMemoryBlock extends 
LoadTsFileAbstractMemoryBlock {
         .decr(memoryInBytes);
   }
 
+  synchronized long getMemoryUsageInBytes() {
+    return memoryUsageInBytes.get();
+  }
+
+  synchronized long getTotalMemorySizeInBytes() {
+    return totalMemorySizeInBytes;
+  }
+
+  synchronized void setTotalMemorySizeInBytes(final long 
totalMemorySizeInBytes) {
+    this.totalMemorySizeInBytes = totalMemorySizeInBytes;
+  }
+
+  public synchronized void forceResize(final long newSizeInBytes) {
+    MEMORY_MANAGER.forceResize(this, newSizeInBytes);
+  }
+
   @Override
   protected synchronized void releaseAllMemory() {
     if (memoryUsageInBytes.get() != 0) {
       LOGGER.warn(
           "Try to release memory from a memory block {} which has not released 
all memory", this);
     }
-    MEMORY_MANAGER.releaseToQuery(totalMemorySizeInBytes);
+    if (totalMemorySizeInBytes > 0) {
+      MEMORY_MANAGER.releaseToQuery(totalMemorySizeInBytes);
+    }
   }
 
   @Override
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryManager.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryManager.java
index c3f88815300..c62d6b5f26a 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryManager.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryManager.java
@@ -121,6 +121,50 @@ public class LoadTsFileMemoryManager {
     return new LoadTsFileMemoryBlock(sizeInBytes);
   }
 
+  /**
+   * Resize an allocated Load TsFile memory block while keeping the query 
memory accounting in sync.
+   *
+   * @throws LoadRuntimeOutOfMemoryException if the additional memory cannot 
be allocated
+   */
+  synchronized void forceResize(final LoadTsFileMemoryBlock memoryBlock, final 
long newSizeInBytes)
+      throws LoadRuntimeOutOfMemoryException {
+    if (newSizeInBytes < 0) {
+      throw new IllegalArgumentException(
+          String.format(
+              "Load: Invalid memory size %d bytes, must be non-negative", 
newSizeInBytes));
+    }
+
+    final long oldSizeInBytes = memoryBlock.getTotalMemorySizeInBytes();
+    if (oldSizeInBytes == newSizeInBytes) {
+      return;
+    }
+
+    if (oldSizeInBytes > newSizeInBytes) {
+      if (memoryBlock.getMemoryUsageInBytes() > newSizeInBytes) {
+        LOGGER.error(
+            "Load: Memory block {} uses more memory than its resized limit {} 
bytes",
+            memoryBlock,
+            newSizeInBytes);
+      }
+      releaseToQuery(oldSizeInBytes - newSizeInBytes);
+      memoryBlock.setTotalMemorySizeInBytes(newSizeInBytes);
+      return;
+    }
+
+    final long bytesNeeded = newSizeInBytes - oldSizeInBytes;
+    try {
+      forceAllocateFromQuery(bytesNeeded);
+    } catch (LoadRuntimeOutOfMemoryException e) {
+      if (dataCacheMemoryBlock == null || 
!dataCacheMemoryBlock.doShrink(bytesNeeded)) {
+        throw e;
+      }
+      LOGGER.info(
+          "Load: Query engine memory is insufficient; resized memory block 
after shrinking data cache by {} bytes",
+          bytesNeeded);
+    }
+    memoryBlock.setTotalMemorySizeInBytes(newSizeInBytes);
+  }
+
   public synchronized LoadTsFileDataCacheMemoryBlock 
allocateDataCacheMemoryBlock()
       throws LoadRuntimeOutOfMemoryException {
     if (dataCacheMemoryBlock == null) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileParserMemoryManager.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileParserMemoryManager.java
new file mode 100644
index 00000000000..78b24dd3439
--- /dev/null
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileParserMemoryManager.java
@@ -0,0 +1,116 @@
+/*
+ * 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.storageengine.load.memory;
+
+import 
org.apache.iotdb.db.pipe.event.common.tsfile.parser.TsFileInsertionEventParserMemoryBlock;
+import 
org.apache.iotdb.db.pipe.event.common.tsfile.parser.TsFileInsertionEventParserMemoryManager;
+
+/**
+ * Allocates the working memory of TsFile parsers reused by Load from the 
query engine memory pool.
+ */
+public class LoadTsFileParserMemoryManager implements 
TsFileInsertionEventParserMemoryManager {
+
+  private static final LoadTsFileMemoryManager LOAD_MEMORY_MANAGER =
+      LoadTsFileMemoryManager.getInstance();
+
+  private LoadTsFileParserMemoryManager() {}
+
+  public static LoadTsFileParserMemoryManager getInstance() {
+    return LoadTsFileParserMemoryManagerHolder.INSTANCE;
+  }
+
+  @Override
+  public TsFileInsertionEventParserMemoryBlock forceAllocateForTabletWithRetry(
+      final long sizeInBytes) {
+    return new LoadParserMemoryBlock(sizeInBytes);
+  }
+
+  @Override
+  public TsFileInsertionEventParserMemoryBlock forceAllocate(final long 
sizeInBytes) {
+    return new LoadParserMemoryBlock(sizeInBytes);
+  }
+
+  private static class LoadParserMemoryBlock implements 
TsFileInsertionEventParserMemoryBlock {
+
+    private LoadTsFileMemoryBlock delegate;
+    private long memoryUsageInBytes;
+    private boolean isClosed;
+
+    private LoadParserMemoryBlock(final long sizeInBytes) {
+      checkNonNegative(sizeInBytes);
+      if (sizeInBytes > 0) {
+        delegate = LOAD_MEMORY_MANAGER.allocateMemoryBlock(sizeInBytes);
+      }
+      memoryUsageInBytes = sizeInBytes;
+    }
+
+    @Override
+    public synchronized long getMemoryUsageInBytes() {
+      return memoryUsageInBytes;
+    }
+
+    @Override
+    public synchronized void forceResize(final long newSizeInBytes) {
+      checkNonNegative(newSizeInBytes);
+      if (isClosed || memoryUsageInBytes == newSizeInBytes) {
+        return;
+      }
+
+      resizeDelegate(newSizeInBytes);
+      memoryUsageInBytes = newSizeInBytes;
+    }
+
+    private void resizeDelegate(final long newSizeInBytes) {
+      if (newSizeInBytes == 0) {
+        delegate.close();
+        delegate = null;
+      } else if (delegate == null) {
+        delegate = LOAD_MEMORY_MANAGER.allocateMemoryBlock(newSizeInBytes);
+      } else {
+        delegate.forceResize(newSizeInBytes);
+      }
+    }
+
+    @Override
+    public synchronized void close() {
+      if (isClosed) {
+        return;
+      }
+      isClosed = true;
+      memoryUsageInBytes = 0;
+      if (delegate != null) {
+        delegate.close();
+        delegate = null;
+      }
+    }
+
+    private static void checkNonNegative(final long sizeInBytes) {
+      if (sizeInBytes < 0) {
+        throw new IllegalArgumentException(
+            String.format("Load: Invalid memory size %d bytes, must be 
non-negative", sizeInBytes));
+      }
+    }
+  }
+
+  private static class LoadTsFileParserMemoryManagerHolder {
+    private static final LoadTsFileParserMemoryManager INSTANCE =
+        new LoadTsFileParserMemoryManager();
+  }
+}
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/event/TsFileInsertionDataContainerTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/event/TsFileInsertionDataContainerTest.java
index 2a2812dd395..dae32e56979 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/event/TsFileInsertionDataContainerTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/pipe/event/TsFileInsertionDataContainerTest.java
@@ -32,7 +32,7 @@ import 
org.apache.iotdb.db.pipe.event.common.tsfile.container.query.TsFileInsert
 import 
org.apache.iotdb.db.pipe.event.common.tsfile.container.scan.AlignedSinglePageWholeChunkReader;
 import 
org.apache.iotdb.db.pipe.event.common.tsfile.container.scan.SinglePageWholeChunkReader;
 import 
org.apache.iotdb.db.pipe.event.common.tsfile.container.scan.TsFileInsertionScanDataContainer;
-import org.apache.iotdb.db.pipe.resource.memory.PipeMemoryBlock;
+import 
org.apache.iotdb.db.pipe.event.common.tsfile.parser.TsFileInsertionEventParserMemoryBlock;
 import org.apache.iotdb.db.pipe.resource.memory.PipeMemoryWeightUtil;
 import 
org.apache.iotdb.db.storageengine.dataregion.compaction.io.CompactionTsFileWriter;
 import 
org.apache.iotdb.db.storageengine.dataregion.compaction.schedule.constant.CompactionType;
@@ -174,11 +174,22 @@ public class TsFileInsertionDataContainerTest {
             false)) {
       replaceAllocatedTabletMemory(
           container,
-          new PipeMemoryBlock(0) {
+          new TsFileInsertionEventParserMemoryBlock() {
+            private long memoryUsageInBytes;
+
+            @Override
+            public long getMemoryUsageInBytes() {
+              return memoryUsageInBytes;
+            }
+
+            @Override
+            public void forceResize(final long newSizeInBytes) {
+              memoryUsageInBytes = newSizeInBytes;
+            }
+
             @Override
             public void close() {
-              Assert.assertEquals(0, getMemoryUsageInBytes());
-              super.close();
+              Assert.assertEquals(0, memoryUsageInBytes);
             }
           });
 
@@ -212,13 +223,25 @@ public class TsFileInsertionDataContainerTest {
       final AtomicInteger memoryUsageReadCount = new AtomicInteger(0);
       replaceAllocatedTabletMemory(
           container,
-          new PipeMemoryBlock(0) {
+          new TsFileInsertionEventParserMemoryBlock() {
+            private long memoryUsageInBytes;
+
             @Override
             public long getMemoryUsageInBytes() {
               if (memoryUsageReadCount.incrementAndGet() == 2) {
                 throw new PipeRuntimeOutOfMemoryCriticalException("expected 
oom");
               }
-              return super.getMemoryUsageInBytes();
+              return memoryUsageInBytes;
+            }
+
+            @Override
+            public void forceResize(final long newSizeInBytes) {
+              memoryUsageInBytes = newSizeInBytes;
+            }
+
+            @Override
+            public void close() {
+              memoryUsageInBytes = 0;
             }
           });
 
@@ -1336,37 +1359,41 @@ public class TsFileInsertionDataContainerTest {
     return count;
   }
 
-  private PipeMemoryBlock getAllocatedChunkMemory(final 
TsFileInsertionScanDataContainer parser)
+  private TsFileInsertionEventParserMemoryBlock getAllocatedChunkMemory(
+      final TsFileInsertionScanDataContainer parser)
       throws NoSuchFieldException, IllegalAccessException {
     final Field field =
         
TsFileInsertionScanDataContainer.class.getDeclaredField("allocatedMemoryBlockForChunk");
     field.setAccessible(true);
-    return (PipeMemoryBlock) field.get(parser);
+    return (TsFileInsertionEventParserMemoryBlock) field.get(parser);
   }
 
-  private PipeMemoryBlock getAllocatedBatchDataMemory(final 
TsFileInsertionScanDataContainer parser)
+  private TsFileInsertionEventParserMemoryBlock getAllocatedBatchDataMemory(
+      final TsFileInsertionScanDataContainer parser)
       throws NoSuchFieldException, IllegalAccessException {
     final Field field =
         
TsFileInsertionScanDataContainer.class.getDeclaredField("allocatedMemoryBlockForBatchData");
     field.setAccessible(true);
-    return (PipeMemoryBlock) field.get(parser);
+    return (TsFileInsertionEventParserMemoryBlock) field.get(parser);
   }
 
-  private PipeMemoryBlock getAllocatedTabletMemory(final 
TsFileInsertionDataContainer container)
+  private TsFileInsertionEventParserMemoryBlock getAllocatedTabletMemory(
+      final TsFileInsertionDataContainer container)
       throws NoSuchFieldException, IllegalAccessException {
     final Field field =
         
TsFileInsertionDataContainer.class.getDeclaredField("allocatedMemoryBlockForTablet");
     field.setAccessible(true);
-    return (PipeMemoryBlock) field.get(container);
+    return (TsFileInsertionEventParserMemoryBlock) field.get(container);
   }
 
   private void replaceAllocatedTabletMemory(
-      final TsFileInsertionDataContainer container, final PipeMemoryBlock 
replacement)
+      final TsFileInsertionDataContainer container,
+      final TsFileInsertionEventParserMemoryBlock replacement)
       throws NoSuchFieldException, IllegalAccessException {
     final Field field =
         
TsFileInsertionDataContainer.class.getDeclaredField("allocatedMemoryBlockForTablet");
     field.setAccessible(true);
-    ((PipeMemoryBlock) field.get(container)).close();
+    ((TsFileInsertionEventParserMemoryBlock) field.get(container)).close();
     field.set(container, replacement);
   }
 
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/load/converter/LoadTsFileParserPipeMemoryIsolationTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/load/converter/LoadTsFileParserPipeMemoryIsolationTest.java
new file mode 100644
index 00000000000..2b403b079c3
--- /dev/null
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/load/converter/LoadTsFileParserPipeMemoryIsolationTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.storageengine.load.converter;
+
+import org.apache.iotdb.db.pipe.resource.PipeDataNodeResourceManager;
+import org.apache.iotdb.db.storageengine.load.memory.LoadTsFileMemoryManager;
+
+import org.apache.tsfile.utils.TsFileGeneratorUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.io.File;
+
+@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", 
"javax.management.*"})
+@RunWith(PowerMockRunner.class)
+@PrepareForTest(PipeDataNodeResourceManager.class)
+public class LoadTsFileParserPipeMemoryIsolationTest {
+
+  @Test
+  public void testLoadParserDoesNotAccessPipeMemoryPool() throws Exception {
+    final File tsFile = new File("load-parser-pipe-memory-isolation.tsfile");
+    try {
+      TsFileGeneratorUtils.generateNonAlignedTsFile(tsFile.getPath(), 1, 1, 
10, 0, 100, 10, 10);
+
+      PowerMockito.mockStatic(PipeDataNodeResourceManager.class);
+      PowerMockito.when(PipeDataNodeResourceManager.memory())
+          .thenThrow(new AssertionError("Load parser must not access Pipe 
memory"));
+
+      final LoadTsFileMemoryManager loadMemoryManager = 
LoadTsFileMemoryManager.getInstance();
+      final long loadMemoryBefore = 
loadMemoryManager.getUsedMemorySizeInBytes();
+      try (final LoadTreeTsFileTabletIterator tabletIterator =
+          new LoadTreeTsFileTabletIterator(tsFile, true)) {
+        Assert.assertTrue(tabletIterator.hasNext());
+        Assert.assertTrue(loadMemoryManager.getUsedMemorySizeInBytes() > 
loadMemoryBefore);
+        Assert.assertNotNull(tabletIterator.next());
+      }
+      Assert.assertEquals(loadMemoryBefore, 
loadMemoryManager.getUsedMemorySizeInBytes());
+    } finally {
+      if (tsFile.exists()) {
+        Assert.assertTrue(tsFile.delete());
+      }
+    }
+  }
+}
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryManagerTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryManagerTest.java
index f3a1bf7e411..f0ffe1d5f99 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryManagerTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/load/memory/LoadTsFileMemoryManagerTest.java
@@ -20,6 +20,7 @@
 package org.apache.iotdb.db.storageengine.load.memory;
 
 import org.apache.iotdb.db.exception.load.LoadRuntimeOutOfMemoryException;
+import 
org.apache.iotdb.db.pipe.event.common.tsfile.parser.TsFileInsertionEventParserMemoryBlock;
 
 import org.junit.Assert;
 import org.junit.Test;
@@ -83,6 +84,25 @@ public class LoadTsFileMemoryManagerTest {
     }
   }
 
+  @Test
+  public void testParserMemoryBlockGrowsAndReleasesFromQueryPool() throws 
Exception {
+    final LoadTsFileMemoryManager manager = 
LoadTsFileMemoryManager.getInstance();
+    final long usedMemoryBefore = manager.getUsedMemorySizeInBytes();
+    final TsFileInsertionEventParserMemoryBlock block =
+        LoadTsFileParserMemoryManager.getInstance().forceAllocate(0);
+
+    Assert.assertEquals(0L, block.getMemoryUsageInBytes());
+    block.forceResize(1024);
+    Assert.assertEquals(usedMemoryBefore + 1024, 
manager.getUsedMemorySizeInBytes());
+    block.forceResize(0);
+    Assert.assertEquals(usedMemoryBefore, manager.getUsedMemorySizeInBytes());
+    block.forceResize(0);
+    Assert.assertEquals(0L, block.getMemoryUsageInBytes());
+    Assert.assertEquals(usedMemoryBefore, manager.getUsedMemorySizeInBytes());
+    block.close();
+    Assert.assertEquals(usedMemoryBefore, manager.getUsedMemorySizeInBytes());
+  }
+
   private static LoadTsFileMemoryManager newMemoryManager() throws Exception {
     final Constructor<LoadTsFileMemoryManager> constructor =
         LoadTsFileMemoryManager.class.getDeclaredConstructor();

Reply via email to