Skip to content

Commit d182c87

Browse files
authored
Fix PBTree schema cache release after pre-delete (#17834)
1 parent 63dfac8 commit d182c87

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
@@ -184,6 +184,7 @@ private N getChild(N parent, String childName, boolean skipTemplateChildren)
184184
&& skipPreDeletedSchema
185185
&& child.isMeasurement()
186186
&& child.getAsMeasurementMNode().isPreDeleted()) {
187+
releaseNode(child);
187188
child = null;
188189
}
189190
}

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
@@ -76,24 +76,12 @@ public void testPBTreeMemoryStatistics() throws Exception {
7676
|| testParams.getTestModeName().equals("PBTree-NonMemory")) {
7777
final IMNodeFactory<ICachedMNode> nodeFactory =
7878
MNodeFactoryLoader.getInstance().getCachedMNodeIMNodeFactory();
79-
// wait release and flush task
80-
Thread.sleep(6000);
79+
ReleaseFlushMonitor.getInstance().forceFlushAndRelease();
8180
// schemaRegion1
8281
final IMNode<ICachedMNode> sg1 = nodeFactory.createDatabaseMNode(null, "sg1");
8382
sg1.setFullPath("root.sg1");
8483
final long size1 = sg1.estimateSize();
85-
if (size1 != schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage()) {
86-
// There are two possibilities here in PartialMemory mode:
87-
// 1. only the "sg1" node remains
88-
// 2. the "sg1" node and the "n" node remain
89-
Assert.assertEquals("PBTree-PartialMemory", testParams.getTestModeName());
90-
Assert.assertEquals(
91-
size1 + nodeFactory.createDeviceMNode(sg1.getAsMNode(), "n").estimateSize(),
92-
schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage());
93-
ReleaseFlushMonitor.getInstance().forceFlushAndRelease();
94-
Assert.assertEquals(
95-
size1, schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage());
96-
}
84+
Assert.assertEquals(size1, schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage());
9785
}
9886
Assert.assertEquals(0, schemaRegion1.getSchemaRegionStatistics().getSchemaRegionId());
9987
checkPBTreeStatistics(engineStatistics);
@@ -123,8 +111,7 @@ public void testMemoryStatistics2() throws Exception {
123111

124112
final IMNodeFactory<?> nodeFactory =
125113
MNodeFactoryLoader.getInstance().getCachedMNodeIMNodeFactory();
126-
// wait release and flush task
127-
Thread.sleep(1000);
114+
ReleaseFlushMonitor.getInstance().forceFlushAndRelease();
128115
// schemaRegion1
129116
final IMNode<?> sg1 = nodeFactory.createDatabaseMNode(null, "sg1");
130117
sg1.setFullPath("root.sg1");
@@ -232,36 +219,12 @@ public void testMemoryStatistics() throws Exception {
232219
|| testParams.getTestModeName().equals("PBTree-NonMemory")) {
233220
final IMNodeFactory<ICachedMNode> nodeFactory =
234221
MNodeFactoryLoader.getInstance().getCachedMNodeIMNodeFactory();
235-
// wait release and flush task
236-
Thread.sleep(1000);
222+
ReleaseFlushMonitor.getInstance().forceFlushAndRelease();
237223
// schemaRegion1
238224
final IMNode<ICachedMNode> sg1 = nodeFactory.createDatabaseDeviceMNode(null, "sg1");
239225
sg1.setFullPath("root.sg1");
240226
final long size1 = sg1.estimateSize();
241-
if (sg1.estimateSize() != schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage()) {
242-
// "d0" or "d1" node may remain in PartialMemory mode
243-
Assert.assertEquals("PBTree-PartialMemory", testParams.getTestModeName());
244-
final long d0ExistSize =
245-
size1
246-
+ nodeFactory
247-
.createMeasurementMNode(
248-
sg1.getAsDeviceMNode(),
249-
"d0",
250-
new MeasurementSchema(
251-
"d0", TSDataType.INT64, TSEncoding.PLAIN, CompressionType.SNAPPY),
252-
null)
253-
.estimateSize();
254-
final long d1ExistSize =
255-
size1 + nodeFactory.createInternalMNode(sg1.getAsMNode(), "d1").estimateSize();
256-
Assert.assertTrue(
257-
d0ExistSize == schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage()
258-
|| d1ExistSize == schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage());
259-
ReleaseFlushMonitor.getInstance().forceFlushAndRelease();
260-
// wait release and flush task
261-
Thread.sleep(1000);
262-
Assert.assertEquals(
263-
size1, schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage());
264-
}
227+
Assert.assertEquals(size1, schemaRegion1.getSchemaRegionStatistics().getRegionMemoryUsage());
265228
// schemaRegion2
266229
final IMNode<?> sg2 = nodeFactory.createDatabaseMNode(null, "sg2");
267230
sg2.setFullPath("root.sg2");
@@ -443,7 +406,11 @@ public void testPBTreeNodeStatistics() throws Exception {
443406
schemaRegion1.deleteTimeseriesInBlackList(patternTree);
444407
schemaRegion2.deleteTimeseriesInBlackList(patternTree);
445408

446-
Thread.sleep(1000);
409+
if (testParams.getCachedMNodeSize() <= 3) {
410+
ReleaseFlushMonitor.getInstance().forceFlushAndRelease();
411+
} else {
412+
Thread.sleep(1000);
413+
}
447414
final CachedSchemaRegionStatistics cachedRegionStatistics1 =
448415
schemaRegion1.getSchemaRegionStatistics().getAsCachedSchemaRegionStatistics();
449416
final CachedSchemaRegionStatistics cachedRegionStatistics2 =
@@ -456,13 +423,7 @@ public void testPBTreeNodeStatistics() throws Exception {
456423
Assert.assertEquals(4, cachedRegionStatistics2.getUnpinnedMNodeNum());
457424
} else {
458425
Assert.assertEquals(1, cachedRegionStatistics1.getPinnedMNodeNum());
459-
if (0 != cachedRegionStatistics1.getUnpinnedMNodeNum()) {
460-
// "d0" may remain in PartialMemory mode
461-
Assert.assertEquals("PBTree-PartialMemory", testParams.getTestModeName());
462-
ReleaseFlushMonitor.getInstance().forceFlushAndRelease();
463-
Thread.sleep(1000);
464-
Assert.assertEquals(0, cachedRegionStatistics1.getUnpinnedMNodeNum());
465-
}
426+
Assert.assertEquals(0, cachedRegionStatistics1.getUnpinnedMNodeNum());
466427
Assert.assertEquals(1, cachedRegionStatistics2.getPinnedMNodeNum());
467428
Assert.assertEquals(0, cachedRegionStatistics2.getUnpinnedMNodeNum());
468429
}

0 commit comments

Comments
 (0)