This is an automated email from the ASF dual-hosted git repository. Caideyipi pushed a commit to branch fix/schema-snapshot-table-name in repository https://gitbox.apache.org/repos/asf/iotdb.git
commit 68fc25735c0c40a9a18d3faac550d6c8bf3df46a Author: Caideyipi <[email protected]> AuthorDate: Tue Jul 28 11:44:11 2026 +0800 Fix table device recovery from schema snapshots --- .../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(
