Skip to content

Commit 06621d0

Browse files
authored
mon: add diagnose information for MemoryNotEnoughException (#17578)
1 parent b7eb193 commit 06621d0

9 files changed

Lines changed: 64 additions & 16 deletions

File tree

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,7 @@ public void releaseResourceWhenAllDriversAreClosed() {
934934
*/
935935
private void releaseTVListOwnedByQuery() {
936936
for (TVList tvList : tvListSet) {
937-
long tvListRamSize = tvList.calculateRamSize();
937+
long tvListRamSize = tvList.calculateRamSize().getRamSize();
938938
tvList.lockQueryList();
939939
Set<QueryContext> queryContextSet = tvList.getQueryContextSet();
940940
try {

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/utils/ResourceByPathUtils.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
package org.apache.iotdb.db.schemaengine.schemaregion.utils;
2121

22+
import org.apache.iotdb.calc.exception.MemoryNotEnoughException;
2223
import org.apache.iotdb.calc.exception.QueryProcessException;
2324
import org.apache.iotdb.calc.plan.planner.memory.MemoryReservationManager;
2425
import org.apache.iotdb.commons.path.AlignedFullPath;
@@ -155,7 +156,7 @@ protected Map<TVList, Integer> prepareTvListMapForQuery(
155156
// mutable tvlist
156157
TVList list = memChunk.getWorkingTVList();
157158
TVList cloneList = null;
158-
long tvListRamSize = list.calculateRamSize();
159+
TVList.RamInfo listRamInfo = list.calculateRamSize();
159160
list.lockQueryList();
160161
try {
161162
if (copyTimeFilter != null
@@ -196,8 +197,8 @@ protected Map<TVList, Integer> prepareTvListMapForQuery(
196197
if (firstQuery instanceof FragmentInstanceContext) {
197198
MemoryReservationManager memoryReservationManager =
198199
((FragmentInstanceContext) firstQuery).getMemoryReservationContext();
199-
memoryReservationManager.reserveMemoryCumulatively(tvListRamSize);
200-
list.setReservedMemoryBytes(tvListRamSize);
200+
memoryReservationManager.reserveMemoryCumulatively(listRamInfo.getRamSize());
201+
list.setReservedMemoryBytes(listRamInfo.getRamSize());
201202
}
202203
list.setOwnerQuery(firstQuery);
203204

@@ -207,6 +208,14 @@ protected Map<TVList, Integer> prepareTvListMapForQuery(
207208
tvListQueryMap.put(cloneList, cloneList.rowCount());
208209
}
209210
}
211+
} catch (MemoryNotEnoughException ex) {
212+
LOGGER.warn(
213+
"Failed to reserve memory for TVList: ramSize {}, timestampsSize {}, arrayMemCost {}, rowCount {}, dataTypes {}",
214+
listRamInfo.getRamSize(),
215+
listRamInfo.getTimestampsSize(),
216+
listRamInfo.getArrayMemCost(),
217+
listRamInfo.getRowCount(),
218+
listRamInfo.getDataTypes());
210219
} finally {
211220
list.unlockQueryList();
212221
}

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AbstractWritableMemChunk.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ protected void maybeReleaseTvList(TVList tvList) {
103103
}
104104

105105
private void tryReleaseTvList(TVList tvList) {
106-
long tvListRamSize = tvList.calculateRamSize();
106+
long tvListRamSize = tvList.calculateRamSize().getRamSize();
107107
tvList.lockQueryList();
108108
try {
109109
if (tvList.getQueryContextSet().isEmpty()) {

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/AlignedReadOnlyMemChunk.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ public void sortTvLists() {
127127
// We must update queryRowCount here, otherwise, it may be used later to build
128128
// BitMaps, causing bitmap array size mismatch and possible out of bound.
129129
entry.setValue(alignedTvList.sort());
130-
long alignedTvListRamSize = alignedTvList.calculateRamSize();
130+
long alignedTvListRamSize = alignedTvList.calculateRamSize().getRamSize();
131131
alignedTvList.lockQueryList();
132132
try {
133133
FragmentInstanceContext ownerQuery =
@@ -384,7 +384,7 @@ public IPointReader getPointReader() {
384384
int queryLength = entry.getValue();
385385
if (!alignedTvList.isSorted() && queryLength > alignedTvList.seqRowCount()) {
386386
entry.setValue(alignedTvList.sort());
387-
long alignedTvListRamSize = alignedTvList.calculateRamSize();
387+
long alignedTvListRamSize = alignedTvList.calculateRamSize().getRamSize();
388388
alignedTvList.lockQueryList();
389389
try {
390390
FragmentInstanceContext ownerQuery =

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/storageengine/dataregion/memtable/ReadOnlyMemChunk.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public void sortTvLists() {
137137
int queryRowCount = entry.getValue();
138138
if (!tvList.isSorted() && queryRowCount > tvList.seqRowCount()) {
139139
entry.setValue(tvList.sort());
140-
long tvListRamSize = tvList.calculateRamSize();
140+
long tvListRamSize = tvList.calculateRamSize().getRamSize();
141141
tvList.lockQueryList();
142142
try {
143143
FragmentInstanceContext ownerQuery = (FragmentInstanceContext) tvList.getOwnerQuery();
@@ -294,7 +294,7 @@ public IPointReader getPointReader() {
294294
int queryLength = entry.getValue();
295295
if (!tvList.isSorted() && queryLength > tvList.seqRowCount()) {
296296
entry.setValue(tvList.sort());
297-
long tvListRamSize = tvList.calculateRamSize();
297+
long tvListRamSize = tvList.calculateRamSize().getRamSize();
298298
tvList.lockQueryList();
299299
try {
300300
FragmentInstanceContext ownerQuery = (FragmentInstanceContext) tvList.getOwnerQuery();

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/AlignedTVList.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,8 +1064,9 @@ public TSDataType getDataType() {
10641064
}
10651065

10661066
@Override
1067-
public synchronized long calculateRamSize() {
1068-
return timestamps.size() * alignedTvListArrayMemCost();
1067+
public synchronized RamInfo calculateRamSize() {
1068+
return new RamInfo(
1069+
timestamps.size(), alignedTvListArrayMemCost(), rowCount, new ArrayList<>(dataTypes));
10691070
}
10701071

10711072
/**

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/datastructure/TVList.java

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.apache.iotdb.db.storageengine.rescon.memory.PrimitiveArrayManager;
2929
import org.apache.iotdb.db.utils.MathUtils;
3030

31+
import com.google.common.collect.ImmutableList;
3132
import org.apache.tsfile.enums.TSDataType;
3233
import org.apache.tsfile.file.metadata.enums.TSEncoding;
3334
import org.apache.tsfile.read.TimeValuePair;
@@ -61,6 +62,42 @@
6162

6263
public abstract class TVList implements WALEntryValue {
6364
protected static final String ERR_DATATYPE_NOT_CONSISTENT = "DataType not consistent";
65+
66+
public static class RamInfo {
67+
private final int timestampsSize;
68+
private final long arrayMemCost;
69+
private final int rowCount;
70+
private final List<TSDataType> dataTypes;
71+
72+
public RamInfo(
73+
int timestampCount, long arrayMemCost, int rowCount, List<TSDataType> dataTypes) {
74+
this.timestampsSize = timestampCount;
75+
this.rowCount = rowCount;
76+
this.arrayMemCost = arrayMemCost;
77+
this.dataTypes = dataTypes;
78+
}
79+
80+
public long getRamSize() {
81+
return timestampsSize * arrayMemCost;
82+
}
83+
84+
public int getTimestampsSize() {
85+
return timestampsSize;
86+
}
87+
88+
public int getRowCount() {
89+
return rowCount;
90+
}
91+
92+
public long getArrayMemCost() {
93+
return arrayMemCost;
94+
}
95+
96+
public List<TSDataType> getDataTypes() {
97+
return dataTypes;
98+
}
99+
}
100+
64101
// list of timestamp array, add 1 when expanded -> data point timestamp array
65102
// index relation: arrayIndex -> elementIndex
66103
protected List<long[]> timestamps;
@@ -165,8 +202,9 @@ public static long tvListArrayMemCost(TSDataType type) {
165202
return size;
166203
}
167204

168-
public synchronized long calculateRamSize() {
169-
return timestamps.size() * tvListArrayMemCost();
205+
public synchronized RamInfo calculateRamSize() {
206+
return new RamInfo(
207+
timestamps.size(), tvListArrayMemCost(), rowCount, ImmutableList.of(getDataType()));
170208
}
171209

172210
public synchronized boolean isSorted() {

iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/execution/fragment/FragmentInstanceExecutionTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ public void testTVListOwnerTransfer() throws InterruptedException {
146146
// mock flush's behavior
147147
fragmentInstanceContext1
148148
.getMemoryReservationContext()
149-
.reserveMemoryCumulatively(tvList.calculateRamSize());
149+
.reserveMemoryCumulatively(tvList.calculateRamSize().getRamSize());
150150
tvList.setOwnerQuery(fragmentInstanceContext1);
151151

152152
fragmentInstanceContext1.decrementNumOfUnClosedDriver();
@@ -226,7 +226,7 @@ public void testTVListCloneForQuery() {
226226
pointReader.nextTimeValuePair();
227227
}
228228
assertTrue(tvList.isSorted());
229-
assertEquals(tvList.calculateRamSize(), tvList.getReservedMemoryBytes());
229+
assertEquals(tvList.calculateRamSize().getRamSize(), tvList.getReservedMemoryBytes());
230230
} catch (QueryProcessException
231231
| IOException
232232
| MetadataException

iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/memtable/PrimitiveMemTableTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -748,7 +748,7 @@ public void testReleaseWithNotEnoughMemory() throws CpuNotEnoughException {
748748
Mockito.mock(MemoryReservationManager.class);
749749
Mockito.doThrow(new MemoryNotEnoughException(""))
750750
.when(memoryReservationManager)
751-
.reserveMemoryCumulatively(list.calculateRamSize());
751+
.reserveMemoryCumulatively(list.calculateRamSize().getRamSize());
752752

753753
// create FragmentInstanceId
754754
QueryId queryId = new QueryId("stub_query");

0 commit comments

Comments
 (0)