Skip to content

Commit 78a4790

Browse files
authored
Fix PBTree schema cache release after pre-delete (#17834) (#17852)
1 parent 3af79aa commit 78a4790

3 files changed

Lines changed: 29 additions & 50 deletions

File tree

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/pbtree/memory/ReleaseFlushMonitor.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ public List<Integer> getRegionsToFlush(long windowsEndTime) {
230230
public void forceFlushAndRelease() {
231231
boolean needFlush;
232232
while (true) {
233+
waitUntilWorkerTasksDone();
233234
needFlush = false;
234235
for (CachedMTreeStore store : regionToStoreMap.values()) {
235236
if (store.getMemoryManager().getBufferNodeNum() > 0) {
@@ -239,13 +240,29 @@ public void forceFlushAndRelease() {
239240
}
240241
if (needFlush) {
241242
scheduler.scheduleFlushAll().join();
243+
waitUntilWorkerTasksDone();
242244
scheduler.scheduleRelease(true);
243245
} else {
246+
// No volatile nodes left, but clean unpinned cache may still remain after previous flushes.
247+
scheduler.scheduleRelease(true);
248+
waitUntilWorkerTasksDone();
244249
break;
245250
}
246251
}
247252
}
248253

254+
@TestOnly
255+
private void waitUntilWorkerTasksDone() {
256+
while (scheduler.getActiveWorkerNum() > 0 || !flushingRegionSet.isEmpty()) {
257+
try {
258+
Thread.sleep(10);
259+
} catch (InterruptedException e) {
260+
Thread.currentThread().interrupt();
261+
return;
262+
}
263+
}
264+
}
265+
249266
public void clear() {
250267
if (releaseMonitor != null) {
251268
releaseMonitor.shutdownNow();

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/traverser/Traverser.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ private N getChild(N parent, String childName, boolean skipTemplateChildren)
185185
&& skipPreDeletedSchema
186186
&& child.isMeasurement()
187187
&& child.getAsMeasurementMNode().isPreDeleted()) {
188+
releaseNode(child);
188189
child = null;
189190
}
190191
}

iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaStatisticsTest.java

Lines changed: 11 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -75,24 +75,12 @@ public void testPBTreeMemoryStatistics() throws Exception {
7575
|| testParams.getTestModeName().equals("PBTree-NonMemory")) {
7676
final IMNodeFactory<ICachedMNode> nodeFactory =
7777
MNodeFactoryLoader.getInstance().getCachedMNodeIMNodeFactory();
78-
// wait release and flush task
79-
Thread.sleep(6000);
78+
ReleaseFlushMonitor.getInstance().forceFlushAndRelease();
8079
// schemaRegion1
8180
final IMNode<ICachedMNode> sg1 = nodeFactory.createDatabaseMNode(null, "sg1");
8281
sg1.setFullPath("root.sg1");
8382
final long size1 = sg1.estimateSize();
84-
if (size1 != schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage()) {
85-
// There are two possibilities here in PartialMemory mode:
86-
// 1. only the "sg1" node remains
87-
// 2. the "sg1" node and the "n" node remain
88-
Assert.assertEquals("PBTree-PartialMemory", testParams.getTestModeName());
89-
Assert.assertEquals(
90-
size1 + nodeFactory.createDeviceMNode(sg1.getAsMNode(), "n").estimateSize(),
91-
schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage());
92-
ReleaseFlushMonitor.getInstance().forceFlushAndRelease();
93-
Assert.assertEquals(
94-
size1, schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage());
95-
}
83+
Assert.assertEquals(size1, schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage());
9684
}
9785
Assert.assertEquals(0, schemaRegion1.getSchemaRegionStatistics().getSchemaRegionId());
9886
checkPBTreeStatistics(engineStatistics);
@@ -122,8 +110,7 @@ public void testMemoryStatistics2() throws Exception {
122110

123111
final IMNodeFactory<?> nodeFactory =
124112
MNodeFactoryLoader.getInstance().getCachedMNodeIMNodeFactory();
125-
// wait release and flush task
126-
Thread.sleep(1000);
113+
ReleaseFlushMonitor.getInstance().forceFlushAndRelease();
127114
// schemaRegion1
128115
final IMNode<?> sg1 = nodeFactory.createDatabaseMNode(null, "sg1");
129116
sg1.setFullPath("root.sg1");
@@ -231,36 +218,12 @@ public void testMemoryStatistics() throws Exception {
231218
|| testParams.getTestModeName().equals("PBTree-NonMemory")) {
232219
final IMNodeFactory<ICachedMNode> nodeFactory =
233220
MNodeFactoryLoader.getInstance().getCachedMNodeIMNodeFactory();
234-
// wait release and flush task
235-
Thread.sleep(1000);
221+
ReleaseFlushMonitor.getInstance().forceFlushAndRelease();
236222
// schemaRegion1
237223
final IMNode<ICachedMNode> sg1 = nodeFactory.createDatabaseDeviceMNode(null, "sg1");
238224
sg1.setFullPath("root.sg1");
239225
final long size1 = sg1.estimateSize();
240-
if (sg1.estimateSize() != schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage()) {
241-
// "d0" or "d1" node may remain in PartialMemory mode
242-
Assert.assertEquals("PBTree-PartialMemory", testParams.getTestModeName());
243-
final long d0ExistSize =
244-
size1
245-
+ nodeFactory
246-
.createMeasurementMNode(
247-
sg1.getAsDeviceMNode(),
248-
"d0",
249-
new MeasurementSchema(
250-
"d0", TSDataType.INT64, TSEncoding.PLAIN, CompressionType.SNAPPY),
251-
null)
252-
.estimateSize();
253-
final long d1ExistSize =
254-
size1 + nodeFactory.createInternalMNode(sg1.getAsMNode(), "d1").estimateSize();
255-
Assert.assertTrue(
256-
d0ExistSize == schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage()
257-
|| d1ExistSize == schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage());
258-
ReleaseFlushMonitor.getInstance().forceFlushAndRelease();
259-
// wait release and flush task
260-
Thread.sleep(1000);
261-
Assert.assertEquals(
262-
size1, schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage());
263-
}
226+
Assert.assertEquals(size1, schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage());
264227
// schemaRegion2
265228
final IMNode<?> sg2 = nodeFactory.createDatabaseMNode(null, "sg2");
266229
sg2.setFullPath("root.sg2");
@@ -420,7 +383,11 @@ public void testPBTreeNodeStatistics() throws Exception {
420383
schemaRegion1.deleteTimeseriesInBlackList(patternTree);
421384
schemaRegion2.deleteTimeseriesInBlackList(patternTree);
422385

423-
Thread.sleep(1000);
386+
if (testParams.getCachedMNodeSize() <= 3) {
387+
ReleaseFlushMonitor.getInstance().forceFlushAndRelease();
388+
} else {
389+
Thread.sleep(1000);
390+
}
424391
final CachedSchemaRegionStatistics cachedRegionStatistics1 =
425392
schemaRegion1.getSchemaRegionStatistics().getAsCachedSchemaRegionStatistics();
426393
final CachedSchemaRegionStatistics cachedRegionStatistics2 =
@@ -433,13 +400,7 @@ public void testPBTreeNodeStatistics() throws Exception {
433400
Assert.assertEquals(4, cachedRegionStatistics2.getUnpinnedMNodeNum());
434401
} else {
435402
Assert.assertEquals(1, cachedRegionStatistics1.getPinnedMNodeNum());
436-
if (0 != cachedRegionStatistics1.getUnpinnedMNodeNum()) {
437-
// "d0" may remain in PartialMemory mode
438-
Assert.assertEquals("PBTree-PartialMemory", testParams.getTestModeName());
439-
ReleaseFlushMonitor.getInstance().forceFlushAndRelease();
440-
Thread.sleep(1000);
441-
Assert.assertEquals(0, cachedRegionStatistics1.getUnpinnedMNodeNum());
442-
}
403+
Assert.assertEquals(0, cachedRegionStatistics1.getUnpinnedMNodeNum());
443404
Assert.assertEquals(1, cachedRegionStatistics2.getPinnedMNodeNum());
444405
Assert.assertEquals(0, cachedRegionStatistics2.getUnpinnedMNodeNum());
445406
}

0 commit comments

Comments
 (0)