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

jt2594838 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 39a20ce31b4 Fix table device recovery from schema snapshots (#18324)
39a20ce31b4 is described below

commit 39a20ce31b4b6b11f268af6325dedfac24c46cbe
Author: Caideyipi <[email protected]>
AuthorDate: Wed Jul 29 10:02:33 2026 +0800

    Fix table device recovery from schema snapshots (#18324)
---
 .../impl/mem/snapshot/MemMTreeSnapshotUtil.java    | 15 +++++----
 .../schemaRegion/SchemaRegionManagementTest.java   | 38 ++++++++++++++++++++++
 2 files changed, 46 insertions(+), 7 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/snapshot/MemMTreeSnapshotUtil.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/snapshot/MemMTreeSnapshotUtil.java
index 9589951c36e..96933bdcae1 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/snapshot/MemMTreeSnapshotUtil.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/schemaregion/mtree/impl/mem/snapshot/MemMTreeSnapshotUtil.java
@@ -246,9 +246,6 @@ public class MemMTreeSnapshotUtil {
       case INTERNAL_MNODE_TYPE:
         childrenNum = ReadWriteIOUtils.readInt(inputStream);
         node = deserializer.deserializeInternalMNode(inputStream);
-        if (ancestors.size() == 1) {
-          currentTableName.set(node.getName());
-        }
         break;
       case DATABASE_MNODE_TYPE:
         childrenNum = ReadWriteIOUtils.readInt(inputStream);
@@ -277,16 +274,20 @@ public class MemMTreeSnapshotUtil {
       case TABLE_MNODE_TYPE:
         childrenNum = ReadWriteIOUtils.readInt(inputStream);
         node = deserializer.deserializeTableDeviceMNode(inputStream);
-        if (ancestors.size() == 1) {
-          currentTableName.set(node.getName());
-        }
         deviceProcess.accept(node.getAsDeviceMNode());
-        tableDeviceProcess.accept(node.getAsDeviceMNode(), 
currentTableName.get());
         break;
       default:
         throw new IOException(DataNodeSchemaMessages.UNRECOGNIZED_MNODE_TYPE + 
type);
     }
 
+    // The table-name node may also be a tree-model device in legacy 
mixed-model metadata.
+    if (ancestors.size() == 1) {
+      currentTableName.set(node.getName());
+    }
+    if (type == TABLE_MNODE_TYPE) {
+      tableDeviceProcess.accept(node.getAsDeviceMNode(), 
currentTableName.get());
+    }
+
     regionStatistics.requestMemory(node.estimateSize());
 
     if (!ancestors.isEmpty()) {
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionManagementTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionManagementTest.java
index 0c0b3a5b953..1bbb17bca4a 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionManagementTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/metadata/schemaRegion/SchemaRegionManagementTest.java
@@ -140,6 +140,44 @@ public class SchemaRegionManagementTest extends 
AbstractSchemaRegionTest {
     }
   }
 
+  @Test
+  public void testLoadSnapshotWithTableDeviceBelowTopLevelTreeDevice() throws 
Exception {
+    if (!testParams.getTestModeName().equals("MemoryMode")) {
+      return;
+    }
+
+    final String schemaRegionConsensusProtocolClass =
+        config.getSchemaRegionConsensusProtocolClass();
+    
config.setSchemaRegionConsensusProtocolClass(ConsensusFactory.RATIS_CONSENSUS);
+    try {
+      final ISchemaRegion schemaRegion = getSchemaRegion("root.sg", 0);
+
+      // Build a mixed-model tree where the table-name node is also a 
tree-model device.
+      schemaRegion.createTimeSeries(
+          SchemaRegionWritePlanFactory.getCreateTimeSeriesPlan(
+              new MeasurementPath("root.sg.t.s1"),
+              TSDataType.INT32,
+              TSEncoding.PLAIN,
+              CompressionType.UNCOMPRESSED,
+              null,
+              null,
+              null,
+              null),
+          -1);
+      SchemaRegionTestUtil.createTableDevice(
+          schemaRegion, "t", new String[] {"d1"}, Collections.emptyMap());
+
+      final File snapshotDir = new File(config.getSchemaDir() + File.separator 
+ "snapshot");
+      Assert.assertTrue(snapshotDir.mkdir());
+      Assert.assertTrue(schemaRegion.createSnapshot(snapshotDir));
+
+      Assert.assertTrue(schemaRegion.loadSnapshot(snapshotDir));
+      Assert.assertEquals(1, 
schemaRegion.getSchemaRegionStatistics().getTableDevicesNumber("t"));
+    } finally {
+      
config.setSchemaRegionConsensusProtocolClass(schemaRegionConsensusProtocolClass);
+    }
+  }
+
   private Template generateTemplate() throws IllegalPathException {
     Template template =
         new Template(

Reply via email to