This is an automated email from the ASF dual-hosted git repository.
JackieTien97 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/master by this push:
new 06621d0f045 mon: add diagnose information for MemoryNotEnoughException
(#17578)
06621d0f045 is described below
commit 06621d0f045a15a66e2f16434fd0724caef226db
Author: shizy <[email protected]>
AuthorDate: Thu Apr 30 08:52:34 2026 +0800
mon: add diagnose information for MemoryNotEnoughException (#17578)
---
.../fragment/FragmentInstanceContext.java | 2 +-
.../schemaregion/utils/ResourceByPathUtils.java | 15 ++++++--
.../memtable/AbstractWritableMemChunk.java | 2 +-
.../memtable/AlignedReadOnlyMemChunk.java | 4 +--
.../dataregion/memtable/ReadOnlyMemChunk.java | 4 +--
.../db/utils/datastructure/AlignedTVList.java | 5 +--
.../iotdb/db/utils/datastructure/TVList.java | 42 ++++++++++++++++++++--
.../fragment/FragmentInstanceExecutionTest.java | 4 +--
.../dataregion/memtable/PrimitiveMemTableTest.java | 2 +-
9 files changed, 64 insertions(+), 16 deletions(-)
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceContext.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceContext.java
index 5102319aeee..3adc5373a75 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceContext.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceContext.java
@@ -934,7 +934,7 @@ public class FragmentInstanceContext extends QueryContext {
*/
private void releaseTVListOwnedByQuery() {
for (TVList tvList : tvListSet) {
- long tvListRamSize = tvList.calculateRamSize();
+ long tvListRamSize = tvList.calculateRamSize().getRamSize();
tvList.lockQueryList();
Set<QueryContext> queryContextSet = tvList.getQueryContextSet();
try {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/utils/ResourceByPathUtils.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/utils/ResourceByPathUtils.java
index 1f177864dd1..e0590a1410e 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/utils/ResourceByPathUtils.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/utils/ResourceByPathUtils.java
@@ -19,6 +19,7 @@
package org.apache.iotdb.db.schemaengine.schemaregion.utils;
+import org.apache.iotdb.calc.exception.MemoryNotEnoughException;
import org.apache.iotdb.calc.exception.QueryProcessException;
import org.apache.iotdb.calc.plan.planner.memory.MemoryReservationManager;
import org.apache.iotdb.commons.path.AlignedFullPath;
@@ -155,7 +156,7 @@ public abstract class ResourceByPathUtils {
// mutable tvlist
TVList list = memChunk.getWorkingTVList();
TVList cloneList = null;
- long tvListRamSize = list.calculateRamSize();
+ TVList.RamInfo listRamInfo = list.calculateRamSize();
list.lockQueryList();
try {
if (copyTimeFilter != null
@@ -196,8 +197,8 @@ public abstract class ResourceByPathUtils {
if (firstQuery instanceof FragmentInstanceContext) {
MemoryReservationManager memoryReservationManager =
((FragmentInstanceContext)
firstQuery).getMemoryReservationContext();
- memoryReservationManager.reserveMemoryCumulatively(tvListRamSize);
- list.setReservedMemoryBytes(tvListRamSize);
+
memoryReservationManager.reserveMemoryCumulatively(listRamInfo.getRamSize());
+ list.setReservedMemoryBytes(listRamInfo.getRamSize());
}
list.setOwnerQuery(firstQuery);
@@ -207,6 +208,14 @@ public abstract class ResourceByPathUtils {
tvListQueryMap.put(cloneList, cloneList.rowCount());
}
}
+ } catch (MemoryNotEnoughException ex) {
+ LOGGER.warn(
+ "Failed to reserve memory for TVList: ramSize {}, timestampsSize {},
arrayMemCost {}, rowCount {}, dataTypes {}",
+ listRamInfo.getRamSize(),
+ listRamInfo.getTimestampsSize(),
+ listRamInfo.getArrayMemCost(),
+ listRamInfo.getRowCount(),
+ listRamInfo.getDataTypes());
} finally {
list.unlockQueryList();
}
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AbstractWritableMemChunk.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AbstractWritableMemChunk.java
index 0f78e0717c3..6ae9333b2de 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AbstractWritableMemChunk.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AbstractWritableMemChunk.java
@@ -103,7 +103,7 @@ public abstract class AbstractWritableMemChunk implements
IWritableMemChunk {
}
private void tryReleaseTvList(TVList tvList) {
- long tvListRamSize = tvList.calculateRamSize();
+ long tvListRamSize = tvList.calculateRamSize().getRamSize();
tvList.lockQueryList();
try {
if (tvList.getQueryContextSet().isEmpty()) {
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedReadOnlyMemChunk.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedReadOnlyMemChunk.java
index 517566ed78c..05c1602bf2a 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedReadOnlyMemChunk.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedReadOnlyMemChunk.java
@@ -127,7 +127,7 @@ public class AlignedReadOnlyMemChunk extends
ReadOnlyMemChunk {
// We must update queryRowCount here, otherwise, it may be used later
to build
// BitMaps, causing bitmap array size mismatch and possible out of
bound.
entry.setValue(alignedTvList.sort());
- long alignedTvListRamSize = alignedTvList.calculateRamSize();
+ long alignedTvListRamSize =
alignedTvList.calculateRamSize().getRamSize();
alignedTvList.lockQueryList();
try {
FragmentInstanceContext ownerQuery =
@@ -384,7 +384,7 @@ public class AlignedReadOnlyMemChunk extends
ReadOnlyMemChunk {
int queryLength = entry.getValue();
if (!alignedTvList.isSorted() && queryLength >
alignedTvList.seqRowCount()) {
entry.setValue(alignedTvList.sort());
- long alignedTvListRamSize = alignedTvList.calculateRamSize();
+ long alignedTvListRamSize =
alignedTvList.calculateRamSize().getRamSize();
alignedTvList.lockQueryList();
try {
FragmentInstanceContext ownerQuery =
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/ReadOnlyMemChunk.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/ReadOnlyMemChunk.java
index 811a080c22f..496035e91ad 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/ReadOnlyMemChunk.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/ReadOnlyMemChunk.java
@@ -137,7 +137,7 @@ public class ReadOnlyMemChunk {
int queryRowCount = entry.getValue();
if (!tvList.isSorted() && queryRowCount > tvList.seqRowCount()) {
entry.setValue(tvList.sort());
- long tvListRamSize = tvList.calculateRamSize();
+ long tvListRamSize = tvList.calculateRamSize().getRamSize();
tvList.lockQueryList();
try {
FragmentInstanceContext ownerQuery = (FragmentInstanceContext)
tvList.getOwnerQuery();
@@ -294,7 +294,7 @@ public class ReadOnlyMemChunk {
int queryLength = entry.getValue();
if (!tvList.isSorted() && queryLength > tvList.seqRowCount()) {
entry.setValue(tvList.sort());
- long tvListRamSize = tvList.calculateRamSize();
+ long tvListRamSize = tvList.calculateRamSize().getRamSize();
tvList.lockQueryList();
try {
FragmentInstanceContext ownerQuery = (FragmentInstanceContext)
tvList.getOwnerQuery();
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/AlignedTVList.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/AlignedTVList.java
index 6293a0fc4b9..cb1379dc19d 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/AlignedTVList.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/AlignedTVList.java
@@ -1064,8 +1064,9 @@ public abstract class AlignedTVList extends TVList {
}
@Override
- public synchronized long calculateRamSize() {
- return timestamps.size() * alignedTvListArrayMemCost();
+ public synchronized RamInfo calculateRamSize() {
+ return new RamInfo(
+ timestamps.size(), alignedTvListArrayMemCost(), rowCount, new
ArrayList<>(dataTypes));
}
/**
diff --git
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java
index 8b571fed01f..fb0cc005813 100644
---
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java
+++
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java
@@ -28,6 +28,7 @@ import
org.apache.iotdb.db.storageengine.dataregion.wal.buffer.WALEntryValue;
import org.apache.iotdb.db.storageengine.rescon.memory.PrimitiveArrayManager;
import org.apache.iotdb.db.utils.MathUtils;
+import com.google.common.collect.ImmutableList;
import org.apache.tsfile.enums.TSDataType;
import org.apache.tsfile.file.metadata.enums.TSEncoding;
import org.apache.tsfile.read.TimeValuePair;
@@ -61,6 +62,42 @@ import static
org.apache.tsfile.utils.RamUsageEstimator.NUM_BYTES_OBJECT_REF;
public abstract class TVList implements WALEntryValue {
protected static final String ERR_DATATYPE_NOT_CONSISTENT = "DataType not
consistent";
+
+ public static class RamInfo {
+ private final int timestampsSize;
+ private final long arrayMemCost;
+ private final int rowCount;
+ private final List<TSDataType> dataTypes;
+
+ public RamInfo(
+ int timestampCount, long arrayMemCost, int rowCount, List<TSDataType>
dataTypes) {
+ this.timestampsSize = timestampCount;
+ this.rowCount = rowCount;
+ this.arrayMemCost = arrayMemCost;
+ this.dataTypes = dataTypes;
+ }
+
+ public long getRamSize() {
+ return timestampsSize * arrayMemCost;
+ }
+
+ public int getTimestampsSize() {
+ return timestampsSize;
+ }
+
+ public int getRowCount() {
+ return rowCount;
+ }
+
+ public long getArrayMemCost() {
+ return arrayMemCost;
+ }
+
+ public List<TSDataType> getDataTypes() {
+ return dataTypes;
+ }
+ }
+
// list of timestamp array, add 1 when expanded -> data point timestamp array
// index relation: arrayIndex -> elementIndex
protected List<long[]> timestamps;
@@ -165,8 +202,9 @@ public abstract class TVList implements WALEntryValue {
return size;
}
- public synchronized long calculateRamSize() {
- return timestamps.size() * tvListArrayMemCost();
+ public synchronized RamInfo calculateRamSize() {
+ return new RamInfo(
+ timestamps.size(), tvListArrayMemCost(), rowCount,
ImmutableList.of(getDataType()));
}
public synchronized boolean isSorted() {
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceExecutionTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceExecutionTest.java
index 393884a519b..99a94eb02a3 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceExecutionTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceExecutionTest.java
@@ -146,7 +146,7 @@ public class FragmentInstanceExecutionTest {
// mock flush's behavior
fragmentInstanceContext1
.getMemoryReservationContext()
- .reserveMemoryCumulatively(tvList.calculateRamSize());
+ .reserveMemoryCumulatively(tvList.calculateRamSize().getRamSize());
tvList.setOwnerQuery(fragmentInstanceContext1);
fragmentInstanceContext1.decrementNumOfUnClosedDriver();
@@ -226,7 +226,7 @@ public class FragmentInstanceExecutionTest {
pointReader.nextTimeValuePair();
}
assertTrue(tvList.isSorted());
- assertEquals(tvList.calculateRamSize(), tvList.getReservedMemoryBytes());
+ assertEquals(tvList.calculateRamSize().getRamSize(),
tvList.getReservedMemoryBytes());
} catch (QueryProcessException
| IOException
| MetadataException
diff --git
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/memtable/PrimitiveMemTableTest.java
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/memtable/PrimitiveMemTableTest.java
index 70ea839382c..c47297fbeb4 100644
---
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/memtable/PrimitiveMemTableTest.java
+++
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/memtable/PrimitiveMemTableTest.java
@@ -748,7 +748,7 @@ public class PrimitiveMemTableTest {
Mockito.mock(MemoryReservationManager.class);
Mockito.doThrow(new MemoryNotEnoughException(""))
.when(memoryReservationManager)
- .reserveMemoryCumulatively(list.calculateRamSize());
+ .reserveMemoryCumulatively(list.calculateRamSize().getRamSize());
// create FragmentInstanceId
QueryId queryId = new QueryId("stub_query");