[IOTDB-1511] Extract IStorageGroupMNode and IMeasurementMNode Interface (#3647)

diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/PartitionedSnapshotLogManager.java b/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/PartitionedSnapshotLogManager.java
index 037b977..20535fe 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/PartitionedSnapshotLogManager.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/log/manage/PartitionedSnapshotLogManager.java
@@ -30,7 +30,7 @@
 import org.apache.iotdb.cluster.rpc.thrift.Node;
 import org.apache.iotdb.cluster.server.member.DataGroupMember;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
-import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
+import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.tsfile.write.schema.TimeseriesSchema;
 
@@ -96,7 +96,7 @@
 
   void collectTimeseriesSchemas(List<Integer> requiredSlots) {
     slotTimeseries.clear();
-    List<StorageGroupMNode> allSgNodes = IoTDB.metaManager.getAllStorageGroupNodes();
+    List<IStorageGroupMNode> allSgNodes = IoTDB.metaManager.getAllStorageGroupNodes();
     for (IMNode sgNode : allSgNodes) {
       String storageGroupName = sgNode.getFullPath();
       int slot =
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java b/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java
index 0a115ba..a88ab25 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/metadata/CMManager.java
@@ -45,6 +45,7 @@
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.VectorPartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.InternalMNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
 import org.apache.iotdb.db.metadata.template.Template;
@@ -205,7 +206,7 @@
     // try remote cache first
     try {
       cacheLock.readLock().lock();
-      MeasurementMNode measurementMNode = mRemoteMetaCache.get(path);
+      IMeasurementMNode measurementMNode = mRemoteMetaCache.get(path);
       if (measurementMNode != null) {
         return measurementMNode.getDataType(path.getMeasurement());
       }
@@ -223,7 +224,7 @@
           metaPuller.pullMeasurementSchemas(Collections.singletonList(path));
       if (!schemas.isEmpty()) {
         IMeasurementSchema measurementSchema = schemas.get(0);
-        MeasurementMNode measurementMNode =
+        IMeasurementMNode measurementMNode =
             new MeasurementMNode(
                 null, measurementSchema.getMeasurementId(), measurementSchema, null);
         if (measurementSchema instanceof VectorMeasurementSchema) {
@@ -252,7 +253,7 @@
     Map<IMNode, List<Integer>> nodeToIndex = new LinkedHashMap<>();
     for (int i = 0; i < fullPaths.size(); i++) {
       PartialPath path = fullPaths.get(i);
-      MeasurementMNode node = getMeasurementMNode(path);
+      IMeasurementMNode node = getMeasurementMNode(path);
       super.getNodeToPartialPath(node, nodeToPartialPath, nodeToIndex, path, i);
     }
     return getPair(fullPaths, nodeToPartialPath, nodeToIndex);
@@ -269,7 +270,7 @@
    */
   @Override
   public PartialPath transformPath(PartialPath partialPath) throws MetadataException {
-    MeasurementMNode node = getMeasurementMNode(partialPath);
+    IMeasurementMNode node = getMeasurementMNode(partialPath);
     if (node.getSchema() instanceof MeasurementSchema) {
       return partialPath;
     } else {
@@ -277,12 +278,12 @@
     }
   }
 
-  private MeasurementMNode getMeasurementMNode(PartialPath fullPath) throws MetadataException {
-    MeasurementMNode node = null;
+  private IMeasurementMNode getMeasurementMNode(PartialPath fullPath) throws MetadataException {
+    IMeasurementMNode node = null;
     // try remote cache first
     try {
       cacheLock.readLock().lock();
-      MeasurementMNode measurementMNode = mRemoteMetaCache.get(fullPath);
+      IMeasurementMNode measurementMNode = mRemoteMetaCache.get(fullPath);
       if (measurementMNode != null) {
         node = measurementMNode;
       }
@@ -293,14 +294,14 @@
     if (node == null) {
       // try local MTree
       try {
-        node = (MeasurementMNode) super.getNodeByPath(fullPath);
+        node = (IMeasurementMNode) super.getNodeByPath(fullPath);
       } catch (PathNotExistException e) {
         // pull from remote node
         List<IMeasurementSchema> schemas =
             metaPuller.pullMeasurementSchemas(Collections.singletonList(fullPath));
         if (!schemas.isEmpty()) {
           IMeasurementSchema measurementSchema = schemas.get(0);
-          MeasurementMNode measurementMNode =
+          IMeasurementMNode measurementMNode =
               new MeasurementMNode(
                   null, measurementSchema.getMeasurementId(), measurementSchema, null);
           cacheMeta(fullPath, measurementMNode, true);
@@ -321,14 +322,14 @@
    * @param measurements the measurements.
    */
   @Override
-  public MeasurementMNode[] getMNodes(PartialPath deviceId, String[] measurements)
+  public IMeasurementMNode[] getMNodes(PartialPath deviceId, String[] measurements)
       throws MetadataException {
     try {
       return super.getMNodes(deviceId, measurements);
     } catch (MetadataException e) {
       // some measurements not exist in local
       // try cache
-      MeasurementMNode[] measurementMNodes = new MeasurementMNode[measurements.length];
+      IMeasurementMNode[] measurementMNodes = new IMeasurementMNode[measurements.length];
       int failedMeasurementIndex = getMNodesLocally(deviceId, measurements, measurementMNodes);
       if (failedMeasurementIndex == -1) {
         return measurementMNodes;
@@ -352,12 +353,12 @@
 
   /** @return -1 if all schemas are found, or the first index of the non-exist schema */
   private int getMNodesLocally(
-      PartialPath deviceId, String[] measurements, MeasurementMNode[] measurementMNodes) {
+      PartialPath deviceId, String[] measurements, IMeasurementMNode[] measurementMNodes) {
     int failedMeasurementIndex = -1;
     cacheLock.readLock().lock();
     try {
       for (int i = 0; i < measurements.length && failedMeasurementIndex == -1; i++) {
-        MeasurementMNode measurementMNode =
+        IMeasurementMNode measurementMNode =
             mRemoteMetaCache.get(deviceId.concatNode(measurements[i]));
         if (measurementMNode == null) {
           failedMeasurementIndex = i;
@@ -381,7 +382,7 @@
     for (IMeasurementSchema schema : schemas) {
       // TODO-Cluster: also pull alias?
       // take care, the pulled schema's measurement Id is only series name
-      MeasurementMNode measurementMNode =
+      IMeasurementMNode measurementMNode =
           new MeasurementMNode(null, schema.getMeasurementId(), schema, null);
       cacheMeta(deviceId.concatNode(schema.getMeasurementId()), measurementMNode, true);
     }
@@ -393,7 +394,7 @@
    */
   @Override
   public void cacheMeta(
-      PartialPath seriesPath, MeasurementMNode measurementMNode, boolean needSetFullPath) {
+      PartialPath seriesPath, IMeasurementMNode measurementMNode, boolean needSetFullPath) {
     if (needSetFullPath) {
       measurementMNode.setFullPath(seriesPath.getFullPath());
     }
@@ -408,10 +409,10 @@
       TimeValuePair timeValuePair,
       boolean highPriorityUpdate,
       Long latestFlushedTime,
-      MeasurementMNode node) {
+      IMeasurementMNode node) {
     cacheLock.writeLock().lock();
     try {
-      MeasurementMNode measurementMNode = mRemoteMetaCache.get(seriesPath);
+      IMeasurementMNode measurementMNode = mRemoteMetaCache.get(seriesPath);
       if (measurementMNode != null) {
         measurementMNode.updateCachedLast(timeValuePair, highPriorityUpdate, latestFlushedTime);
       }
@@ -424,7 +425,7 @@
 
   @Override
   public TimeValuePair getLastCache(PartialPath seriesPath) {
-    MeasurementMNode measurementMNode = mRemoteMetaCache.get(seriesPath);
+    IMeasurementMNode measurementMNode = mRemoteMetaCache.get(seriesPath);
     if (measurementMNode != null) {
       return measurementMNode.getCachedLast();
     }
@@ -435,7 +436,7 @@
   @Override
   public IMNode getSeriesSchemasAndReadLockDevice(InsertPlan plan)
       throws MetadataException, IOException {
-    MeasurementMNode[] measurementMNodes = new MeasurementMNode[plan.getMeasurements().length];
+    IMeasurementMNode[] measurementMNodes = new IMeasurementMNode[plan.getMeasurements().length];
     int nonExistSchemaIndex =
         getMNodesLocally(plan.getPrefixPath(), plan.getMeasurements(), measurementMNodes);
     if (nonExistSchemaIndex == -1) {
@@ -462,7 +463,7 @@
     // try cache
     cacheLock.readLock().lock();
     try {
-      MeasurementMNode measurementMNode = mRemoteMetaCache.get(device.concatNode(measurement));
+      IMeasurementMNode measurementMNode = mRemoteMetaCache.get(device.concatNode(measurement));
       if (measurementMNode != null) {
         return measurementMNode.getSchema();
       }
@@ -476,7 +477,7 @@
     // try again
     cacheLock.readLock().lock();
     try {
-      MeasurementMNode measurementMeta = mRemoteMetaCache.get(device.concatNode(measurement));
+      IMeasurementMNode measurementMeta = mRemoteMetaCache.get(device.concatNode(measurement));
       if (measurementMeta != null) {
         return measurementMeta.getSchema();
       }
@@ -517,14 +518,14 @@
         config.getDefaultStorageGroupLevel());
   }
 
-  private static class RemoteMetaCache extends LRUCache<PartialPath, MeasurementMNode> {
+  private static class RemoteMetaCache extends LRUCache<PartialPath, IMeasurementMNode> {
 
     RemoteMetaCache(int cacheSize) {
       super(cacheSize);
     }
 
     @Override
-    protected MeasurementMNode loadObjectByKey(PartialPath key) {
+    protected IMeasurementMNode loadObjectByKey(PartialPath key) {
       return null;
     }
 
@@ -534,7 +535,7 @@
     }
 
     @Override
-    public synchronized MeasurementMNode get(PartialPath key) {
+    public synchronized IMeasurementMNode get(PartialPath key) {
       try {
         return super.get(key);
       } catch (IOException e) {
diff --git a/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanExecutor.java b/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanExecutor.java
index 849b802..373841d 100644
--- a/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanExecutor.java
+++ b/cluster/src/main/java/org/apache/iotdb/cluster/query/ClusterPlanExecutor.java
@@ -41,7 +41,7 @@
 import org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
+import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.crud.AlignByDevicePlan;
@@ -600,7 +600,7 @@
   }
 
   @Override
-  protected List<StorageGroupMNode> getAllStorageGroupNodes() {
+  protected List<IStorageGroupMNode> getAllStorageGroupNodes() {
     try {
       metaGroupMember.syncLeader(null);
     } catch (CheckConsistencyException e) {
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/common/IoTDBTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/common/IoTDBTest.java
index b2ee075..479b96c 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/common/IoTDBTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/common/IoTDBTest.java
@@ -29,7 +29,7 @@
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
@@ -105,7 +105,7 @@
     for (int i = 0; i < measurements.length; i++) {
       measurements[i] = TestUtils.getTestMeasurement(i);
     }
-    MeasurementMNode[] schemas = new MeasurementMNode[10];
+    IMeasurementMNode[] schemas = new IMeasurementMNode[10];
     for (int i = 0; i < measurements.length; i++) {
       schemas[i] = TestUtils.getTestMeasurementMNode(i);
     }
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/common/TestUtils.java b/cluster/src/test/java/org/apache/iotdb/cluster/common/TestUtils.java
index 5f06d3f..986b019 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/common/TestUtils.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/common/TestUtils.java
@@ -38,6 +38,7 @@
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
@@ -210,7 +211,7 @@
         Collections.emptyMap());
   }
 
-  public static MeasurementMNode getTestMeasurementMNode(int seriesNum) {
+  public static IMeasurementMNode getTestMeasurementMNode(int seriesNum) {
     TSDataType dataType = TSDataType.DOUBLE;
     TSEncoding encoding = IoTDBDescriptor.getInstance().getConfig().getDefaultDoubleEncoding();
     IMeasurementSchema measurementSchema =
@@ -301,7 +302,7 @@
     for (int j = 0; j < 10; j++) {
       insertPlan.setPrefixPath(new PartialPath(getTestSg(j)));
       String[] measurements = new String[10];
-      MeasurementMNode[] mNodes = new MeasurementMNode[10];
+      IMeasurementMNode[] mNodes = new IMeasurementMNode[10];
       // 10 series each device, all double
       for (int i = 0; i < 10; i++) {
         measurements[i] = getTestMeasurement(i);
@@ -354,7 +355,7 @@
     // data for fill
     insertPlan.setPrefixPath(new PartialPath(getTestSg(0)));
     String[] measurements = new String[] {getTestMeasurement(10)};
-    MeasurementMNode[] schemas = new MeasurementMNode[] {TestUtils.getTestMeasurementMNode(10)};
+    IMeasurementMNode[] schemas = new IMeasurementMNode[] {TestUtils.getTestMeasurementMNode(10)};
     insertPlan.setMeasurements(measurements);
     insertPlan.setNeedInferType(true);
     insertPlan.setDataTypes(new TSDataType[insertPlan.getMeasurements().length]);
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/DataLogApplierTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/DataLogApplierTest.java
index b55bd9b..a6e86a8 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/DataLogApplierTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/log/applier/DataLogApplierTest.java
@@ -56,7 +56,7 @@
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.qp.physical.crud.DeletePlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowsPlan;
@@ -268,7 +268,7 @@
     insertPlan.setDataTypes(new TSDataType[insertPlan.getMeasurements().length]);
     insertPlan.setValues(new Object[] {"1.0"});
     insertPlan.setNeedInferType(true);
-    insertPlan.setMeasurementMNodes(new MeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
+    insertPlan.setMeasurementMNodes(new IMeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
 
     applier.apply(log);
     QueryDataSet dataSet = query(Collections.singletonList(TestUtils.getTestSeries(1, 0)), null);
@@ -323,7 +323,7 @@
       insertPlan.setValues(new Object[] {"1.0"});
       insertPlan.setNeedInferType(true);
       insertPlan.setMeasurementMNodes(
-          new MeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
+          new IMeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
       insertRowsPlan.addOneInsertRowPlan(insertPlan, i - 1);
     }
 
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/log/logtypes/SerializeLogTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/log/logtypes/SerializeLogTest.java
index bcb3ccb..8ffa221 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/log/logtypes/SerializeLogTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/log/logtypes/SerializeLogTest.java
@@ -27,7 +27,7 @@
 import org.apache.iotdb.cluster.utils.Constants;
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateTimeSeriesPlan;
 import org.apache.iotdb.db.qp.physical.sys.SetStorageGroupPlan;
@@ -57,7 +57,7 @@
     plan.setNeedInferType(true);
     plan.setDataTypes(new TSDataType[plan.getMeasurements().length]);
     plan.setValues(new Object[] {"0.1", "1", "\"dd\""});
-    MeasurementMNode[] schemas = {
+    IMeasurementMNode[] schemas = {
       TestUtils.getTestMeasurementMNode(1),
       TestUtils.getTestMeasurementMNode(2),
       TestUtils.getTestMeasurementMNode(3)
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPlanExecutorTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPlanExecutorTest.java
index e60674c..7b29dfe 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPlanExecutorTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/query/ClusterPlanExecutorTest.java
@@ -23,7 +23,7 @@
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
+import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
 import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
 import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
@@ -82,7 +82,7 @@
 
   @Test
   public void testGetAllStorageGroupNodes() {
-    List<StorageGroupMNode> allStorageGroupNodes = queryExecutor.getAllStorageGroupNodes();
+    List<IStorageGroupMNode> allStorageGroupNodes = queryExecutor.getAllStorageGroupNodes();
     for (int i = 0; i < allStorageGroupNodes.size(); i++) {
       assertEquals(
           IoTDB.metaManager.getAllStorageGroupNodes().get(i).getFullPath(),
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/server/member/DataGroupMemberTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/server/member/DataGroupMemberTest.java
index fecd87d..293549c 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/server/member/DataGroupMemberTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/server/member/DataGroupMemberTest.java
@@ -73,7 +73,7 @@
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateTimeSeriesPlan;
@@ -520,7 +520,7 @@
     insertPlan.setNeedInferType(true);
     insertPlan.setDataTypes(new TSDataType[insertPlan.getMeasurements().length]);
     insertPlan.setValues(new Object[] {"1.0"});
-    insertPlan.setMeasurementMNodes(new MeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
+    insertPlan.setMeasurementMNodes(new IMeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
     insertPlan.transferType();
     processor.insert(insertPlan);
     processor.syncCloseAllWorkingTsFileProcessors();
@@ -729,7 +729,7 @@
       insertPlan.setTime(i);
       insertPlan.setValues(new Object[] {String.valueOf(i)});
       insertPlan.setMeasurementMNodes(
-          new MeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
+          new IMeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
       PlanExecutor PlanExecutor = new PlanExecutor();
       PlanExecutor.processNonQuery(insertPlan);
     }
@@ -797,7 +797,7 @@
       insertPlan.setTime(i);
       insertPlan.setValues(new Object[] {String.valueOf(i)});
       insertPlan.setMeasurementMNodes(
-          new MeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
+          new IMeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
       PlanExecutor PlanExecutor = new PlanExecutor();
       PlanExecutor.processNonQuery(insertPlan);
     }
@@ -865,7 +865,7 @@
       insertPlan.setTime(i);
       insertPlan.setValues(new Object[] {String.valueOf(i)});
       insertPlan.setMeasurementMNodes(
-          new MeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
+          new IMeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
       PlanExecutor PlanExecutor = new PlanExecutor();
       PlanExecutor.processNonQuery(insertPlan);
     }
@@ -933,7 +933,7 @@
       insertPlan.setTime(i);
       insertPlan.setValues(new Object[] {String.valueOf(i)});
       insertPlan.setMeasurementMNodes(
-          new MeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
+          new IMeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
       PlanExecutor PlanExecutor = new PlanExecutor();
       PlanExecutor.processNonQuery(insertPlan);
     }
diff --git a/cluster/src/test/java/org/apache/iotdb/cluster/server/member/MetaGroupMemberTest.java b/cluster/src/test/java/org/apache/iotdb/cluster/server/member/MetaGroupMemberTest.java
index 14706e9..a857599 100644
--- a/cluster/src/test/java/org/apache/iotdb/cluster/server/member/MetaGroupMemberTest.java
+++ b/cluster/src/test/java/org/apache/iotdb/cluster/server/member/MetaGroupMemberTest.java
@@ -88,7 +88,7 @@
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
@@ -588,7 +588,7 @@
       insertPlan.setTime(i);
       insertPlan.setValues(new Object[] {String.valueOf(i)});
       insertPlan.setMeasurementMNodes(
-          new MeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
+          new IMeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
       PlanExecutor planExecutor = new PlanExecutor();
       planExecutor.processNonQuery(insertPlan);
     }
@@ -913,7 +913,7 @@
         insertPlan.setTime(j);
         insertPlan.setValues(new Object[] {String.valueOf(j)});
         insertPlan.setMeasurementMNodes(
-            new MeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
+            new IMeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
         planExecutor.processNonQuery(insertPlan);
       }
     }
@@ -979,7 +979,7 @@
         insertPlan.setTime(j);
         insertPlan.setValues(new Object[] {String.valueOf(j)});
         insertPlan.setMeasurementMNodes(
-            new MeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
+            new IMeasurementMNode[] {TestUtils.getTestMeasurementMNode(0)});
         planExecutor.processNonQuery(insertPlan);
       }
     }
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java b/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java
index 2150984..ef955f5 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/StorageEngine.java
@@ -47,7 +47,7 @@
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.exception.runtime.StorageEngineFailureException;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
+import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
 import org.apache.iotdb.db.monitor.StatMonitor;
 import org.apache.iotdb.db.qp.physical.crud.InsertPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
@@ -239,9 +239,9 @@
             Runtime.getRuntime().availableProcessors(), "Recovery-Thread-Pool");
 
     // recover all logic storage group processors
-    List<StorageGroupMNode> sgNodes = IoTDB.metaManager.getAllStorageGroupNodes();
+    List<IStorageGroupMNode> sgNodes = IoTDB.metaManager.getAllStorageGroupNodes();
     List<Future<Void>> futures = new LinkedList<>();
-    for (StorageGroupMNode storageGroup : sgNodes) {
+    for (IStorageGroupMNode storageGroup : sgNodes) {
       VirtualStorageGroupManager virtualStorageGroupManager =
           processorMap.computeIfAbsent(
               storageGroup.getPartialPath(), id -> new VirtualStorageGroupManager(true));
@@ -387,7 +387,7 @@
       throws StorageEngineException {
     PartialPath storageGroupPath;
     try {
-      StorageGroupMNode storageGroupMNode = IoTDB.metaManager.getStorageGroupNodeByPath(path);
+      IStorageGroupMNode storageGroupMNode = IoTDB.metaManager.getStorageGroupNodeByPath(path);
       storageGroupPath = storageGroupMNode.getPartialPath();
       return getStorageGroupProcessorByPath(storageGroupPath, storageGroupMNode);
     } catch (StorageGroupProcessorException | MetadataException e) {
@@ -403,7 +403,7 @@
    */
   public StorageGroupProcessor getProcessor(PartialPath path) throws StorageEngineException {
     try {
-      StorageGroupMNode storageGroupMNode = IoTDB.metaManager.getStorageGroupNodeByPath(path);
+      IStorageGroupMNode storageGroupMNode = IoTDB.metaManager.getStorageGroupNodeByPath(path);
       return getStorageGroupProcessorByPath(path, storageGroupMNode);
     } catch (StorageGroupProcessorException | MetadataException e) {
       throw new StorageEngineException(e);
@@ -419,7 +419,7 @@
     try {
       List<String> lockHolderList = new ArrayList<>(pathList.size());
       for (PartialPath path : pathList) {
-        StorageGroupMNode storageGroupMNode = IoTDB.metaManager.getStorageGroupNodeByPath(path);
+        IStorageGroupMNode storageGroupMNode = IoTDB.metaManager.getStorageGroupNodeByPath(path);
         StorageGroupProcessor storageGroupProcessor =
             getStorageGroupProcessorByPath(path, storageGroupMNode);
         lockHolderList.add(storageGroupProcessor.getInsertWriteLockHolder());
@@ -441,7 +441,7 @@
   @SuppressWarnings("java:S2445")
   // actually storageGroupMNode is a unique object on the mtree, synchronize it is reasonable
   private StorageGroupProcessor getStorageGroupProcessorByPath(
-      PartialPath devicePath, StorageGroupMNode storageGroupMNode)
+      PartialPath devicePath, IStorageGroupMNode storageGroupMNode)
       throws StorageGroupProcessorException, StorageEngineException {
     VirtualStorageGroupManager virtualStorageGroupManager =
         processorMap.get(storageGroupMNode.getPartialPath());
@@ -465,7 +465,7 @@
    */
   public StorageGroupProcessor buildNewStorageGroupProcessor(
       PartialPath logicalStorageGroupName,
-      StorageGroupMNode storageGroupMNode,
+      IStorageGroupMNode storageGroupMNode,
       String virtualStorageGroupId)
       throws StorageGroupProcessorException {
     StorageGroupProcessor processor;
@@ -511,7 +511,7 @@
       storageGroupProcessor.insert(insertRowPlan);
       if (config.isEnableStatMonitor()) {
         try {
-          StorageGroupMNode storageGroupMNode =
+          IStorageGroupMNode storageGroupMNode =
               IoTDB.metaManager.getStorageGroupNodeByPath(insertRowPlan.getPrefixPath());
           updateMonitorStatistics(
               processorMap.get(storageGroupMNode.getPartialPath()), insertRowPlan);
@@ -571,7 +571,7 @@
 
     if (config.isEnableStatMonitor()) {
       try {
-        StorageGroupMNode storageGroupMNode =
+        IStorageGroupMNode storageGroupMNode =
             IoTDB.metaManager.getStorageGroupNodeByPath(insertTabletPlan.getPrefixPath());
         updateMonitorStatistics(
             processorMap.get(storageGroupMNode.getPartialPath()), insertTabletPlan);
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
index 569d2f4..51af231 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/memtable/AbstractMemTable.java
@@ -24,7 +24,7 @@
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.MetaUtils;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertTabletPlan;
 import org.apache.iotdb.db.rescon.TVListAllocator;
@@ -124,10 +124,10 @@
     updatePlanIndexes(insertRowPlan.getIndex());
     Object[] values = insertRowPlan.getValues();
 
-    MeasurementMNode[] measurementMNodes = insertRowPlan.getMeasurementMNodes();
+    IMeasurementMNode[] measurementMNodes = insertRowPlan.getMeasurementMNodes();
     int columnIndex = 0;
     if (insertRowPlan.isAligned()) {
-      MeasurementMNode measurementMNode = measurementMNodes[0];
+      IMeasurementMNode measurementMNode = measurementMNodes[0];
       if (measurementMNode != null) {
         // write vector
         Object[] vectorValue =
@@ -148,7 +148,7 @@
             vectorValue);
       }
     } else {
-      for (MeasurementMNode measurementMNode : measurementMNodes) {
+      for (IMeasurementMNode measurementMNode : measurementMNodes) {
         if (values[columnIndex] == null) {
           columnIndex++;
           continue;
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/merge/task/MergeTask.java b/server/src/main/java/org/apache/iotdb/db/engine/merge/task/MergeTask.java
index d35e75b..bcc774a 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/merge/task/MergeTask.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/merge/task/MergeTask.java
@@ -26,7 +26,7 @@
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.db.utils.MergeUtils;
 import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
@@ -153,7 +153,7 @@
       // todo add template merge logic
       for (Entry<String, IMNode> entry : deviceNode.getChildren().entrySet()) {
         PartialPath path = device.concatNode(entry.getKey());
-        measurementSchemaMap.put(path, ((MeasurementMNode) entry.getValue()).getSchema());
+        measurementSchemaMap.put(path, ((IMeasurementMNode) entry.getValue()).getSchema());
         unmergedSeries.add(path);
       }
     }
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
index 0481b27..af54491 100755
--- a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessor.java
@@ -56,7 +56,7 @@
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.qp.physical.crud.DeletePlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowsOfOneDevicePlan;
@@ -1063,7 +1063,7 @@
     if (!IoTDBDescriptor.getInstance().getConfig().isLastCacheEnabled()) {
       return;
     }
-    MeasurementMNode[] mNodes = plan.getMeasurementMNodes();
+    IMeasurementMNode[] mNodes = plan.getMeasurementMNodes();
     int columnIndex = 0;
     for (int i = 0; i < mNodes.length; i++) {
       // Don't update cached last value for vector type
@@ -1130,9 +1130,9 @@
     if (!IoTDBDescriptor.getInstance().getConfig().isLastCacheEnabled()) {
       return;
     }
-    MeasurementMNode[] mNodes = plan.getMeasurementMNodes();
+    IMeasurementMNode[] mNodes = plan.getMeasurementMNodes();
     int columnIndex = 0;
-    for (MeasurementMNode mNode : mNodes) {
+    for (IMeasurementMNode mNode : mNodes) {
       // Don't update cached last value for vector type
       if (!plan.isAligned()) {
         if (plan.getValues()[columnIndex] == null) {
@@ -1938,11 +1938,11 @@
       for (IMNode measurementNode : node.getChildren().values()) {
         if (measurementNode != null
             && originalPath.matchFullPath(measurementNode.getPartialPath())) {
-          TimeValuePair lastPair = ((MeasurementMNode) measurementNode).getCachedLast();
+          TimeValuePair lastPair = ((IMeasurementMNode) measurementNode).getCachedLast();
           if (lastPair != null
               && startTime <= lastPair.getTimestamp()
               && lastPair.getTimestamp() <= endTime) {
-            ((MeasurementMNode) measurementNode).resetCache();
+            ((IMeasurementMNode) measurementNode).resetCache();
             logger.info(
                 "[tryToDeleteLastCache] Last cache for path: {} is set to null",
                 measurementNode.getFullPath());
@@ -2282,7 +2282,7 @@
 
       for (IMNode measurementNode : node.getChildren().values()) {
         if (measurementNode != null) {
-          ((MeasurementMNode) measurementNode).resetCache();
+          ((IMeasurementMNode) measurementNode).resetCache();
           logger.debug(
               "[tryToDeleteLastCacheByDevice] Last cache for path: {} is set to null",
               measurementNode.getFullPath());
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/VirtualStorageGroupManager.java b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/VirtualStorageGroupManager.java
index 1f65389..a969fe2 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/VirtualStorageGroupManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/storagegroup/virtualSg/VirtualStorageGroupManager.java
@@ -27,7 +27,7 @@
 import org.apache.iotdb.db.exception.StorageGroupProcessorException;
 import org.apache.iotdb.db.exception.TsFileProcessorException;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
+import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
 import org.apache.iotdb.rpc.TSStatusCode;
 import org.apache.iotdb.tsfile.utils.Pair;
 
@@ -123,7 +123,7 @@
   @SuppressWarnings("java:S2445")
   // actually storageGroupMNode is a unique object on the mtree, synchronize it is reasonable
   public StorageGroupProcessor getProcessor(
-      PartialPath partialPath, StorageGroupMNode storageGroupMNode)
+      PartialPath partialPath, IStorageGroupMNode storageGroupMNode)
       throws StorageGroupProcessorException, StorageEngineException {
     int loc = partitioner.deviceToVirtualStorageGroupId(partialPath);
 
@@ -162,7 +162,7 @@
    * @param futures virtual storage group recover tasks
    */
   public void asyncRecover(
-      StorageGroupMNode storageGroupMNode, ExecutorService pool, List<Future<Void>> futures) {
+      IStorageGroupMNode storageGroupMNode, ExecutorService pool, List<Future<Void>> futures) {
     for (int i = 0; i < partitioner.getPartitionCount(); i++) {
       int cur = i;
       Callable<Void> recoverVsgTask =
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/trigger/executor/TriggerEngine.java b/server/src/main/java/org/apache/iotdb/db/engine/trigger/executor/TriggerEngine.java
index 2dfb10f..458ae3e 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/trigger/executor/TriggerEngine.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/trigger/executor/TriggerEngine.java
@@ -23,7 +23,7 @@
 import org.apache.iotdb.db.engine.trigger.service.TriggerRegistrationService;
 import org.apache.iotdb.db.exception.TriggerExecutionException;
 import org.apache.iotdb.db.exception.TriggerManagementException;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertTabletPlan;
 import org.apache.iotdb.db.qp.physical.sys.DropTriggerPlan;
@@ -40,14 +40,14 @@
 
   public static void fire(TriggerEvent event, InsertRowPlan insertRowPlan)
       throws TriggerExecutionException {
-    MeasurementMNode[] mNodes = insertRowPlan.getMeasurementMNodes();
+    IMeasurementMNode[] mNodes = insertRowPlan.getMeasurementMNodes();
     int size = mNodes.length;
 
     long timestamp = insertRowPlan.getTime();
     Object[] values = insertRowPlan.getValues();
 
     for (int i = 0; i < size; ++i) {
-      MeasurementMNode mNode = mNodes[i];
+      IMeasurementMNode mNode = mNodes[i];
       if (mNode == null) {
         continue;
       }
@@ -61,7 +61,7 @@
 
   public static void fire(TriggerEvent event, InsertTabletPlan insertTabletPlan, int firePosition)
       throws TriggerExecutionException {
-    MeasurementMNode[] mNodes = insertTabletPlan.getMeasurementMNodes();
+    IMeasurementMNode[] mNodes = insertTabletPlan.getMeasurementMNodes();
     int size = mNodes.length;
 
     long[] timestamps = insertTabletPlan.getTimes();
@@ -72,7 +72,7 @@
     }
 
     for (int i = 0; i < size; ++i) {
-      MeasurementMNode mNode = mNodes[i];
+      IMeasurementMNode mNode = mNodes[i];
       if (mNode == null) {
         continue;
       }
@@ -84,7 +84,7 @@
     }
   }
 
-  public static void drop(MeasurementMNode measurementMNode) {
+  public static void drop(IMeasurementMNode measurementMNode) {
     TriggerExecutor executor = measurementMNode.getTriggerExecutor();
     if (executor == null) {
       return;
@@ -104,8 +104,8 @@
     }
   }
 
-  public static void drop(List<MeasurementMNode> measurementMNodes) {
-    for (MeasurementMNode measurementMNode : measurementMNodes) {
+  public static void drop(List<IMeasurementMNode> measurementMNodes) {
+    for (IMeasurementMNode measurementMNode : measurementMNodes) {
       drop(measurementMNode);
     }
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/trigger/executor/TriggerExecutor.java b/server/src/main/java/org/apache/iotdb/db/engine/trigger/executor/TriggerExecutor.java
index a747bec..ebb523d 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/trigger/executor/TriggerExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/trigger/executor/TriggerExecutor.java
@@ -25,7 +25,7 @@
 import org.apache.iotdb.db.engine.trigger.service.TriggerRegistrationInformation;
 import org.apache.iotdb.db.exception.TriggerExecutionException;
 import org.apache.iotdb.db.exception.TriggerManagementException;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.utils.TestOnly;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
 import org.apache.iotdb.tsfile.utils.Binary;
@@ -39,7 +39,7 @@
 
   private final TriggerClassLoader classLoader;
 
-  private final MeasurementMNode measurementMNode;
+  private final IMeasurementMNode measurementMNode;
   private final TSDataType seriesDataType;
 
   private final Trigger trigger;
@@ -47,7 +47,7 @@
   public TriggerExecutor(
       TriggerRegistrationInformation registrationInformation,
       TriggerClassLoader classLoader,
-      MeasurementMNode measurementMNode)
+      IMeasurementMNode measurementMNode)
       throws TriggerManagementException {
     this.registrationInformation = registrationInformation;
     attributes = new TriggerAttributes(registrationInformation.getAttributes());
@@ -231,7 +231,7 @@
     return registrationInformation;
   }
 
-  public MeasurementMNode getMeasurementMNode() {
+  public IMeasurementMNode getMeasurementMNode() {
     return measurementMNode;
   }
 
diff --git a/server/src/main/java/org/apache/iotdb/db/engine/trigger/service/TriggerRegistrationService.java b/server/src/main/java/org/apache/iotdb/db/engine/trigger/service/TriggerRegistrationService.java
index b6675e9..da74389 100644
--- a/server/src/main/java/org/apache/iotdb/db/engine/trigger/service/TriggerRegistrationService.java
+++ b/server/src/main/java/org/apache/iotdb/db/engine/trigger/service/TriggerRegistrationService.java
@@ -28,7 +28,7 @@
 import org.apache.iotdb.db.exception.TriggerManagementException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.sys.CreateTriggerPlan;
 import org.apache.iotdb.db.qp.physical.sys.DropTriggerPlan;
@@ -91,7 +91,7 @@
   public synchronized void register(CreateTriggerPlan plan)
       throws TriggerManagementException, TriggerExecutionException {
     checkIfRegistered(plan);
-    MeasurementMNode measurementMNode = tryGetMeasurementMNode(plan);
+    IMeasurementMNode measurementMNode = tryGetMeasurementMNode(plan);
     tryAppendRegistrationLog(plan);
     doRegister(plan, measurementMNode);
   }
@@ -116,10 +116,10 @@
                 information.getClassName()));
   }
 
-  private MeasurementMNode tryGetMeasurementMNode(CreateTriggerPlan plan)
+  private IMeasurementMNode tryGetMeasurementMNode(CreateTriggerPlan plan)
       throws TriggerManagementException {
     try {
-      return (MeasurementMNode) IoTDB.metaManager.getNodeByPath(plan.getFullPath());
+      return (IMeasurementMNode) IoTDB.metaManager.getNodeByPath(plan.getFullPath());
     } catch (MetadataException e) {
       throw new TriggerManagementException(e.getMessage(), e);
     } catch (ClassCastException e) {
@@ -138,7 +138,7 @@
     }
   }
 
-  private void doRegister(CreateTriggerPlan plan, MeasurementMNode measurementMNode)
+  private void doRegister(CreateTriggerPlan plan, IMeasurementMNode measurementMNode)
       throws TriggerManagementException, TriggerExecutionException {
     TriggerRegistrationInformation information = new TriggerRegistrationInformation(plan);
     TriggerClassLoader classLoader =
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
index 9c686f5..b1c33ee 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MManager.java
@@ -35,9 +35,7 @@
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.metadata.logfile.MLogReader;
 import org.apache.iotdb.db.metadata.logfile.MLogWriter;
-import org.apache.iotdb.db.metadata.mnode.IMNode;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
-import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
+import org.apache.iotdb.db.metadata.mnode.*;
 import org.apache.iotdb.db.metadata.tag.TagManager;
 import org.apache.iotdb.db.metadata.template.Template;
 import org.apache.iotdb.db.metadata.template.TemplateManager;
@@ -445,7 +443,7 @@
 
       TSDataType type = plan.getDataType();
       // create time series in MTree
-      MeasurementMNode leafMNode =
+      IMeasurementMNode leafMNode =
           mtree.createTimeseries(
               path,
               type,
@@ -591,7 +589,7 @@
       // should be removed after partial deletion is supported
       IMNode lastNode = getNodeByPath(allTimeseries.get(0));
       if (lastNode instanceof MeasurementMNode) {
-        IMeasurementSchema schema = ((MeasurementMNode) lastNode).getSchema();
+        IMeasurementSchema schema = ((IMeasurementMNode) lastNode).getSchema();
         if (schema instanceof VectorMeasurementSchema) {
           if (schema.getValueMeasurementIdList().size() != allTimeseries.size()) {
             throw new AlignedTimeseriesException(
@@ -636,7 +634,7 @@
 
   /** remove the node from the tag inverted index */
   @SuppressWarnings("squid:S3776") // Suppress high Cognitive Complexity warning
-  private void removeFromTagInvertedIndex(MeasurementMNode node) throws IOException {
+  private void removeFromTagInvertedIndex(IMeasurementMNode node) throws IOException {
     tagManager.removeFromTagInvertedIndex(node);
   }
 
@@ -646,7 +644,7 @@
    */
   private PartialPath deleteOneTimeseriesUpdateStatisticsAndDropTrigger(PartialPath path)
       throws MetadataException, IOException {
-    Pair<PartialPath, MeasurementMNode> pair =
+    Pair<PartialPath, IMeasurementMNode> pair =
         mtree.deleteTimeseriesAndReturnEmptyStorageGroup(path);
     // if one of the aligned timeseries is deleted, pair.right could be null
     IMeasurementSchema schema = pair.right.getSchema();
@@ -710,8 +708,8 @@
         mNodeCache.clear();
 
         // try to delete storage group
-        List<MeasurementMNode> leafMNodes = mtree.deleteStorageGroup(storageGroup);
-        for (MeasurementMNode leafMNode : leafMNodes) {
+        List<IMeasurementMNode> leafMNodes = mtree.deleteStorageGroup(storageGroup);
+        for (IMeasurementMNode leafMNode : leafMNodes) {
           removeFromTagInvertedIndex(leafMNode);
         }
 
@@ -768,12 +766,12 @@
     }
   }
 
-  public MeasurementMNode[] getMNodes(PartialPath deviceId, String[] measurements)
+  public IMeasurementMNode[] getMNodes(PartialPath deviceId, String[] measurements)
       throws MetadataException {
-    MeasurementMNode[] mNodes = new MeasurementMNode[measurements.length];
+    IMeasurementMNode[] mNodes = new IMeasurementMNode[measurements.length];
     for (int i = 0; i < mNodes.length; i++) {
       try {
-        mNodes[i] = (MeasurementMNode) getNodeByPath(deviceId.concatNode(measurements[i]));
+        mNodes[i] = (IMeasurementMNode) getNodeByPath(deviceId.concatNode(measurements[i]));
       } catch (PathNotExistException ignored) {
         logger.warn("{} does not exist in {}", measurements[i], deviceId);
       }
@@ -851,7 +849,7 @@
   }
 
   /** Get all storage group MNodes */
-  public List<StorageGroupMNode> getAllStorageGroupNodes() {
+  public List<IStorageGroupMNode> getAllStorageGroupNodes() {
     return mtree.getAllStorageGroupNodes();
   }
 
@@ -911,7 +909,7 @@
   private List<ShowTimeSeriesResult> showTimeseriesWithIndex(
       ShowTimeSeriesPlan plan, QueryContext context) throws MetadataException {
 
-    List<MeasurementMNode> allMatchedNodes = tagManager.getMatchedTimeseriesInIndex(plan, context);
+    List<IMeasurementMNode> allMatchedNodes = tagManager.getMatchedTimeseriesInIndex(plan, context);
 
     List<ShowTimeSeriesResult> res = new LinkedList<>();
     String[] prefixNodes = plan.getPath().getNodes();
@@ -919,7 +917,7 @@
     int count = 0;
     int limit = plan.getLimit();
     int offset = plan.getOffset();
-    for (MeasurementMNode leaf : allMatchedNodes) {
+    for (IMeasurementMNode leaf : allMatchedNodes) {
       if (match(leaf.getPartialPath(), prefixNodes)) {
         if (limit != 0 || offset != 0) {
           curOffset++;
@@ -1018,7 +1016,7 @@
   public IMeasurementSchema getSeriesSchema(PartialPath device, String measurement)
       throws MetadataException {
     IMNode deviceIMNode = getDeviceNode(device);
-    MeasurementMNode measurementMNode = (MeasurementMNode) deviceIMNode.getChild(measurement);
+    IMeasurementMNode measurementMNode = (IMeasurementMNode) deviceIMNode.getChild(measurement);
     if (measurementMNode == null) {
       // Just for the initial adaptation of the template functionality and merge functionality
       // The getSeriesSchema interface needs to be cleaned up later
@@ -1034,11 +1032,11 @@
    * @return MeasurementSchema or VectorMeasurementSchema
    */
   public IMeasurementSchema getSeriesSchema(PartialPath fullPath) throws MetadataException {
-    MeasurementMNode leaf = (MeasurementMNode) mtree.getNodeByPath(fullPath);
+    IMeasurementMNode leaf = (IMeasurementMNode) mtree.getNodeByPath(fullPath);
     return getSeriesSchema(fullPath, leaf);
   }
 
-  protected IMeasurementSchema getSeriesSchema(PartialPath fullPath, MeasurementMNode leaf) {
+  protected IMeasurementSchema getSeriesSchema(PartialPath fullPath, IMeasurementMNode leaf) {
     IMeasurementSchema schema = leaf.getSchema();
 
     if (schema == null || schema.getType() != TSDataType.VECTOR) {
@@ -1067,7 +1065,7 @@
    * we don't change it.
    */
   public PartialPath transformPath(PartialPath partialPath) throws MetadataException {
-    MeasurementMNode node = (MeasurementMNode) getNodeByPath(partialPath);
+    IMeasurementMNode node = (IMeasurementMNode) getNodeByPath(partialPath);
     if (node.getSchema() instanceof MeasurementSchema) {
       return partialPath;
     } else {
@@ -1099,14 +1097,14 @@
     for (int i = 0; i < fullPaths.size(); i++) {
       PartialPath path = fullPaths.get(i);
       // use dfs to collect paths
-      MeasurementMNode node = (MeasurementMNode) getNodeByPath(path);
+      IMeasurementMNode node = (IMeasurementMNode) getNodeByPath(path);
       getNodeToPartialPath(node, nodeToPartialPath, nodeToIndex, path, i);
     }
     return getPair(fullPaths, nodeToPartialPath, nodeToIndex);
   }
 
   protected void getNodeToPartialPath(
-      MeasurementMNode node,
+      IMeasurementMNode node,
       Map<IMNode, PartialPath> nodeToPartialPath,
       Map<IMNode, List<Integer>> nodeToIndex,
       PartialPath path,
@@ -1203,13 +1201,13 @@
    * device], return the MNode of root.sg Get storage group node by path. If storage group is not
    * set, StorageGroupNotSetException will be thrown
    */
-  public StorageGroupMNode getStorageGroupNodeByStorageGroupPath(PartialPath path)
+  public IStorageGroupMNode getStorageGroupNodeByStorageGroupPath(PartialPath path)
       throws MetadataException {
     return mtree.getStorageGroupNodeByStorageGroupPath(path);
   }
 
   /** Get storage group node by path. the give path don't need to be storage group path. */
-  public StorageGroupMNode getStorageGroupNodeByPath(PartialPath path) throws MetadataException {
+  public IStorageGroupMNode getStorageGroupNodeByPath(PartialPath path) throws MetadataException {
     return mtree.getStorageGroupNodeByPath(path);
   }
 
@@ -1280,7 +1278,7 @@
       }
 
       for (IMNode IMNode : mNodeTemplatePair.left.getChildren().values()) {
-        MeasurementMNode measurementMNode = (MeasurementMNode) IMNode;
+        IMeasurementMNode measurementMNode = (IMeasurementMNode) IMNode;
         res.add(measurementMNode.getSchema());
       }
 
@@ -1362,11 +1360,11 @@
    * @param offset offset in the tag file
    */
   public void changeOffset(PartialPath path, long offset) throws MetadataException {
-    ((MeasurementMNode) mtree.getNodeByPath(path)).setOffset(offset);
+    ((IMeasurementMNode) mtree.getNodeByPath(path)).setOffset(offset);
   }
 
   public void changeAlias(PartialPath path, String alias) throws MetadataException {
-    MeasurementMNode leafMNode = (MeasurementMNode) mtree.getNodeByPath(path);
+    IMeasurementMNode leafMNode = (IMeasurementMNode) mtree.getNodeByPath(path);
     if (leafMNode.getAlias() != null) {
       leafMNode.getParent().deleteAliasChild(leafMNode.getAlias());
     }
@@ -1394,7 +1392,7 @@
     if (!(IMNode instanceof MeasurementMNode)) {
       throw new PathNotExistException(fullPath.getFullPath());
     }
-    MeasurementMNode leafMNode = (MeasurementMNode) IMNode;
+    IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
     // upsert alias
     upsertAlias(alias, fullPath, leafMNode);
 
@@ -1414,7 +1412,7 @@
     tagManager.updateTagsAndAttributes(tagsMap, attributesMap, leafMNode);
   }
 
-  private void upsertAlias(String alias, PartialPath fullPath, MeasurementMNode leafMNode)
+  private void upsertAlias(String alias, PartialPath fullPath, IMeasurementMNode leafMNode)
       throws MetadataException, IOException {
     // upsert alias
     if (alias != null && !alias.equals(leafMNode.getAlias())) {
@@ -1444,7 +1442,7 @@
     if (!(IMNode instanceof MeasurementMNode)) {
       throw new PathNotExistException(fullPath.getFullPath());
     }
-    MeasurementMNode leafMNode = (MeasurementMNode) IMNode;
+    IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
     // no tag or attribute, we need to add a new record in log
     if (leafMNode.getOffset() < 0) {
       long offset = tagManager.writeTagFile(Collections.emptyMap(), attributesMap);
@@ -1468,7 +1466,7 @@
     if (!(IMNode instanceof MeasurementMNode)) {
       throw new PathNotExistException(fullPath.getFullPath());
     }
-    MeasurementMNode leafMNode = (MeasurementMNode) IMNode;
+    IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
     // no tag or attribute, we need to add a new record in log
     if (leafMNode.getOffset() < 0) {
       long offset = tagManager.writeTagFile(tagsMap, Collections.emptyMap());
@@ -1495,7 +1493,7 @@
     if (!(IMNode instanceof MeasurementMNode)) {
       throw new PathNotExistException(fullPath.getFullPath());
     }
-    MeasurementMNode leafMNode = (MeasurementMNode) IMNode;
+    IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
     // no tag or attribute, just do nothing.
     if (leafMNode.getOffset() < 0) {
       return;
@@ -1516,7 +1514,7 @@
     if (!(IMNode instanceof MeasurementMNode)) {
       throw new PathNotExistException(fullPath.getFullPath());
     }
-    MeasurementMNode leafMNode = (MeasurementMNode) IMNode;
+    IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
     if (leafMNode.getOffset() < 0) {
       throw new MetadataException(
           String.format("TimeSeries [%s] does not have any tag/attribute.", fullPath));
@@ -1540,7 +1538,7 @@
     if (!(IMNode instanceof MeasurementMNode)) {
       throw new PathNotExistException(fullPath.getFullPath());
     }
-    MeasurementMNode leafMNode = (MeasurementMNode) IMNode;
+    IMeasurementMNode leafMNode = (IMeasurementMNode) IMNode;
     if (leafMNode.getOffset() < 0) {
       throw new MetadataException(
           String.format("TimeSeries [%s] does not have [%s] tag/attribute.", fullPath, oldKey),
@@ -1576,7 +1574,7 @@
     while (!nodeDeque.isEmpty()) {
       IMNode node = nodeDeque.removeFirst();
       if (node instanceof MeasurementMNode) {
-        IMeasurementSchema nodeSchema = ((MeasurementMNode) node).getSchema();
+        IMeasurementSchema nodeSchema = ((IMeasurementMNode) node).getSchema();
         timeseriesSchemas.add(
             new TimeseriesSchema(
                 node.getFullPath(),
@@ -1601,7 +1599,7 @@
     while (!nodeDeque.isEmpty()) {
       IMNode node = nodeDeque.removeFirst();
       if (node instanceof MeasurementMNode) {
-        IMeasurementSchema nodeSchema = ((MeasurementMNode) node).getSchema();
+        IMeasurementSchema nodeSchema = ((IMeasurementMNode) node).getSchema();
         measurementSchemas.add(nodeSchema);
       } else if (!node.getChildren().isEmpty()) {
         nodeDeque.addAll(node.getChildren().values());
@@ -1657,7 +1655,7 @@
    * cache the path to mRemoteSchemaCache
    */
   public void cacheMeta(
-      PartialPath path, MeasurementMNode measurementMNode, boolean needSetFullPath) {
+      PartialPath path, IMeasurementMNode measurementMNode, boolean needSetFullPath) {
     // do nothing
   }
 
@@ -1666,12 +1664,12 @@
       TimeValuePair timeValuePair,
       boolean highPriorityUpdate,
       Long latestFlushedTime,
-      MeasurementMNode node) {
+      IMeasurementMNode node) {
     if (node != null) {
       node.updateCachedLast(timeValuePair, highPriorityUpdate, latestFlushedTime);
     } else {
       try {
-        MeasurementMNode node1 = (MeasurementMNode) mtree.getNodeByPath(seriesPath);
+        IMeasurementMNode node1 = (IMeasurementMNode) mtree.getNodeByPath(seriesPath);
         node1.updateCachedLast(timeValuePair, highPriorityUpdate, latestFlushedTime);
       } catch (MetadataException e) {
         logger.warn("failed to update last cache for the {}, err:{}", seriesPath, e.getMessage());
@@ -1681,7 +1679,7 @@
 
   public TimeValuePair getLastCache(PartialPath seriesPath) {
     try {
-      MeasurementMNode node = (MeasurementMNode) mtree.getNodeByPath(seriesPath);
+      IMeasurementMNode node = (IMeasurementMNode) mtree.getNodeByPath(seriesPath);
       return node.getCachedLast();
     } catch (MetadataException e) {
       logger.warn("failed to get last cache for the {}, err:{}", seriesPath, e.getMessage());
@@ -1701,7 +1699,7 @@
       vectorId = prefixPath.getMeasurement();
     }
     String[] measurementList = plan.getMeasurements();
-    MeasurementMNode[] measurementMNodes = plan.getMeasurementMNodes();
+    IMeasurementMNode[] measurementMNodes = plan.getMeasurementMNodes();
 
     // 1. get device node
     Pair<IMNode, Template> deviceMNode = getDeviceNodeWithAutoCreate(deviceId);
@@ -1712,7 +1710,7 @@
 
     // check insert non-aligned InsertPlan for aligned timeseries
     if (deviceMNode.left instanceof MeasurementMNode
-        && ((MeasurementMNode) deviceMNode.left).getSchema() instanceof VectorMeasurementSchema
+        && ((IMeasurementMNode) deviceMNode.left).getSchema() instanceof VectorMeasurementSchema
         && !plan.isAligned()) {
       throw new MetadataException(
           String.format(
@@ -1731,13 +1729,13 @@
 
     // 2. get schema of each measurement
     // if do not have measurement
-    MeasurementMNode measurementMNode;
+    IMeasurementMNode measurementMNode;
     for (int i = 0; i < measurementList.length; i++) {
       try {
         String measurement = measurementList[i];
         IMNode child = getMNode(deviceMNode.left, plan.isAligned() ? vectorId : measurement);
         if (child instanceof MeasurementMNode) {
-          measurementMNode = (MeasurementMNode) child;
+          measurementMNode = (IMeasurementMNode) child;
         } else if (child instanceof StorageGroupMNode) {
           throw new PathAlreadyExistException(deviceId + PATH_SEPARATOR + measurement);
         } else if ((measurementMNode = findTemplate(deviceMNode, measurement, vectorId)) != null) {
@@ -1750,11 +1748,11 @@
               if (!plan.isAligned()) {
                 internalCreateTimeseries(
                     prefixPath.concatNode(measurement), plan.getDataTypes()[i]);
-                measurementMNode = (MeasurementMNode) deviceMNode.left.getChild(measurement);
+                measurementMNode = (IMeasurementMNode) deviceMNode.left.getChild(measurement);
               } else {
                 internalAlignedCreateTimeseries(
                     prefixPath, Arrays.asList(measurementList), Arrays.asList(plan.getDataTypes()));
-                measurementMNode = (MeasurementMNode) deviceMNode.left.getChild(vectorId);
+                measurementMNode = (IMeasurementMNode) deviceMNode.left.getChild(vectorId);
               }
             } else {
               throw new MetadataException(
@@ -1869,7 +1867,7 @@
     return deviceMNode.getChild(measurementName);
   }
 
-  private MeasurementMNode findTemplate(
+  private IMeasurementMNode findTemplate(
       Pair<IMNode, Template> deviceMNode, String measurement, String vectorId)
       throws MetadataException {
     if (deviceMNode.right != null) {
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
index aff1214..8fa19fa 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/MTree.java
@@ -35,6 +35,8 @@
 import org.apache.iotdb.db.metadata.logfile.MLogReader;
 import org.apache.iotdb.db.metadata.logfile.MLogWriter;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
 import org.apache.iotdb.db.metadata.mnode.InternalMNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
@@ -178,7 +180,7 @@
     }
   }
 
-  public static long getLastTimeStamp(MeasurementMNode node, QueryContext queryContext) {
+  public static long getLastTimeStamp(IMeasurementMNode node, QueryContext queryContext) {
     TimeValuePair last = node.getCachedLast();
     if (last != null) {
       return node.getCachedLast().getTimestamp();
@@ -270,7 +272,7 @@
    * @param props props
    * @param alias alias of measurement
    */
-  MeasurementMNode createTimeseries(
+  IMeasurementMNode createTimeseries(
       PartialPath path,
       TSDataType dataType,
       TSEncoding encoding,
@@ -338,7 +340,7 @@
         throw new AliasAlreadyExistException(path.getFullPath(), alias);
       }
 
-      MeasurementMNode measurementMNode =
+      IMeasurementMNode measurementMNode =
           new MeasurementMNode(cur, leafName, alias, dataType, encoding, compressor, props);
       cur.addChild(leafName, measurementMNode);
       // link alias to LeafMNode
@@ -410,7 +412,7 @@
       int measurementsSize = measurements.size();
 
       // this measurementMNode could be a leaf or not.
-      MeasurementMNode measurementMNode =
+      IMeasurementMNode measurementMNode =
           new MeasurementMNode(
               cur,
               leafName,
@@ -537,9 +539,9 @@
         if (i == nodeNames.length - 1) {
           return true;
         }
-        if (((MeasurementMNode) cur).getSchema() instanceof VectorMeasurementSchema) {
+        if (((IMeasurementMNode) cur).getSchema() instanceof VectorMeasurementSchema) {
           return i == nodeNames.length - 2
-              && ((MeasurementMNode) cur).getSchema().isCompatible(nodeNames[i + 1]);
+              && ((IMeasurementMNode) cur).getSchema().isCompatible(nodeNames[i + 1]);
         } else {
           return false;
         }
@@ -596,7 +598,7 @@
           throw new PathAlreadyExistException(
               cur.getPartialPath().concatNode(nodeNames[i]).getFullPath());
         }
-        StorageGroupMNode storageGroupMNode =
+        IStorageGroupMNode storageGroupMNode =
             new StorageGroupMNode(
                 cur, nodeNames[i], IoTDBDescriptor.getInstance().getConfig().getDefaultTTL());
         cur.addChild(nodeNames[i], storageGroupMNode);
@@ -614,7 +616,7 @@
   }
 
   /** Delete a storage group */
-  List<MeasurementMNode> deleteStorageGroup(PartialPath path) throws MetadataException {
+  List<IMeasurementMNode> deleteStorageGroup(PartialPath path) throws MetadataException {
     IMNode cur = getNodeByPath(path);
     if (!(cur instanceof StorageGroupMNode)) {
       throw new StorageGroupNotSetException(path.getFullPath());
@@ -624,14 +626,14 @@
     cur.getParent().deleteChild(cur.getName());
 
     // collect all the LeafMNode in this storage group
-    List<MeasurementMNode> leafMNodes = new LinkedList<>();
+    List<IMeasurementMNode> leafMNodes = new LinkedList<>();
     Queue<IMNode> queue = new LinkedList<>();
     queue.add(cur);
     while (!queue.isEmpty()) {
       IMNode node = queue.poll();
       for (IMNode child : node.getChildren().values()) {
         if (child instanceof MeasurementMNode) {
-          leafMNodes.add((MeasurementMNode) child);
+          leafMNodes.add((IMeasurementMNode) child);
         } else {
           queue.add(child);
         }
@@ -679,7 +681,7 @@
    *
    * @param path Format: root.node(.node)+
    */
-  Pair<PartialPath, MeasurementMNode> deleteTimeseriesAndReturnEmptyStorageGroup(PartialPath path)
+  Pair<PartialPath, IMeasurementMNode> deleteTimeseriesAndReturnEmptyStorageGroup(PartialPath path)
       throws MetadataException {
     IMNode curNode = getNodeByPath(path);
     if (!(curNode instanceof MeasurementMNode)) {
@@ -690,12 +692,12 @@
       throw new IllegalPathException(path.getFullPath());
     }
 
-    MeasurementMNode deletedNode = (MeasurementMNode) curNode;
+    IMeasurementMNode deletedNode = (IMeasurementMNode) curNode;
 
     // delete the last node of path
     curNode.getParent().deleteChild(path.getMeasurement());
     if (deletedNode.getAlias() != null) {
-      curNode.getParent().deleteAliasChild(((MeasurementMNode) curNode).getAlias());
+      curNode.getParent().deleteAliasChild(((IMeasurementMNode) curNode).getAlias());
     }
     curNode = curNode.getParent();
     // delete all empty ancestors except storage group and MeasurementMNode
@@ -716,7 +718,7 @@
    * Get measurement schema for a given path. Path must be a complete Path from root to leaf node.
    */
   IMeasurementSchema getSchema(PartialPath path) throws MetadataException {
-    MeasurementMNode node = (MeasurementMNode) getNodeByPath(path);
+    IMeasurementMNode node = (IMeasurementMNode) getNodeByPath(path);
     return node.getSchema();
   }
 
@@ -762,11 +764,11 @@
    * device], throw exception Get storage group node, if the give path is not a storage group, throw
    * exception
    */
-  StorageGroupMNode getStorageGroupNodeByStorageGroupPath(PartialPath path)
+  IStorageGroupMNode getStorageGroupNodeByStorageGroupPath(PartialPath path)
       throws MetadataException {
     IMNode node = getNodeByPath(path);
     if (node instanceof StorageGroupMNode) {
-      return (StorageGroupMNode) node;
+      return (IStorageGroupMNode) node;
     } else {
       throw new StorageGroupNotSetException(path.getFullPath(), true);
     }
@@ -777,7 +779,7 @@
    * device], return the MNode of root.sg Get storage group node, the give path don't need to be
    * storage group path.
    */
-  StorageGroupMNode getStorageGroupNodeByPath(PartialPath path) throws MetadataException {
+  IStorageGroupMNode getStorageGroupNodeByPath(PartialPath path) throws MetadataException {
     String[] nodes = path.getNodes();
     if (nodes.length == 0 || !nodes[0].equals(root.getName())) {
       throw new IllegalPathException(path.getFullPath());
@@ -789,7 +791,7 @@
       }
       cur = cur.getChild(nodes[i]);
       if (cur instanceof StorageGroupMNode) {
-        return (StorageGroupMNode) cur;
+        return (IStorageGroupMNode) cur;
       }
     }
     throw new StorageGroupNotSetException(path.getFullPath());
@@ -811,7 +813,7 @@
     for (int i = 1; i < nodes.length; i++) {
       if (cur instanceof MeasurementMNode) {
         if (i == nodes.length - 1
-            || ((MeasurementMNode) cur).getSchema() instanceof VectorMeasurementSchema) {
+            || ((IMeasurementMNode) cur).getSchema() instanceof VectorMeasurementSchema) {
           return cur;
         } else {
           throw new PathNotExistException(path.getFullPath(), true);
@@ -985,14 +987,14 @@
   }
 
   /** Get all storage group MNodes */
-  List<StorageGroupMNode> getAllStorageGroupNodes() {
-    List<StorageGroupMNode> ret = new ArrayList<>();
+  List<IStorageGroupMNode> getAllStorageGroupNodes() {
+    List<IStorageGroupMNode> ret = new ArrayList<>();
     Deque<IMNode> nodeStack = new ArrayDeque<>();
     nodeStack.add(root);
     while (!nodeStack.isEmpty()) {
       IMNode current = nodeStack.pop();
       if (current instanceof StorageGroupMNode) {
-        ret.add((StorageGroupMNode) current);
+        ret.add((IStorageGroupMNode) current);
       } else {
         nodeStack.addAll(current.getChildren().values());
       }
@@ -1104,7 +1106,7 @@
       throws PathNotExistException {
     if (node instanceof MeasurementMNode) {
       if (idx < nodes.length) {
-        if (((MeasurementMNode) node).getSchema().isCompatible(nodes[idx])) {
+        if (((IMeasurementMNode) node).getSchema().isCompatible(nodes[idx])) {
           return 1;
         } else {
           if (!wildcard) {
@@ -1114,7 +1116,7 @@
           }
         }
       } else {
-        return ((MeasurementMNode) node).getMeasurementCount();
+        return ((IMeasurementMNode) node).getMeasurementCount();
       }
     }
     if (idx < nodes.length) {
@@ -1345,14 +1347,14 @@
       throws MetadataException {
     if (node instanceof MeasurementMNode) {
       if ((nodes.length <= idx
-          || ((MeasurementMNode) node).getSchema() instanceof VectorMeasurementSchema)) {
+          || ((IMeasurementMNode) node).getSchema() instanceof VectorMeasurementSchema)) {
         if (hasLimit) {
           curOffset.set(curOffset.get() + 1);
           if (curOffset.get() < offset.get() || count.get().intValue() == limit.get().intValue()) {
             return;
           }
         }
-        IMeasurementSchema measurementSchema = ((MeasurementMNode) node).getSchema();
+        IMeasurementSchema measurementSchema = ((IMeasurementMNode) node).getSchema();
         if (measurementSchema instanceof MeasurementSchema) {
           addMeasurementSchema(
               node, timeseriesSchemaList, needLast, queryContext, measurementSchema, "*");
@@ -1457,14 +1459,16 @@
     if (Pattern.matches(reg.replace("*", ".*"), measurementSchema.getMeasurementId())) {
       PartialPath nodePath = node.getPartialPath();
       String[] tsRow = new String[7];
-      tsRow[0] = ((MeasurementMNode) node).getAlias();
+      tsRow[0] = ((IMeasurementMNode) node).getAlias();
       tsRow[1] = getStorageGroupPath(nodePath).getFullPath();
       tsRow[2] = measurementSchema.getType().toString();
       tsRow[3] = measurementSchema.getEncodingType().toString();
       tsRow[4] = measurementSchema.getCompressor().toString();
-      tsRow[5] = String.valueOf(((MeasurementMNode) node).getOffset());
+      tsRow[5] = String.valueOf(((IMeasurementMNode) node).getOffset());
       tsRow[6] =
-          needLast ? String.valueOf(getLastTimeStamp((MeasurementMNode) node, queryContext)) : null;
+          needLast
+              ? String.valueOf(getLastTimeStamp((IMeasurementMNode) node, queryContext))
+              : null;
       Pair<PartialPath, String[]> temp = new Pair<>(nodePath, tsRow);
       timeseriesSchemaList.add(temp);
     }
@@ -1492,7 +1496,9 @@
       tsRow[4] = schema.getCompressor().toString();
       tsRow[5] = "-1";
       tsRow[6] =
-          needLast ? String.valueOf(getLastTimeStamp((MeasurementMNode) node, queryContext)) : null;
+          needLast
+              ? String.valueOf(getLastTimeStamp((IMeasurementMNode) node, queryContext))
+              : null;
       Pair<PartialPath, String[]> temp =
           new Pair<>(new PartialPath(devicePath.getFullPath(), measurements.get(i)), tsRow);
       timeseriesSchemaList.add(temp);
@@ -1523,7 +1529,9 @@
       tsRow[4] = schema.getCompressor().toString();
       tsRow[5] = "-1";
       tsRow[6] =
-          needLast ? String.valueOf(getLastTimeStamp((MeasurementMNode) node, queryContext)) : null;
+          needLast
+              ? String.valueOf(getLastTimeStamp((IMeasurementMNode) node, queryContext))
+              : null;
       Pair<PartialPath, String[]> temp =
           new Pair<>(new PartialPath(devicePath.getFullPath(), measurements.get(i)), tsRow);
       timeseriesSchemaList.add(temp);
@@ -1890,7 +1898,7 @@
             child.setParent(node);
             childrenMap.put(child.getName(), child);
             if (child instanceof MeasurementMNode) {
-              String alias = ((MeasurementMNode) child).getAlias();
+              String alias = ((IMeasurementMNode) child).getAlias();
               if (alias != null) {
                 node.addAlias(alias, child);
               }
@@ -1929,7 +1937,7 @@
         jsonObject.add(child.getName(), mNodeToJSON(child, storageGroupName));
       }
     } else if (node instanceof MeasurementMNode) {
-      MeasurementMNode leafMNode = (MeasurementMNode) node;
+      IMeasurementMNode leafMNode = (IMeasurementMNode) node;
       jsonObject.add("DataType", GSON.toJsonTree(leafMNode.getSchema().getType()));
       jsonObject.add("Encoding", GSON.toJsonTree(leafMNode.getSchema().getEncodingType()));
       jsonObject.add("Compressor", GSON.toJsonTree(leafMNode.getSchema().getCompressor()));
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java b/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java
index 4448399..b0de7cf 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/logfile/MLogWriter.java
@@ -25,8 +25,8 @@
 import org.apache.iotdb.db.metadata.MetadataOperationType;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
-import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.crud.CreateTemplatePlan;
 import org.apache.iotdb.db.qp.physical.crud.SetDeviceTemplatePlan;
@@ -194,7 +194,7 @@
     putLog(plan);
   }
 
-  public void serializeMeasurementMNode(MeasurementMNode node) throws IOException {
+  public void serializeMeasurementMNode(IMeasurementMNode node) throws IOException {
     int childSize = 0;
     if (node.getChildren() != null) {
       childSize = node.getChildren().size();
@@ -205,7 +205,7 @@
     putLog(plan);
   }
 
-  public void serializeStorageGroupMNode(StorageGroupMNode node) throws IOException {
+  public void serializeStorageGroupMNode(IStorageGroupMNode node) throws IOException {
     int childSize = 0;
     if (node.getChildren() != null) {
       childSize = node.getChildren().size();
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMeasurementMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMeasurementMNode.java
new file mode 100644
index 0000000..904f4dd
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IMeasurementMNode.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iotdb.db.metadata.mnode;
+
+import org.apache.iotdb.db.engine.trigger.executor.TriggerExecutor;
+import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
+import org.apache.iotdb.tsfile.read.TimeValuePair;
+import org.apache.iotdb.tsfile.write.schema.IMeasurementSchema;
+
+/** This interface defines a MeasurementMNode's operation interfaces. */
+public interface IMeasurementMNode extends IMNode {
+  int getMeasurementCount();
+
+  IMeasurementSchema getSchema();
+
+  TimeValuePair getCachedLast();
+
+  void updateCachedLast(
+      TimeValuePair timeValuePair, boolean highPriorityUpdate, Long latestFlushedTime);
+
+  void resetCache();
+
+  long getOffset();
+
+  void setOffset(long offset);
+
+  String getAlias();
+
+  TriggerExecutor getTriggerExecutor();
+
+  void setAlias(String alias);
+
+  void setSchema(IMeasurementSchema schema);
+
+  void setTriggerExecutor(TriggerExecutor triggerExecutor);
+
+  TSDataType getDataType(String measurementId);
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IStorageGroupMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IStorageGroupMNode.java
new file mode 100644
index 0000000..131ab2c
--- /dev/null
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/IStorageGroupMNode.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.iotdb.db.metadata.mnode;
+
+/** This interface defines a StorageGroupMNode's operation interfaces. */
+public interface IStorageGroupMNode extends IMNode {
+  long getDataTTL();
+
+  void setDataTTL(long dataTTL);
+}
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/InternalMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/InternalMNode.java
index 89a6ba0..75c6487 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/InternalMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/InternalMNode.java
@@ -37,7 +37,7 @@
  * This class is the implementation of Metadata Node. One MNode instance represents one node in the
  * Metadata Tree
  */
-public class InternalMNode extends MNode implements IMNode {
+public class InternalMNode extends MNode {
 
   private static final long serialVersionUID = -770028375899514063L;
 
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java
index 901e1b9..a833307 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/MeasurementMNode.java
@@ -39,7 +39,7 @@
 import java.util.Map;
 
 /** Represents an MNode which has a Measurement or Sensor attached to it. */
-public class MeasurementMNode extends MNode {
+public class MeasurementMNode extends MNode implements IMeasurementMNode {
 
   private static final Logger logger = LoggerFactory.getLogger(MeasurementMNode.class);
 
@@ -86,14 +86,17 @@
     return 1;
   }
 
+  @Override
   public int getMeasurementCount() {
     return schema.getMeasurementCount();
   }
 
+  @Override
   public IMeasurementSchema getSchema() {
     return schema;
   }
 
+  @Override
   public TimeValuePair getCachedLast() {
     return cachedLastValuePair;
   }
@@ -105,6 +108,7 @@
    * @param highPriorityUpdate whether it's a high priority update
    * @param latestFlushedTime latest flushed time
    */
+  @Override
   public synchronized void updateCachedLast(
       TimeValuePair timeValuePair, boolean highPriorityUpdate, Long latestFlushedTime) {
     if (timeValuePair == null || timeValuePair.getValue() == null) {
@@ -131,34 +135,42 @@
     return concatFullPath();
   }
 
+  @Override
   public void resetCache() {
     cachedLastValuePair = null;
   }
 
+  @Override
   public long getOffset() {
     return offset;
   }
 
+  @Override
   public void setOffset(long offset) {
     this.offset = offset;
   }
 
+  @Override
   public String getAlias() {
     return alias;
   }
 
+  @Override
   public TriggerExecutor getTriggerExecutor() {
     return triggerExecutor;
   }
 
+  @Override
   public void setAlias(String alias) {
     this.alias = alias;
   }
 
+  @Override
   public void setSchema(IMeasurementSchema schema) {
     this.schema = schema;
   }
 
+  @Override
   public void setTriggerExecutor(TriggerExecutor triggerExecutor) {
     this.triggerExecutor = triggerExecutor;
   }
@@ -176,7 +188,7 @@
    *     [3] TSDataType.ordinal() [4] TSEncoding.ordinal() [5] CompressionType.ordinal() [6] props
    *     [7] offset [8] children size
    */
-  public static MeasurementMNode deserializeFrom(String[] nodeInfo) {
+  public static IMeasurementMNode deserializeFrom(String[] nodeInfo) {
     String name = nodeInfo[1];
     String alias = nodeInfo[2].equals("") ? null : nodeInfo[2];
     Map<String, String> props = new HashMap<>();
@@ -192,14 +204,14 @@
             Byte.parseByte(nodeInfo[4]),
             Byte.parseByte(nodeInfo[5]),
             props);
-    MeasurementMNode node = new MeasurementMNode(null, name, schema, alias);
+    IMeasurementMNode node = new MeasurementMNode(null, name, schema, alias);
     node.setOffset(Long.parseLong(nodeInfo[7]));
     return node;
   }
 
   /** deserialize MeasuremetMNode from MeasurementNodePlan */
-  public static MeasurementMNode deserializeFrom(MeasurementMNodePlan plan) {
-    MeasurementMNode node =
+  public static IMeasurementMNode deserializeFrom(MeasurementMNodePlan plan) {
+    IMeasurementMNode node =
         new MeasurementMNode(null, plan.getName(), plan.getSchema(), plan.getAlias());
     node.setOffset(plan.getOffset());
 
@@ -212,6 +224,7 @@
    * @param measurementId if it's a vector schema, we need sensor name of it
    * @return measurement data type
    */
+  @Override
   public TSDataType getDataType(String measurementId) {
     if (schema instanceof MeasurementSchema) {
       return schema.getType();
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/StorageGroupMNode.java b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/StorageGroupMNode.java
index b229427..8acd920 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/mnode/StorageGroupMNode.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/mnode/StorageGroupMNode.java
@@ -23,7 +23,7 @@
 
 import java.io.IOException;
 
-public class StorageGroupMNode extends InternalMNode {
+public class StorageGroupMNode extends InternalMNode implements IStorageGroupMNode {
 
   private static final long serialVersionUID = 7999036474525817732L;
 
@@ -38,10 +38,12 @@
     this.dataTTL = dataTTL;
   }
 
+  @Override
   public long getDataTTL() {
     return dataTTL;
   }
 
+  @Override
   public void setDataTTL(long dataTTL) {
     this.dataTTL = dataTTL;
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/tag/TagManager.java b/server/src/main/java/org/apache/iotdb/db/metadata/tag/TagManager.java
index b621930..6062bd3 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/tag/TagManager.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/tag/TagManager.java
@@ -29,7 +29,7 @@
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.logfile.TagLogFile;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.qp.physical.sys.ShowTimeSeriesPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
 import org.apache.iotdb.db.utils.TestOnly;
@@ -59,7 +59,7 @@
 
   private TagLogFile tagLogFile;
   // tag key -> tag value -> LeafMNode
-  private Map<String, Map<String, Set<MeasurementMNode>>> tagIndex = new ConcurrentHashMap<>();
+  private Map<String, Map<String, Set<IMeasurementMNode>>> tagIndex = new ConcurrentHashMap<>();
 
   private static class TagManagerHolder {
 
@@ -85,14 +85,14 @@
     tagLogFile = new TagLogFile(config.getSchemaDir(), MetadataConstant.TAG_LOG);
   }
 
-  public void addIndex(String tagKey, String tagValue, MeasurementMNode measurementMNode) {
+  public void addIndex(String tagKey, String tagValue, IMeasurementMNode measurementMNode) {
     tagIndex
         .computeIfAbsent(tagKey, k -> new ConcurrentHashMap<>())
         .computeIfAbsent(tagValue, v -> new CopyOnWriteArraySet<>())
         .add(measurementMNode);
   }
 
-  public void addIndex(Map<String, String> tagsMap, MeasurementMNode measurementMNode) {
+  public void addIndex(Map<String, String> tagsMap, IMeasurementMNode measurementMNode) {
     if (tagsMap != null && measurementMNode != null) {
       for (Map.Entry<String, String> entry : tagsMap.entrySet()) {
         addIndex(entry.getKey(), entry.getValue(), measurementMNode);
@@ -100,26 +100,26 @@
     }
   }
 
-  public void removeIndex(String tagKey, String tagValue, MeasurementMNode measurementMNode) {
+  public void removeIndex(String tagKey, String tagValue, IMeasurementMNode measurementMNode) {
     tagIndex.get(tagKey).get(tagValue).remove(measurementMNode);
     if (tagIndex.get(tagKey).get(tagValue).isEmpty()) {
       tagIndex.get(tagKey).remove(tagValue);
     }
   }
 
-  public List<MeasurementMNode> getMatchedTimeseriesInIndex(
+  public List<IMeasurementMNode> getMatchedTimeseriesInIndex(
       ShowTimeSeriesPlan plan, QueryContext context) throws MetadataException {
     if (!tagIndex.containsKey(plan.getKey())) {
       throw new MetadataException("The key " + plan.getKey() + " is not a tag.", true);
     }
-    Map<String, Set<MeasurementMNode>> value2Node = tagIndex.get(plan.getKey());
+    Map<String, Set<IMeasurementMNode>> value2Node = tagIndex.get(plan.getKey());
     if (value2Node.isEmpty()) {
       throw new MetadataException("The key " + plan.getKey() + " is not a tag.");
     }
 
-    List<MeasurementMNode> allMatchedNodes = new ArrayList<>();
+    List<IMeasurementMNode> allMatchedNodes = new ArrayList<>();
     if (plan.isContains()) {
-      for (Map.Entry<String, Set<MeasurementMNode>> entry : value2Node.entrySet()) {
+      for (Map.Entry<String, Set<IMeasurementMNode>> entry : value2Node.entrySet()) {
         if (entry.getKey() == null || entry.getValue() == null) {
           continue;
         }
@@ -129,7 +129,7 @@
         }
       }
     } else {
-      for (Map.Entry<String, Set<MeasurementMNode>> entry : value2Node.entrySet()) {
+      for (Map.Entry<String, Set<IMeasurementMNode>> entry : value2Node.entrySet()) {
         if (entry.getKey() == null || entry.getValue() == null) {
           continue;
         }
@@ -153,7 +153,7 @@
               allMatchedNodes.stream()
                   .sorted(
                       Comparator.comparingLong(
-                              (MeasurementMNode mNode) -> MTree.getLastTimeStamp(mNode, context))
+                              (IMeasurementMNode mNode) -> MTree.getLastTimeStamp(mNode, context))
                           .reversed()
                           .thenComparing(IMNode::getFullPath))
                   .collect(toList());
@@ -175,7 +175,7 @@
   }
 
   /** remove the node from the tag inverted index */
-  public void removeFromTagInvertedIndex(MeasurementMNode node) throws IOException {
+  public void removeFromTagInvertedIndex(IMeasurementMNode node) throws IOException {
     if (node.getOffset() < 0) {
       return;
     }
@@ -220,7 +220,7 @@
    * new value to update it.
    */
   public void updateTagsAndAttributes(
-      Map<String, String> tagsMap, Map<String, String> attributesMap, MeasurementMNode leafMNode)
+      Map<String, String> tagsMap, Map<String, String> attributesMap, IMeasurementMNode leafMNode)
       throws MetadataException, IOException {
 
     Pair<Map<String, String>, Map<String, String>> pair =
@@ -283,7 +283,7 @@
    * @param attributesMap newly added attributes map
    */
   public void addAttributes(
-      Map<String, String> attributesMap, PartialPath fullPath, MeasurementMNode leafMNode)
+      Map<String, String> attributesMap, PartialPath fullPath, IMeasurementMNode leafMNode)
       throws MetadataException, IOException {
 
     Pair<Map<String, String>, Map<String, String>> pair =
@@ -309,7 +309,8 @@
    * @param tagsMap newly added tags map
    * @param fullPath timeseries
    */
-  public void addTags(Map<String, String> tagsMap, PartialPath fullPath, MeasurementMNode leafMNode)
+  public void addTags(
+      Map<String, String> tagsMap, PartialPath fullPath, IMeasurementMNode leafMNode)
       throws MetadataException, IOException {
 
     Pair<Map<String, String>, Map<String, String>> pair =
@@ -338,7 +339,7 @@
    * @param keySet tags key or attributes key
    */
   public void dropTagsOrAttributes(
-      Set<String> keySet, PartialPath fullPath, MeasurementMNode leafMNode)
+      Set<String> keySet, PartialPath fullPath, IMeasurementMNode leafMNode)
       throws MetadataException, IOException {
     Pair<Map<String, String>, Map<String, String>> pair =
         tagLogFile.read(config.getTagAttributeTotalSize(), leafMNode.getOffset());
@@ -361,8 +362,8 @@
     // persist the change to disk
     tagLogFile.write(pair.left, pair.right, leafMNode.getOffset());
 
-    Map<String, Set<MeasurementMNode>> tagVal2LeafMNodeSet;
-    Set<MeasurementMNode> MMNodes;
+    Map<String, Set<IMeasurementMNode>> tagVal2LeafMNodeSet;
+    Set<IMeasurementMNode> MMNodes;
     for (Map.Entry<String, String> entry : deleteTag.entrySet()) {
       String key = entry.getKey();
       String value = entry.getValue();
@@ -408,7 +409,7 @@
    * @param alterMap the new tags or attributes key-value
    */
   public void setTagsOrAttributesValue(
-      Map<String, String> alterMap, PartialPath fullPath, MeasurementMNode leafMNode)
+      Map<String, String> alterMap, PartialPath fullPath, IMeasurementMNode leafMNode)
       throws MetadataException, IOException {
     // tags, attributes
     Pair<Map<String, String>, Map<String, String>> pair =
@@ -476,7 +477,7 @@
    * @param newKey new key of tag or attribute
    */
   public void renameTagOrAttributeKey(
-      String oldKey, String newKey, PartialPath fullPath, MeasurementMNode leafMNode)
+      String oldKey, String newKey, PartialPath fullPath, IMeasurementMNode leafMNode)
       throws MetadataException, IOException {
     // tags, attributes
     Pair<Map<String, String>, Map<String, String>> pair =
diff --git a/server/src/main/java/org/apache/iotdb/db/metadata/template/Template.java b/server/src/main/java/org/apache/iotdb/db/metadata/template/Template.java
index 1612483..5b769da 100644
--- a/server/src/main/java/org/apache/iotdb/db/metadata/template/Template.java
+++ b/server/src/main/java/org/apache/iotdb/db/metadata/template/Template.java
@@ -19,6 +19,7 @@
 package org.apache.iotdb.db.metadata.template;
 
 import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
 import org.apache.iotdb.db.qp.physical.crud.CreateTemplatePlan;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -124,13 +125,13 @@
     return schemaMap.containsKey(measurementId);
   }
 
-  public List<MeasurementMNode> getMeasurementMNode() {
+  public List<IMeasurementMNode> getMeasurementMNode() {
     Set<IMeasurementSchema> deduplicateSchema = new HashSet<>();
-    List<MeasurementMNode> res = new ArrayList<>();
+    List<IMeasurementMNode> res = new ArrayList<>();
 
     for (IMeasurementSchema measurementSchema : schemaMap.values()) {
       if (deduplicateSchema.add(measurementSchema)) {
-        MeasurementMNode measurementMNode = null;
+        IMeasurementMNode measurementMNode = null;
         if (measurementSchema instanceof MeasurementSchema) {
           measurementMNode =
               new MeasurementMNode(
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
index b778a49..df47b6c 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/executor/PlanExecutor.java
@@ -51,8 +51,9 @@
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
-import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
 import org.apache.iotdb.db.monitor.StatMonitor;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.qp.logical.Operator.OperatorType;
@@ -840,7 +841,7 @@
     return new ShowTimeseriesDataSet(showTimeSeriesPlan, context);
   }
 
-  protected List<StorageGroupMNode> getAllStorageGroupNodes() {
+  protected List<IStorageGroupMNode> getAllStorageGroupNodes() {
     return IoTDB.metaManager.getAllStorageGroupNodes();
   }
 
@@ -852,9 +853,9 @@
             Arrays.asList(TSDataType.TEXT, TSDataType.INT64));
     List<PartialPath> selectedSgs = showTTLPlan.getStorageGroups();
 
-    List<StorageGroupMNode> storageGroups = getAllStorageGroupNodes();
+    List<IStorageGroupMNode> storageGroups = getAllStorageGroupNodes();
     int timestamp = 0;
-    for (StorageGroupMNode mNode : storageGroups) {
+    for (IStorageGroupMNode mNode : storageGroups) {
       PartialPath sgName = mNode.getPartialPath();
       if (!selectedSgs.isEmpty() && !selectedSgs.contains(sgName)) {
         continue;
@@ -1323,7 +1324,7 @@
     }
     try {
       for (InsertRowPlan plan : insertRowsOfOneDevicePlan.getRowPlans()) {
-        plan.setMeasurementMNodes(new MeasurementMNode[plan.getMeasurements().length]);
+        plan.setMeasurementMNodes(new IMeasurementMNode[plan.getMeasurements().length]);
         // check whether types are match
         getSeriesSchemas(plan);
         // we do not need to infer data type for insertRowsOfOneDevicePlan
@@ -1402,7 +1403,7 @@
   public void insert(InsertRowPlan insertRowPlan) throws QueryProcessException {
     try {
       insertRowPlan.setMeasurementMNodes(
-          new MeasurementMNode[insertRowPlan.getMeasurements().length]);
+          new IMeasurementMNode[insertRowPlan.getMeasurements().length]);
       // When insert data with sql statement, the data types will be null here.
       // We need to predicted the data types first
       if (insertRowPlan.getDataTypes()[0] == null) {
@@ -1456,7 +1457,7 @@
     }
     try {
       insertTabletPlan.setMeasurementMNodes(
-          new MeasurementMNode[insertTabletPlan.getMeasurements().length]);
+          new IMeasurementMNode[insertTabletPlan.getMeasurements().length]);
       getSeriesSchemas(insertTabletPlan);
       if (insertTabletPlan.isAligned()) {
         insertTabletPlan.setPrefixPath(insertTabletPlan.getPrefixPath().getDevicePath());
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertPlan.java
index 6da9b2e..bca9209 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertPlan.java
@@ -21,7 +21,7 @@
 
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -39,7 +39,7 @@
   // get from client
   protected TSDataType[] dataTypes;
   // get from MManager
-  protected MeasurementMNode[] measurementMNodes;
+  protected IMeasurementMNode[] measurementMNodes;
 
   // record the failed measurements, their reasons, and positions in "measurements"
   List<String> failedMeasurements;
@@ -83,11 +83,11 @@
     this.dataTypes = dataTypes;
   }
 
-  public MeasurementMNode[] getMeasurementMNodes() {
+  public IMeasurementMNode[] getMeasurementMNodes() {
     return measurementMNodes;
   }
 
-  public void setMeasurementMNodes(MeasurementMNode[] mNodes) {
+  public void setMeasurementMNodes(IMeasurementMNode[] mNodes) {
     this.measurementMNodes = mNodes;
   }
 
@@ -166,8 +166,8 @@
       }
     }
     if (measurementMNodes != null) {
-      MeasurementMNode[] temp = measurementMNodes.clone();
-      measurementMNodes = new MeasurementMNode[failedIndices.size()];
+      IMeasurementMNode[] temp = measurementMNodes.clone();
+      measurementMNodes = new IMeasurementMNode[failedIndices.size()];
       for (int i = 0; i < failedIndices.size(); i++) {
         measurementMNodes[i] = temp[failedIndices.get(i)];
       }
diff --git a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java
index 6990fec..d201ae7 100644
--- a/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java
+++ b/server/src/main/java/org/apache/iotdb/db/qp/physical/crud/InsertRowPlan.java
@@ -24,6 +24,7 @@
 import org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
 import org.apache.iotdb.db.qp.logical.Operator;
 import org.apache.iotdb.db.qp.logical.Operator.OperatorType;
@@ -198,7 +199,7 @@
     this.prefixPath = new PartialPath(tsRecord.deviceId);
     this.time = tsRecord.time;
     this.measurements = new String[tsRecord.dataPointList.size()];
-    this.measurementMNodes = new MeasurementMNode[tsRecord.dataPointList.size()];
+    this.measurementMNodes = new IMeasurementMNode[tsRecord.dataPointList.size()];
     this.dataTypes = new TSDataType[tsRecord.dataPointList.size()];
     this.values = new Object[tsRecord.dataPointList.size()];
     for (int i = 0; i < tsRecord.dataPointList.size(); i++) {
diff --git a/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java b/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java
index 6748c51..73dba0f 100644
--- a/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java
+++ b/server/src/main/java/org/apache/iotdb/db/query/executor/LastQueryExecutor.java
@@ -27,7 +27,7 @@
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.qp.physical.crud.LastQueryPlan;
 import org.apache.iotdb.db.qp.physical.crud.RawDataQueryPlan;
 import org.apache.iotdb.db.query.context.QueryContext;
@@ -253,7 +253,7 @@
 
   private static class LastCacheAccessor {
     private PartialPath path;
-    private MeasurementMNode node;
+    private IMeasurementMNode node;
 
     LastCacheAccessor(PartialPath seriesPath) {
       this.path = seriesPath;
@@ -261,7 +261,7 @@
 
     public TimeValuePair read() {
       try {
-        node = (MeasurementMNode) IoTDB.metaManager.getNodeByPath(path);
+        node = (IMeasurementMNode) IoTDB.metaManager.getNodeByPath(path);
       } catch (MetadataException e) {
         TimeValuePair timeValuePair = IoTDB.metaManager.getLastCache(path);
         if (timeValuePair != null) {
diff --git a/server/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java b/server/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
index e071504..0043a69 100644
--- a/server/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
+++ b/server/src/main/java/org/apache/iotdb/db/utils/SchemaUtils.java
@@ -24,6 +24,7 @@
 import org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
 import org.apache.iotdb.db.qp.constant.SQLConstant;
 import org.apache.iotdb.db.service.IoTDB;
@@ -119,7 +120,7 @@
     IMeasurementSchema measurementSchema =
         new MeasurementSchema(path.getMeasurement(), dataType, encoding, compressionType);
 
-    MeasurementMNode measurementMNode =
+    IMeasurementMNode measurementMNode =
         new MeasurementMNode(null, path.getMeasurement(), measurementSchema, null);
     IoTDB.metaManager.cacheMeta(path, measurementMNode, true);
   }
diff --git a/server/src/main/java/org/apache/iotdb/db/writelog/recover/LogReplayer.java b/server/src/main/java/org/apache/iotdb/db/writelog/recover/LogReplayer.java
index 52fbd1f..61d7692 100644
--- a/server/src/main/java/org/apache/iotdb/db/writelog/recover/LogReplayer.java
+++ b/server/src/main/java/org/apache/iotdb/db/writelog/recover/LogReplayer.java
@@ -30,7 +30,7 @@
 import org.apache.iotdb.db.exception.metadata.PathNotExistException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.qp.physical.PhysicalPlan;
 import org.apache.iotdb.db.qp.physical.crud.DeletePlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertPlan;
@@ -169,7 +169,7 @@
         tempEndTimeMap.put(plan.getPrefixPath().getFullPath(), maxTime);
       }
     }
-    MeasurementMNode[] mNodes;
+    IMeasurementMNode[] mNodes;
     try {
       mNodes = IoTDB.metaManager.getMNodes(plan.getPrefixPath(), plan.getMeasurements());
     } catch (MetadataException e) {
@@ -187,7 +187,7 @@
     }
   }
 
-  private void checkDataTypeAndMarkFailed(final MeasurementMNode[] mNodes, InsertPlan tPlan) {
+  private void checkDataTypeAndMarkFailed(final IMeasurementMNode[] mNodes, InsertPlan tPlan) {
     int columnIndex = 0;
     for (int i = 0; i < mNodes.length; i++) {
       if (mNodes[i] == null) {
diff --git a/server/src/test/java/org/apache/iotdb/db/engine/memtable/MemTableTestUtils.java b/server/src/test/java/org/apache/iotdb/db/engine/memtable/MemTableTestUtils.java
index 2c3777b..861305f 100644
--- a/server/src/test/java/org/apache/iotdb/db/engine/memtable/MemTableTestUtils.java
+++ b/server/src/test/java/org/apache/iotdb/db/engine/memtable/MemTableTestUtils.java
@@ -20,6 +20,7 @@
 
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
 import org.apache.iotdb.db.qp.physical.crud.InsertTabletPlan;
 import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
@@ -85,7 +86,7 @@
     encodings[0] = TSEncoding.PLAIN;
     encodings[1] = TSEncoding.GORILLA;
 
-    MeasurementMNode[] mNodes = new MeasurementMNode[2];
+    IMeasurementMNode[] mNodes = new IMeasurementMNode[2];
     IMeasurementSchema schema =
         new VectorMeasurementSchema("vectorName", measurements, dataTypes, encodings);
     mNodes[0] = new MeasurementMNode(null, "sensor0", schema, null);
diff --git a/server/src/test/java/org/apache/iotdb/db/engine/memtable/PrimitiveMemTableTest.java b/server/src/test/java/org/apache/iotdb/db/engine/memtable/PrimitiveMemTableTest.java
index 9de28d8..1d30d62 100644
--- a/server/src/test/java/org/apache/iotdb/db/engine/memtable/PrimitiveMemTableTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/engine/memtable/PrimitiveMemTableTest.java
@@ -23,6 +23,7 @@
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
 import org.apache.iotdb.db.qp.physical.crud.InsertTabletPlan;
 import org.apache.iotdb.db.utils.MathUtils;
@@ -320,7 +321,7 @@
 
     String deviceId = "root.sg.device5";
 
-    MeasurementMNode[] mNodes = new MeasurementMNode[2];
+    IMeasurementMNode[] mNodes = new IMeasurementMNode[2];
     IMeasurementSchema schema =
         new VectorMeasurementSchema("$#$0", measurements, dataTypes, encodings);
     mNodes[0] = new MeasurementMNode(null, "sensor0", schema, null);
diff --git a/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessorTest.java b/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessorTest.java
index 31ecaef..910d097 100644
--- a/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessorTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/StorageGroupProcessorTest.java
@@ -35,6 +35,7 @@
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertTabletPlan;
@@ -219,7 +220,7 @@
     dataTypes.add(TSDataType.INT32.ordinal());
     dataTypes.add(TSDataType.INT64.ordinal());
 
-    MeasurementMNode[] measurementMNodes = new MeasurementMNode[2];
+    IMeasurementMNode[] measurementMNodes = new IMeasurementMNode[2];
     measurementMNodes[0] =
         new MeasurementMNode(
             null, "s0", new MeasurementSchema("s0", TSDataType.INT32, TSEncoding.PLAIN), null);
@@ -367,7 +368,7 @@
     dataTypes.add(TSDataType.INT32.ordinal());
     dataTypes.add(TSDataType.INT64.ordinal());
 
-    MeasurementMNode[] measurementMNodes = new MeasurementMNode[2];
+    IMeasurementMNode[] measurementMNodes = new IMeasurementMNode[2];
     measurementMNodes[0] =
         new MeasurementMNode(
             null, "s0", new MeasurementSchema("s0", TSDataType.INT32, TSEncoding.PLAIN), null);
@@ -448,7 +449,7 @@
     dataTypes.add(TSDataType.INT32.ordinal());
     dataTypes.add(TSDataType.INT64.ordinal());
 
-    MeasurementMNode[] measurementMNodes = new MeasurementMNode[2];
+    IMeasurementMNode[] measurementMNodes = new IMeasurementMNode[2];
     measurementMNodes[0] =
         new MeasurementMNode(
             null, "s0", new MeasurementSchema("s0", TSDataType.INT32, TSEncoding.PLAIN), null);
@@ -529,7 +530,7 @@
     dataTypes.add(TSDataType.INT32.ordinal());
     dataTypes.add(TSDataType.INT64.ordinal());
 
-    MeasurementMNode[] measurementMNodes = new MeasurementMNode[2];
+    IMeasurementMNode[] measurementMNodes = new IMeasurementMNode[2];
     measurementMNodes[0] =
         new MeasurementMNode(
             null, "s0", new MeasurementSchema("s0", TSDataType.INT32, TSEncoding.PLAIN), null);
diff --git a/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/TTLTest.java b/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/TTLTest.java
index db4f812..71db7cb 100644
--- a/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/TTLTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/engine/storagegroup/TTLTest.java
@@ -34,8 +34,9 @@
 import org.apache.iotdb.db.exception.query.OutOfTTLException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IStorageGroupMNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
-import org.apache.iotdb.db.metadata.mnode.StorageGroupMNode;
 import org.apache.iotdb.db.qp.Planner;
 import org.apache.iotdb.db.qp.executor.PlanExecutor;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
@@ -139,7 +140,7 @@
 
     // normally set ttl
     IoTDB.metaManager.setTTL(new PartialPath(sg1), ttl);
-    StorageGroupMNode mNode =
+    IStorageGroupMNode mNode =
         IoTDB.metaManager.getStorageGroupNodeByStorageGroupPath(new PartialPath(sg1));
     assertEquals(ttl, mNode.getDataTTL());
 
@@ -159,7 +160,7 @@
     plan.setDataTypes(new TSDataType[] {TSDataType.INT64});
     plan.setValues(new Object[] {1L});
     plan.setMeasurementMNodes(
-        new MeasurementMNode[] {
+        new IMeasurementMNode[] {
           new MeasurementMNode(
               null, null, new MeasurementSchema("s1", TSDataType.INT64, TSEncoding.PLAIN), null)
         });
@@ -192,7 +193,7 @@
     plan.setDataTypes(new TSDataType[] {TSDataType.INT64});
     plan.setValues(new Object[] {1L});
     plan.setMeasurementMNodes(
-        new MeasurementMNode[] {
+        new IMeasurementMNode[] {
           new MeasurementMNode(
               null, null, new MeasurementSchema("s1", TSDataType.INT64, TSEncoding.PLAIN), null)
         });
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBLastIT.java b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBLastIT.java
index 3dabe36..e854069 100644
--- a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBLastIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBLastIT.java
@@ -21,7 +21,7 @@
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.metadata.PartialPath;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 import org.apache.iotdb.jdbc.Config;
@@ -215,8 +215,8 @@
         }
       }
 
-      MeasurementMNode node =
-          (MeasurementMNode)
+      IMeasurementMNode node =
+          (IMeasurementMNode)
               IoTDB.metaManager.getNodeByPath(new PartialPath("root.ln.wf01.wt01.temperature"));
       node.resetCache();
 
@@ -285,7 +285,7 @@
 
       IMNode node =
           IoTDB.metaManager.getNodeByPath(new PartialPath("root.ln.wf01.wt02.temperature"));
-      ((MeasurementMNode) node).resetCache();
+      ((IMeasurementMNode) node).resetCache();
       boolean hasResultSet =
           statement.execute("select last temperature,status,id from root.ln.wf01.wt02");
 
@@ -325,7 +325,7 @@
       }
       Assert.assertEquals(cnt, retArray.length);
 
-      ((MeasurementMNode) node).resetCache();
+      ((IMeasurementMNode) node).resetCache();
       String[] retArray3 =
           new String[] {
             "900,root.ln.wf01.wt01.temperature,10.2",
@@ -369,7 +369,7 @@
 
       IMNode node =
           IoTDB.metaManager.getNodeByPath(new PartialPath("root.ln.wf01.wt03.temperature"));
-      ((MeasurementMNode) node).resetCache();
+      ((IMeasurementMNode) node).resetCache();
 
       statement.execute(
           "INSERT INTO root.ln.wf01.wt03(timestamp,status, id) values(500, false, 9)");
@@ -418,7 +418,7 @@
 
       IMNode node =
           IoTDB.metaManager.getNodeByPath(new PartialPath("root.ln.wf01.wt04.temperature"));
-      ((MeasurementMNode) node).resetCache();
+      ((IMeasurementMNode) node).resetCache();
 
       boolean hasResultSet = statement.execute("select last temperature from root.ln.wf01.wt04");
 
diff --git a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBSimpleQueryIT.java b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBSimpleQueryIT.java
index 9477f64..f6402fb 100644
--- a/server/src/test/java/org/apache/iotdb/db/integration/IoTDBSimpleQueryIT.java
+++ b/server/src/test/java/org/apache/iotdb/db/integration/IoTDBSimpleQueryIT.java
@@ -22,7 +22,7 @@
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.metadata.MManager;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 import org.apache.iotdb.jdbc.Config;
 import org.apache.iotdb.jdbc.IoTDBSQLException;
@@ -81,8 +81,8 @@
       e.printStackTrace();
     }
 
-    MeasurementMNode mNode =
-        (MeasurementMNode) MManager.getInstance().getNodeByPath(new PartialPath("root.sg1.d0.s1"));
+    IMeasurementMNode mNode =
+        (IMeasurementMNode) MManager.getInstance().getNodeByPath(new PartialPath("root.sg1.d0.s1"));
     assertNull(mNode.getSchema().getProps());
   }
 
@@ -102,8 +102,8 @@
       e.printStackTrace();
     }
 
-    MeasurementMNode mNode =
-        (MeasurementMNode) MManager.getInstance().getNodeByPath(new PartialPath("root.sg1.d0.s1"));
+    IMeasurementMNode mNode =
+        (IMeasurementMNode) MManager.getInstance().getNodeByPath(new PartialPath("root.sg1.d0.s1"));
 
     // check if SDT property is set
     assertEquals(2, mNode.getSchema().getProps().size());
@@ -127,8 +127,8 @@
       e.printStackTrace();
     }
 
-    MeasurementMNode mNode =
-        (MeasurementMNode) MManager.getInstance().getNodeByPath(new PartialPath("root.sg1.d0.s1"));
+    IMeasurementMNode mNode =
+        (IMeasurementMNode) MManager.getInstance().getNodeByPath(new PartialPath("root.sg1.d0.s1"));
 
     // check if SDT property is set
     assertEquals(4, mNode.getSchema().getProps().size());
diff --git a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerAdvancedTest.java b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerAdvancedTest.java
index 0f6bb41..21e3c01 100644
--- a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerAdvancedTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerAdvancedTest.java
@@ -20,7 +20,7 @@
 
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
@@ -197,7 +197,7 @@
 
     IMNode node = mmanager.getNodeByPath(new PartialPath("root.vehicle.d0"));
     Assert.assertEquals(
-        TSDataType.INT32, ((MeasurementMNode) node.getChild("s0")).getSchema().getType());
+        TSDataType.INT32, ((IMeasurementMNode) node.getChild("s0")).getSchema().getType());
 
     try {
       mmanager.getNodeByPath(new PartialPath("root.vehicle.d100"));
@@ -219,12 +219,12 @@
     TimeValuePair tv2 = new TimeValuePair(2000, TsPrimitiveType.getByType(TSDataType.DOUBLE, 3.0));
     TimeValuePair tv3 = new TimeValuePair(1500, TsPrimitiveType.getByType(TSDataType.DOUBLE, 2.5));
     IMNode node = mmanager.getNodeByPath(new PartialPath("root.vehicle.d2.s0"));
-    ((MeasurementMNode) node).updateCachedLast(tv1, true, Long.MIN_VALUE);
-    ((MeasurementMNode) node).updateCachedLast(tv2, true, Long.MIN_VALUE);
+    ((IMeasurementMNode) node).updateCachedLast(tv1, true, Long.MIN_VALUE);
+    ((IMeasurementMNode) node).updateCachedLast(tv2, true, Long.MIN_VALUE);
     Assert.assertEquals(
-        tv2.getTimestamp(), ((MeasurementMNode) node).getCachedLast().getTimestamp());
-    ((MeasurementMNode) node).updateCachedLast(tv3, true, Long.MIN_VALUE);
+        tv2.getTimestamp(), ((IMeasurementMNode) node).getCachedLast().getTimestamp());
+    ((IMeasurementMNode) node).updateCachedLast(tv3, true, Long.MIN_VALUE);
     Assert.assertEquals(
-        tv2.getTimestamp(), ((MeasurementMNode) node).getCachedLast().getTimestamp());
+        tv2.getTimestamp(), ((IMeasurementMNode) node).getCachedLast().getTimestamp());
   }
 }
diff --git a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java
index 00632f5..74c3032 100644
--- a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerBasicTest.java
@@ -24,7 +24,7 @@
 import org.apache.iotdb.db.exception.metadata.PathAlreadyExistException;
 import org.apache.iotdb.db.exception.metadata.StorageGroupNotSetException;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.metadata.template.Template;
 import org.apache.iotdb.db.qp.physical.crud.CreateTemplatePlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
@@ -878,7 +878,7 @@
 
     assertTrue(allSchema.isEmpty());
 
-    MeasurementMNode[] mNodes =
+    IMeasurementMNode[] mNodes =
         manager.getMNodes(new PartialPath("root.sg1.d1"), new String[] {"s11"});
     assertNotNull(mNodes[0]);
     assertEquals(mNodes[0].getSchema(), s11);
@@ -1550,7 +1550,7 @@
               columns,
               true);
       insertRowPlan.setMeasurementMNodes(
-          new MeasurementMNode[insertRowPlan.getMeasurements().length]);
+          new IMeasurementMNode[insertRowPlan.getMeasurements().length]);
 
       // call getSeriesSchemasAndReadLockDevice
       IMNode IMNode = manager.getSeriesSchemasAndReadLockDevice(insertRowPlan);
@@ -1602,7 +1602,7 @@
               columns,
               false);
       insertRowPlan.setMeasurementMNodes(
-          new MeasurementMNode[insertRowPlan.getMeasurements().length]);
+          new IMeasurementMNode[insertRowPlan.getMeasurements().length]);
 
       // call getSeriesSchemasAndReadLockDevice
       manager.getSeriesSchemasAndReadLockDevice(insertRowPlan);
@@ -1637,7 +1637,7 @@
           new InsertRowPlan(
               new PartialPath("root.laptop.d1"), time, new String[] {"s0"}, dataTypes, columns);
       insertRowPlan.setMeasurementMNodes(
-          new MeasurementMNode[insertRowPlan.getMeasurements().length]);
+          new IMeasurementMNode[insertRowPlan.getMeasurements().length]);
 
       // call getSeriesSchemasAndReadLockDevice
       IMNode IMNode = manager.getSeriesSchemasAndReadLockDevice(insertRowPlan);
@@ -1686,7 +1686,7 @@
               columns,
               true);
       insertRowPlan.setMeasurementMNodes(
-          new MeasurementMNode[insertRowPlan.getMeasurements().length]);
+          new IMeasurementMNode[insertRowPlan.getMeasurements().length]);
 
       // call getSeriesSchemasAndReadLockDevice
       manager.getSeriesSchemasAndReadLockDevice(insertRowPlan);
diff --git a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerImproveTest.java b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerImproveTest.java
index effcb24..40b22fb 100644
--- a/server/src/test/java/org/apache/iotdb/db/metadata/MManagerImproveTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/metadata/MManagerImproveTest.java
@@ -21,7 +21,7 @@
 import org.apache.iotdb.db.exception.metadata.IllegalPathException;
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.metadata.mnode.IMNode;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.service.IoTDB;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 import org.apache.iotdb.tsfile.common.conf.TSFileDescriptor;
@@ -141,7 +141,7 @@
       IMNode node = mManager.getDeviceNodeWithAutoCreate(new PartialPath(deviceId)).left;
       for (String s : measurementList) {
         assertTrue(node.hasChild(s));
-        MeasurementMNode measurementNode = (MeasurementMNode) node.getChild(s);
+        IMeasurementMNode measurementNode = (IMeasurementMNode) node.getChild(s);
         TSDataType dataType = measurementNode.getSchema().getType();
         assertEquals(TSDataType.TEXT, dataType);
       }
diff --git a/server/src/test/java/org/apache/iotdb/db/writelog/recover/LogReplayerTest.java b/server/src/test/java/org/apache/iotdb/db/writelog/recover/LogReplayerTest.java
index 5dcb1b7..6a8a307 100644
--- a/server/src/test/java/org/apache/iotdb/db/writelog/recover/LogReplayerTest.java
+++ b/server/src/test/java/org/apache/iotdb/db/writelog/recover/LogReplayerTest.java
@@ -34,6 +34,7 @@
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.exception.query.QueryProcessException;
 import org.apache.iotdb.db.metadata.PartialPath;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
 import org.apache.iotdb.db.qp.physical.crud.DeletePlan;
 import org.apache.iotdb.db.qp.physical.crud.InsertRowPlan;
@@ -260,7 +261,7 @@
 
     String deviceId = "root.sg.device5";
 
-    MeasurementMNode[] mNodes = new MeasurementMNode[2];
+    IMeasurementMNode[] mNodes = new IMeasurementMNode[2];
     mNodes[0] = new MeasurementMNode(null, "sensor0", null, null);
     mNodes[1] = new MeasurementMNode(null, "sensor1", null, null);
 
diff --git a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionSimpleIT.java b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionSimpleIT.java
index 15bd740..c8e098f 100644
--- a/session/src/test/java/org/apache/iotdb/session/IoTDBSessionSimpleIT.java
+++ b/session/src/test/java/org/apache/iotdb/session/IoTDBSessionSimpleIT.java
@@ -23,7 +23,7 @@
 import org.apache.iotdb.db.exception.metadata.MetadataException;
 import org.apache.iotdb.db.metadata.MManager;
 import org.apache.iotdb.db.metadata.PartialPath;
-import org.apache.iotdb.db.metadata.mnode.MeasurementMNode;
+import org.apache.iotdb.db.metadata.mnode.IMeasurementMNode;
 import org.apache.iotdb.db.utils.EnvironmentUtils;
 import org.apache.iotdb.rpc.BatchExecutionException;
 import org.apache.iotdb.rpc.IoTDBConnectionException;
@@ -320,8 +320,8 @@
 
     assertTrue(session.checkTimeseriesExists("root.sg1.d1.s1"));
     assertTrue(session.checkTimeseriesExists("root.sg1.d1.s2"));
-    MeasurementMNode mNode =
-        (MeasurementMNode) MManager.getInstance().getNodeByPath(new PartialPath("root.sg1.d1.s1"));
+    IMeasurementMNode mNode =
+        (IMeasurementMNode) MManager.getInstance().getNodeByPath(new PartialPath("root.sg1.d1.s1"));
     assertNull(mNode.getSchema().getProps());
 
     session.close();
diff --git a/testcontainer/src/test/java/org/apache/iotdb/db/sql/Cases.java b/testcontainer/src/test/java/org/apache/iotdb/db/sql/Cases.java
index 2a2fd27..4b450cd 100644
--- a/testcontainer/src/test/java/org/apache/iotdb/db/sql/Cases.java
+++ b/testcontainer/src/test/java/org/apache/iotdb/db/sql/Cases.java
@@ -83,10 +83,17 @@
     String[] timeSeriesArray = {"root.sg1.aa.bb", "root.sg1.aa.bb.cc", "root.sg1.aa"};
 
     for (String timeSeries : timeSeriesArray) {
-      writeStatement.execute(
-          String.format(
-              "create timeseries %s with datatype=INT64, encoding=PLAIN, compression=SNAPPY",
-              timeSeries));
+      try {
+        writeStatement.execute(
+            String.format(
+                "create timeseries %s with datatype=INT64, encoding=PLAIN, compression=SNAPPY",
+                timeSeries));
+      } catch (Exception e) {
+        if (timeSeries.equals("root.sg1.aa.bb")) {
+          e.printStackTrace();
+          fail();
+        }
+      }
     }
     ResultSet resultSet = null;
     // try to read data on each node.
@@ -96,10 +103,10 @@
       while (resultSet.next()) {
         result.add(resultSet.getString(1));
       }
-      Assert.assertEquals(3, result.size());
-      for (String timeseries : timeSeriesArray) {
-        Assert.assertTrue(result.contains(timeseries));
-      }
+      Assert.assertEquals(1, result.size());
+      Assert.assertTrue(result.contains("root.sg1.aa.bb"));
+      Assert.assertFalse(result.contains("root.sg1.aa.bb.cc"));
+      Assert.assertFalse(result.contains("root.sg1.aa"));
       resultSet.close();
     }