You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2022/12/24 04:35:00 UTC

[shardingsphere] branch master updated: Add ModeContextManager interface and split ClusterModeContextManager and StandaloneModeContextManager (#23061)

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

duanzhengqiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 34a5db9f951 Add ModeContextManager interface and split ClusterModeContextManager and StandaloneModeContextManager (#23061)
34a5db9f951 is described below

commit 34a5db9f95120e900a86c01ad7d66bbbb7f98d00
Author: zhaojinchao <zh...@apache.org>
AuthorDate: Sat Dec 24 12:34:53 2022 +0800

    Add ModeContextManager interface and split ClusterModeContextManager and StandaloneModeContextManager (#23061)
    
    * Add ModeContextManager and split ClusterModeContextManager and StandaloneModeContextManager
    
    * Refactor alterRuleConfiguration logic
    
    * Fix checkstyle
    
    * Fix checkstyle
    
    * Fix it
    
    * Fix unit test
    
    * Add synchronized
    
    * Fix checkstyle
---
 .../PrometheusPluginBootServiceTest.java           |   5 +-
 .../collector/ProxyInfoCollectorTest.java          |   5 +-
 .../keygen/SnowflakeKeyGenerateAlgorithmTest.java  |   5 +-
 .../checker/ShardingRouteCacheableCheckerTest.java |   2 +-
 .../CosIdSnowflakeKeyGenerateAlgorithmTest.java    |  11 +-
 .../infra/instance/InstanceContext.java            |   3 +
 .../infra/instance/mode/ModeContextManager.java    |  94 +++++++++
 .../infra/instance/InstanceContextTest.java        |  23 ++-
 .../builder/global/GlobalRulesBuilderTest.java     |   3 +-
 .../rule/builder/TransactionRuleBuilderTest.java   |   5 +-
 .../mode/manager/ContextManager.java               | 214 ++++++++-------------
 .../mode/manager/ContextManagerAware.java          |  31 +++
 .../mode/manager/ContextManagerTest.java           |  73 +------
 .../cluster/ClusterContextManagerBuilder.java      |  11 +-
 .../manager/cluster/ClusterModeContextManager.java |  89 +++++++++
 .../StandaloneContextManagerBuilder.java           |  10 +-
 .../standalone/StandaloneModeContextManager.java   | 131 +++++++++++++
 .../database/CreateDatabaseBackendHandler.java     |   2 +-
 .../database/DropDatabaseBackendHandler.java       |   2 +-
 .../ral/UpdatableGlobalRuleRALBackendHandler.java  |  10 +-
 .../ImportDatabaseConfigurationHandler.java        |   6 +-
 .../ral/updatable/SetDistVariableHandler.java      |   7 +-
 .../resource/AlterStorageUnitBackendHandler.java   |   2 +-
 .../RegisterStorageUnitBackendHandler.java         |   2 +-
 .../UnregisterStorageUnitBackendHandler.java       |   2 +-
 .../rdl/rule/RuleDefinitionBackendHandler.java     |  10 +-
 .../distsql/DistSQLBackendHandlerFactoryTest.java  |   4 +-
 .../ral/updatable/SetDistVariableExecutorTest.java |  14 +-
 .../UnregisterStorageUnitBackendHandlerTest.java   |  11 +-
 .../discovery/cases/base/BaseDiscoveryE2EIT.java   |   2 +-
 .../test/e2e/engine/ral/BaseRALE2EIT.java          |   8 +
 .../test/e2e/engine/ral/GeneralRALE2EIT.java       |   1 +
 32 files changed, 535 insertions(+), 263 deletions(-)

diff --git a/agent/plugins/metrics/type/prometheus/src/test/java/org/apache/shardingsphere/agent/metrics/prometheus/PrometheusPluginBootServiceTest.java b/agent/plugins/metrics/type/prometheus/src/test/java/org/apache/shardingsphere/agent/metrics/prometheus/PrometheusPluginBootServiceTest.java
index 69035f5af38..5e530168741 100644
--- a/agent/plugins/metrics/type/prometheus/src/test/java/org/apache/shardingsphere/agent/metrics/prometheus/PrometheusPluginBootServiceTest.java
+++ b/agent/plugins/metrics/type/prometheus/src/test/java/org/apache/shardingsphere/agent/metrics/prometheus/PrometheusPluginBootServiceTest.java
@@ -22,6 +22,7 @@ import org.apache.shardingsphere.infra.config.mode.ModeConfiguration;
 import org.apache.shardingsphere.infra.instance.ComputeNodeInstance;
 import org.apache.shardingsphere.infra.instance.InstanceContext;
 import org.apache.shardingsphere.infra.instance.metadata.InstanceMetaData;
+import org.apache.shardingsphere.infra.instance.mode.ModeContextManager;
 import org.apache.shardingsphere.infra.lock.LockContext;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
 import org.apache.shardingsphere.infra.util.eventbus.EventBusContext;
@@ -53,8 +54,8 @@ public final class PrometheusPluginBootServiceTest extends ProxyContextRestorer
     public void assertStart() throws IOException {
         MetaDataContexts metaDataContexts = new MetaDataContexts(mock(MetaDataPersistService.class), new ShardingSphereMetaData());
         InstanceContext instanceContext = new InstanceContext(
-                new ComputeNodeInstance(mock(InstanceMetaData.class)), new StandaloneWorkerIdGenerator(), new ModeConfiguration("Standalone", null), mock(LockContext.class),
-                new EventBusContext());
+                new ComputeNodeInstance(mock(InstanceMetaData.class)), new StandaloneWorkerIdGenerator(), new ModeConfiguration("Standalone", null),
+                mock(ModeContextManager.class), mock(LockContext.class), new EventBusContext());
         ProxyContext.init(new ContextManager(metaDataContexts, instanceContext));
         pluginBootService.start(new PluginConfiguration("localhost", 8090, "", createProperties()), true);
         new Socket().connect(new InetSocketAddress("localhost", 8090));
diff --git a/agent/plugins/metrics/type/prometheus/src/test/java/org/apache/shardingsphere/agent/metrics/prometheus/collector/ProxyInfoCollectorTest.java b/agent/plugins/metrics/type/prometheus/src/test/java/org/apache/shardingsphere/agent/metrics/prometheus/collector/ProxyInfoCollectorTest.java
index 8d9f7d803e0..f290d64a06a 100644
--- a/agent/plugins/metrics/type/prometheus/src/test/java/org/apache/shardingsphere/agent/metrics/prometheus/collector/ProxyInfoCollectorTest.java
+++ b/agent/plugins/metrics/type/prometheus/src/test/java/org/apache/shardingsphere/agent/metrics/prometheus/collector/ProxyInfoCollectorTest.java
@@ -22,6 +22,7 @@ import org.apache.shardingsphere.infra.config.mode.ModeConfiguration;
 import org.apache.shardingsphere.infra.instance.ComputeNodeInstance;
 import org.apache.shardingsphere.infra.instance.InstanceContext;
 import org.apache.shardingsphere.infra.instance.metadata.InstanceMetaData;
+import org.apache.shardingsphere.infra.instance.mode.ModeContextManager;
 import org.apache.shardingsphere.infra.lock.LockContext;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
 import org.apache.shardingsphere.infra.util.eventbus.EventBusContext;
@@ -41,8 +42,8 @@ public final class ProxyInfoCollectorTest extends ProxyContextRestorer {
     public void assertCollect() {
         MetaDataContexts metaDataContexts = new MetaDataContexts(mock(MetaDataPersistService.class), new ShardingSphereMetaData());
         InstanceContext instanceContext = new InstanceContext(
-                new ComputeNodeInstance(mock(InstanceMetaData.class)), new StandaloneWorkerIdGenerator(), new ModeConfiguration("Standalone", null), mock(LockContext.class),
-                new EventBusContext());
+                new ComputeNodeInstance(mock(InstanceMetaData.class)), new StandaloneWorkerIdGenerator(), new ModeConfiguration("Standalone", null),
+                mock(ModeContextManager.class), mock(LockContext.class), new EventBusContext());
         ProxyContext.init(new ContextManager(metaDataContexts, instanceContext));
         assertFalse(new ProxyInfoCollector().collect().isEmpty());
     }
diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/algorithm/keygen/SnowflakeKeyGenerateAlgorithmTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/algorithm/keygen/SnowflakeKeyGenerateAlgorithmTest.java
index 494c1b13467..51819d39b9e 100644
--- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/algorithm/keygen/SnowflakeKeyGenerateAlgorithmTest.java
+++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/algorithm/keygen/SnowflakeKeyGenerateAlgorithmTest.java
@@ -24,6 +24,7 @@ import org.apache.shardingsphere.infra.instance.ComputeNodeInstance;
 import org.apache.shardingsphere.infra.instance.InstanceContext;
 import org.apache.shardingsphere.infra.instance.InstanceContextAware;
 import org.apache.shardingsphere.infra.instance.metadata.InstanceMetaData;
+import org.apache.shardingsphere.infra.instance.mode.ModeContextManager;
 import org.apache.shardingsphere.infra.lock.LockContext;
 import org.apache.shardingsphere.infra.util.eventbus.EventBusContext;
 import org.apache.shardingsphere.sharding.algorithm.keygen.fixture.FixedTimeService;
@@ -203,7 +204,7 @@ public final class SnowflakeKeyGenerateAlgorithmTest {
     public void assertSetWorkerIdFailureWhenNegative() {
         SnowflakeKeyGenerateAlgorithm algorithm = (SnowflakeKeyGenerateAlgorithm) KeyGenerateAlgorithmFactory.newInstance(new AlgorithmConfiguration("SNOWFLAKE", new Properties()));
         InstanceContext instanceContext = new InstanceContext(new ComputeNodeInstance(mock(InstanceMetaData.class)), new WorkerIdGeneratorFixture(-1),
-                new ModeConfiguration("Standalone", null), mock(LockContext.class), new EventBusContext());
+                new ModeConfiguration("Standalone", null), mock(ModeContextManager.class), mock(LockContext.class), new EventBusContext());
         algorithm.setInstanceContext(instanceContext);
         algorithm.generateKey();
     }
@@ -219,7 +220,7 @@ public final class SnowflakeKeyGenerateAlgorithmTest {
     public void assertSetWorkerIdFailureWhenOutOfRange() {
         SnowflakeKeyGenerateAlgorithm algorithm = (SnowflakeKeyGenerateAlgorithm) KeyGenerateAlgorithmFactory.newInstance(new AlgorithmConfiguration("SNOWFLAKE", new Properties()));
         InstanceContext instanceContext = new InstanceContext(new ComputeNodeInstance(mock(InstanceMetaData.class)), new WorkerIdGeneratorFixture(Integer.MIN_VALUE),
-                new ModeConfiguration("Standalone", null), mock(LockContext.class), new EventBusContext());
+                new ModeConfiguration("Standalone", null), mock(ModeContextManager.class), mock(LockContext.class), new EventBusContext());
         algorithm.setInstanceContext(instanceContext);
         algorithm.generateKey();
     }
diff --git a/features/sharding/plugin/cache/src/test/java/org/apache/shardingsphere/sharding/cache/checker/ShardingRouteCacheableCheckerTest.java b/features/sharding/plugin/cache/src/test/java/org/apache/shardingsphere/sharding/cache/checker/ShardingRouteCacheableCheckerTest.java
index 49ab3e50f61..a592fb5dfde 100644
--- a/features/sharding/plugin/cache/src/test/java/org/apache/shardingsphere/sharding/cache/checker/ShardingRouteCacheableCheckerTest.java
+++ b/features/sharding/plugin/cache/src/test/java/org/apache/shardingsphere/sharding/cache/checker/ShardingRouteCacheableCheckerTest.java
@@ -143,7 +143,7 @@ public final class ShardingRouteCacheableCheckerTest {
         ShardingTableRuleConfiguration nonCacheableTableSharding = new ShardingTableRuleConfiguration("t_non_cacheable_table_sharding", "ds_0.t_non_cacheable_table_sharding_${0..1}");
         nonCacheableTableSharding.setTableShardingStrategy(new StandardShardingStrategyConfiguration("id", "inline"));
         ruleConfig.getTables().add(nonCacheableTableSharding);
-        return new ShardingRule(ruleConfig, Arrays.asList("ds_0", "ds_1"), new InstanceContext(mock(ComputeNodeInstance.class), props -> 0, null, null, null));
+        return new ShardingRule(ruleConfig, Arrays.asList("ds_0", "ds_1"), new InstanceContext(mock(ComputeNodeInstance.class), props -> 0, null, null, null, null));
     }
     
     private ShardingCacheRule prepareShardingCacheRule(final ShardingRule shardingRule) {
diff --git a/features/sharding/plugin/cosid/src/test/java/org/apache/shardingsphere/sharding/cosid/algorithm/keygen/CosIdSnowflakeKeyGenerateAlgorithmTest.java b/features/sharding/plugin/cosid/src/test/java/org/apache/shardingsphere/sharding/cosid/algorithm/keygen/CosIdSnowflakeKeyGenerateAlgorithmTest.java
index 712a4503356..d8415e626c8 100644
--- a/features/sharding/plugin/cosid/src/test/java/org/apache/shardingsphere/sharding/cosid/algorithm/keygen/CosIdSnowflakeKeyGenerateAlgorithmTest.java
+++ b/features/sharding/plugin/cosid/src/test/java/org/apache/shardingsphere/sharding/cosid/algorithm/keygen/CosIdSnowflakeKeyGenerateAlgorithmTest.java
@@ -27,6 +27,7 @@ import org.apache.shardingsphere.infra.config.mode.ModeConfiguration;
 import org.apache.shardingsphere.infra.instance.ComputeNodeInstance;
 import org.apache.shardingsphere.infra.instance.InstanceContext;
 import org.apache.shardingsphere.infra.instance.metadata.InstanceMetaData;
+import org.apache.shardingsphere.infra.instance.mode.ModeContextManager;
 import org.apache.shardingsphere.infra.lock.LockContext;
 import org.apache.shardingsphere.infra.util.eventbus.EventBusContext;
 import org.apache.shardingsphere.sharding.cosid.algorithm.keygen.fixture.WorkerIdGeneratorFixture;
@@ -60,7 +61,7 @@ public final class CosIdSnowflakeKeyGenerateAlgorithmTest {
         CosIdSnowflakeKeyGenerateAlgorithm algorithm = (CosIdSnowflakeKeyGenerateAlgorithm) KeyGenerateAlgorithmFactory.newInstance(
                 new AlgorithmConfiguration("COSID_SNOWFLAKE", new Properties()));
         algorithm.setInstanceContext(new InstanceContext(new ComputeNodeInstance(mock(InstanceMetaData.class)), new WorkerIdGeneratorFixture(FIXTURE_WORKER_ID),
-                new ModeConfiguration("Standalone", null), mock(LockContext.class), eventBusContext));
+                new ModeConfiguration("Standalone", null), mock(ModeContextManager.class), mock(LockContext.class), eventBusContext));
         long firstActualKey = (Long) algorithm.generateKey();
         long secondActualKey = (Long) algorithm.generateKey();
         SnowflakeIdState firstActualState = snowflakeIdStateParser.parse(firstActualKey);
@@ -76,7 +77,7 @@ public final class CosIdSnowflakeKeyGenerateAlgorithmTest {
     public void assertGenerateKeyModUniformity() {
         CosIdSnowflakeKeyGenerateAlgorithm algorithm = (CosIdSnowflakeKeyGenerateAlgorithm) KeyGenerateAlgorithmFactory.newInstance(new AlgorithmConfiguration("COSID_SNOWFLAKE", new Properties()));
         algorithm.setInstanceContext(new InstanceContext(new ComputeNodeInstance(mock(InstanceMetaData.class)), new WorkerIdGeneratorFixture(FIXTURE_WORKER_ID),
-                new ModeConfiguration("Standalone", null), mock(LockContext.class), eventBusContext));
+                new ModeConfiguration("Standalone", null), mock(ModeContextManager.class), mock(LockContext.class), eventBusContext));
         int divisor = 4;
         int total = 99999;
         int avg = total / divisor;
@@ -121,7 +122,7 @@ public final class CosIdSnowflakeKeyGenerateAlgorithmTest {
                 new AlgorithmConfiguration("COSID_SNOWFLAKE", props));
         algorithm.setInstanceContext(new InstanceContext(new ComputeNodeInstance(mock(InstanceMetaData.class)),
                 new WorkerIdGeneratorFixture(FIXTURE_WORKER_ID), new ModeConfiguration("Standalone", null),
-                mock(LockContext.class), eventBusContext));
+                mock(ModeContextManager.class), mock(LockContext.class), eventBusContext));
         Comparable<?> actualKey = algorithm.generateKey();
         assertThat(actualKey, instanceOf(String.class));
         String actualStringKey = (String) actualKey;
@@ -142,7 +143,7 @@ public final class CosIdSnowflakeKeyGenerateAlgorithmTest {
         CosIdSnowflakeKeyGenerateAlgorithm algorithm = (CosIdSnowflakeKeyGenerateAlgorithm) KeyGenerateAlgorithmFactory.newInstance(
                 new AlgorithmConfiguration("COSID_SNOWFLAKE", new Properties()));
         algorithm.setInstanceContext(new InstanceContext(new ComputeNodeInstance(mock(InstanceMetaData.class)), new WorkerIdGeneratorFixture(-1),
-                new ModeConfiguration("Standalone", null), mock(LockContext.class), eventBusContext));
+                new ModeConfiguration("Standalone", null), mock(ModeContextManager.class), mock(LockContext.class), eventBusContext));
         algorithm.generateKey();
     }
     
@@ -151,7 +152,7 @@ public final class CosIdSnowflakeKeyGenerateAlgorithmTest {
         CosIdSnowflakeKeyGenerateAlgorithm algorithm = (CosIdSnowflakeKeyGenerateAlgorithm) KeyGenerateAlgorithmFactory.newInstance(
                 new AlgorithmConfiguration("COSID_SNOWFLAKE", new Properties()));
         algorithm.setInstanceContext(new InstanceContext(new ComputeNodeInstance(mock(InstanceMetaData.class)), new WorkerIdGeneratorFixture(1024),
-                new ModeConfiguration("Standalone", null), mock(LockContext.class), eventBusContext));
+                new ModeConfiguration("Standalone", null), mock(ModeContextManager.class), mock(LockContext.class), eventBusContext));
         algorithm.generateKey();
     }
 }
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/instance/InstanceContext.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/instance/InstanceContext.java
index beab858732d..53bcd0d5aef 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/instance/InstanceContext.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/instance/InstanceContext.java
@@ -21,6 +21,7 @@ import lombok.AccessLevel;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.infra.config.mode.ModeConfiguration;
+import org.apache.shardingsphere.infra.instance.mode.ModeContextManager;
 import org.apache.shardingsphere.infra.util.eventbus.EventBusContext;
 import org.apache.shardingsphere.infra.instance.metadata.InstanceMetaData;
 import org.apache.shardingsphere.infra.instance.metadata.InstanceType;
@@ -48,6 +49,8 @@ public final class InstanceContext {
     
     private final ModeConfiguration modeConfiguration;
     
+    private final ModeContextManager modeContextManager;
+    
     private final LockContext lockContext;
     
     private final EventBusContext eventBusContext;
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/instance/mode/ModeContextManager.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/instance/mode/ModeContextManager.java
new file mode 100644
index 00000000000..780b5817994
--- /dev/null
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/instance/mode/ModeContextManager.java
@@ -0,0 +1,94 @@
+/*
+ * 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.shardingsphere.infra.instance.mode;
+
+import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
+import org.apache.shardingsphere.infra.datasource.props.DataSourceProperties;
+
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Mode context manager.
+ */
+public interface ModeContextManager {
+    
+    /**
+     * Create database.
+     *
+     * @param databaseName database name
+     */
+    void createDatabase(String databaseName);
+    
+    /**
+     * Drop database.
+     *
+     * @param databaseName database name
+     */
+    void dropDatabase(String databaseName);
+    
+    /**
+     * Register storage units.
+     *
+     * @param databaseName database name
+     * @param toBeRegisterStorageUnitProps to be register storage unit props
+     * @throws SQLException SQL exception
+     */
+    void registerStorageUnits(String databaseName, Map<String, DataSourceProperties> toBeRegisterStorageUnitProps) throws SQLException;
+    
+    /**
+     * Alter storage units.
+     *
+     * @param databaseName database name
+     * @param toBeUpdatedStorageUnitProps to be updated storage unit props
+     * @throws SQLException SQL exception
+     */
+    void alterStorageUnits(String databaseName, Map<String, DataSourceProperties> toBeUpdatedStorageUnitProps) throws SQLException;
+    
+    /**
+     * Unregister storage units.
+     * @param databaseName database name
+     * @param toBeDroppedStorageUnitNames to be dropped storage unit names
+     * @throws SQLException SQL exception
+     */
+    void unregisterStorageUnits(String databaseName, Collection<String> toBeDroppedStorageUnitNames) throws SQLException;
+    
+    /**
+     * Alter rule configuration.
+     *
+     * @param databaseName database name
+     * @param ruleConfigs rule configs
+     */
+    void alterRuleConfiguration(String databaseName, Collection<RuleConfiguration> ruleConfigs);
+    
+    /**
+     * Alter global rule configuration.
+     *
+     * @param globalRuleConfigs global rule configs
+     */
+    void alterGlobalRuleConfiguration(Collection<RuleConfiguration> globalRuleConfigs);
+    
+    /**
+     * Alter properties.
+     *
+     * @param props pros
+     */
+    void alterProperties(Properties props);
+}
diff --git a/infra/common/src/test/java/org/apache/shardingsphere/infra/instance/InstanceContextTest.java b/infra/common/src/test/java/org/apache/shardingsphere/infra/instance/InstanceContextTest.java
index 83bf38a9a00..674a627e711 100644
--- a/infra/common/src/test/java/org/apache/shardingsphere/infra/instance/InstanceContextTest.java
+++ b/infra/common/src/test/java/org/apache/shardingsphere/infra/instance/InstanceContextTest.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.infra.instance;
 import org.apache.shardingsphere.infra.config.mode.ModeConfiguration;
 import org.apache.shardingsphere.infra.instance.fixture.WorkerIdGeneratorFixture;
 import org.apache.shardingsphere.infra.instance.metadata.InstanceMetaData;
+import org.apache.shardingsphere.infra.instance.mode.ModeContextManager;
 import org.apache.shardingsphere.infra.lock.LockContext;
 import org.apache.shardingsphere.infra.state.StateType;
 import org.apache.shardingsphere.infra.util.eventbus.EventBusContext;
@@ -43,6 +44,8 @@ public final class InstanceContextTest {
     
     private final ModeConfiguration modeConfig = new ModeConfiguration("Standalone", null);
     
+    private final ModeContextManager modeContextManager = mock(ModeContextManager.class);
+    
     private final LockContext lockContext = mock(LockContext.class);
     
     private final EventBusContext eventBusContext = new EventBusContext();
@@ -51,7 +54,8 @@ public final class InstanceContextTest {
     public void assertUpdateInstanceStatus() {
         InstanceMetaData instanceMetaData = mock(InstanceMetaData.class);
         when(instanceMetaData.getId()).thenReturn("foo_instance_id");
-        InstanceContext context = new InstanceContext(new ComputeNodeInstance(instanceMetaData), new WorkerIdGeneratorFixture(Integer.MIN_VALUE), modeConfig, lockContext, eventBusContext);
+        InstanceContext context = new InstanceContext(new ComputeNodeInstance(instanceMetaData),
+                new WorkerIdGeneratorFixture(Integer.MIN_VALUE), modeConfig, modeContextManager, lockContext, eventBusContext);
         StateType actual = context.getInstance().getState().getCurrentState();
         assertThat(actual, is(StateType.OK));
         context.updateInstanceStatus(instanceMetaData.getId(), StateType.CIRCUIT_BREAK.name());
@@ -66,14 +70,14 @@ public final class InstanceContextTest {
     public void assertGetWorkerId() {
         ComputeNodeInstance computeNodeInstance = mock(ComputeNodeInstance.class);
         when(computeNodeInstance.getWorkerId()).thenReturn(0);
-        InstanceContext context = new InstanceContext(computeNodeInstance, new WorkerIdGeneratorFixture(Integer.MIN_VALUE), modeConfig, lockContext, eventBusContext);
+        InstanceContext context = new InstanceContext(computeNodeInstance, new WorkerIdGeneratorFixture(Integer.MIN_VALUE), modeConfig, modeContextManager, lockContext, eventBusContext);
         assertThat(context.getWorkerId(), is(0));
     }
     
     @Test
     public void assertGenerateWorkerId() {
         InstanceContext context = new InstanceContext(
-                new ComputeNodeInstance(mock(InstanceMetaData.class)), new WorkerIdGeneratorFixture(Integer.MIN_VALUE), modeConfig, lockContext, eventBusContext);
+                new ComputeNodeInstance(mock(InstanceMetaData.class)), new WorkerIdGeneratorFixture(Integer.MIN_VALUE), modeConfig, modeContextManager, lockContext, eventBusContext);
         assertThat(context.generateWorkerId(new Properties()), is(Integer.MIN_VALUE));
     }
     
@@ -81,7 +85,8 @@ public final class InstanceContextTest {
     public void assertUpdateLabel() {
         InstanceMetaData instanceMetaData = mock(InstanceMetaData.class);
         when(instanceMetaData.getId()).thenReturn("foo_instance_id");
-        InstanceContext context = new InstanceContext(new ComputeNodeInstance(instanceMetaData), new WorkerIdGeneratorFixture(Integer.MIN_VALUE), modeConfig, lockContext, eventBusContext);
+        InstanceContext context = new InstanceContext(new ComputeNodeInstance(instanceMetaData), new WorkerIdGeneratorFixture(Integer.MIN_VALUE),
+                modeConfig, modeContextManager, lockContext, eventBusContext);
         Set<String> expected = new LinkedHashSet<>(Arrays.asList("label_1", "label_2"));
         context.updateLabel("foo_instance_id", expected);
         Collection<String> actual = context.getInstance().getLabels();
@@ -91,7 +96,7 @@ public final class InstanceContextTest {
     @Test
     public void assertGetInstance() {
         ComputeNodeInstance expected = new ComputeNodeInstance(mock(InstanceMetaData.class));
-        InstanceContext context = new InstanceContext(expected, new WorkerIdGeneratorFixture(Integer.MIN_VALUE), modeConfig, lockContext, eventBusContext);
+        InstanceContext context = new InstanceContext(expected, new WorkerIdGeneratorFixture(Integer.MIN_VALUE), modeConfig, modeContextManager, lockContext, eventBusContext);
         ComputeNodeInstance actual = context.getInstance();
         assertThat(actual, is(expected));
     }
@@ -99,24 +104,24 @@ public final class InstanceContextTest {
     @Test
     public void assertGetState() {
         InstanceContext context = new InstanceContext(new ComputeNodeInstance(mock(InstanceMetaData.class)), new WorkerIdGeneratorFixture(Integer.MIN_VALUE), modeConfig,
-                lockContext, eventBusContext);
+                modeContextManager, lockContext, eventBusContext);
         assertNotNull(context.getInstance().getState());
     }
     
     @Test
     public void assertGetModeConfiguration() {
         InstanceContext context = new InstanceContext(new ComputeNodeInstance(mock(InstanceMetaData.class)), new WorkerIdGeneratorFixture(Integer.MIN_VALUE), modeConfig,
-                lockContext, eventBusContext);
+                modeContextManager, lockContext, eventBusContext);
         assertThat(context.getModeConfiguration(), is(modeConfig));
     }
     
     @Test
     public void assertIsCluster() {
         InstanceContext context = new InstanceContext(new ComputeNodeInstance(mock(InstanceMetaData.class)), new WorkerIdGeneratorFixture(Integer.MIN_VALUE), modeConfig,
-                lockContext, eventBusContext);
+                modeContextManager, lockContext, eventBusContext);
         assertFalse(context.isCluster());
         InstanceContext clusterContext = new InstanceContext(new ComputeNodeInstance(mock(InstanceMetaData.class)), new WorkerIdGeneratorFixture(Integer.MIN_VALUE),
-                new ModeConfiguration("Cluster", null), lockContext, eventBusContext);
+                new ModeConfiguration("Cluster", null), modeContextManager, lockContext, eventBusContext);
         assertTrue(clusterContext.isCluster());
     }
 }
diff --git a/infra/common/src/test/java/org/apache/shardingsphere/infra/rule/builder/global/GlobalRulesBuilderTest.java b/infra/common/src/test/java/org/apache/shardingsphere/infra/rule/builder/global/GlobalRulesBuilderTest.java
index 37601602934..7f3cdb5ad28 100644
--- a/infra/common/src/test/java/org/apache/shardingsphere/infra/rule/builder/global/GlobalRulesBuilderTest.java
+++ b/infra/common/src/test/java/org/apache/shardingsphere/infra/rule/builder/global/GlobalRulesBuilderTest.java
@@ -23,6 +23,7 @@ import org.apache.shardingsphere.infra.database.type.dialect.MySQLDatabaseType;
 import org.apache.shardingsphere.infra.instance.ComputeNodeInstance;
 import org.apache.shardingsphere.infra.instance.InstanceContext;
 import org.apache.shardingsphere.infra.instance.metadata.jdbc.JDBCInstanceMetaData;
+import org.apache.shardingsphere.infra.instance.mode.ModeContextManager;
 import org.apache.shardingsphere.infra.instance.workerid.WorkerIdGenerator;
 import org.apache.shardingsphere.infra.lock.LockContext;
 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
@@ -68,7 +69,7 @@ public final class GlobalRulesBuilderTest {
     private InstanceContext buildInstanceContext() {
         ComputeNodeInstance computeNodeInstance = new ComputeNodeInstance(new JDBCInstanceMetaData(UUID.randomUUID().toString()));
         ModeConfiguration modeConfig = new ModeConfiguration("Standalone", null);
-        return new InstanceContext(computeNodeInstance, createWorkerIdGenerator(), modeConfig, mock(LockContext.class), new EventBusContext());
+        return new InstanceContext(computeNodeInstance, createWorkerIdGenerator(), modeConfig, mock(ModeContextManager.class), mock(LockContext.class), new EventBusContext());
     }
     
     private WorkerIdGenerator createWorkerIdGenerator() {
diff --git a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/rule/builder/TransactionRuleBuilderTest.java b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/rule/builder/TransactionRuleBuilderTest.java
index 811631c9636..0b1c3422402 100644
--- a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/rule/builder/TransactionRuleBuilderTest.java
+++ b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/rule/builder/TransactionRuleBuilderTest.java
@@ -23,6 +23,7 @@ import org.apache.shardingsphere.infra.database.DefaultDatabase;
 import org.apache.shardingsphere.infra.instance.ComputeNodeInstance;
 import org.apache.shardingsphere.infra.instance.InstanceContext;
 import org.apache.shardingsphere.infra.instance.metadata.InstanceMetaData;
+import org.apache.shardingsphere.infra.instance.mode.ModeContextManager;
 import org.apache.shardingsphere.infra.instance.workerid.WorkerIdGenerator;
 import org.apache.shardingsphere.infra.lock.LockContext;
 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
@@ -54,8 +55,8 @@ public final class TransactionRuleBuilderTest {
         TransactionRuleConfiguration ruleConfig = new TransactionRuleConfiguration("LOCAL", "provider", new Properties());
         ShardingSphereDatabase database = new ShardingSphereDatabase("logic_db", null, new ShardingSphereResourceMetaData("db", createDataSourceMap()),
                 new ShardingSphereRuleMetaData(Collections.singletonList(mock(ShardingSphereRule.class))), Collections.singletonMap("test", mock(ShardingSphereSchema.class)));
-        InstanceContext instanceContext = new InstanceContext(new ComputeNodeInstance(mock(InstanceMetaData.class)),
-                mock(WorkerIdGenerator.class), new ModeConfiguration("Standalone", null), mock(LockContext.class), new EventBusContext());
+        InstanceContext instanceContext = new InstanceContext(new ComputeNodeInstance(mock(InstanceMetaData.class)), mock(WorkerIdGenerator.class),
+                new ModeConfiguration("Standalone", null), mock(ModeContextManager.class), mock(LockContext.class), new EventBusContext());
         TransactionRule rule = new TransactionRuleBuilder().build(ruleConfig, Collections.singletonMap(DefaultDatabase.LOGIC_NAME, database), instanceContext, mock(ConfigurationProperties.class));
         assertNotNull(rule.getConfiguration());
         assertThat(rule.getDatabases().get("logic_db").getResourceMetaData().getDataSources().size(), is(2));
diff --git a/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java b/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
index 40914ec0d67..bf9bf12b037 100644
--- a/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
+++ b/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
@@ -121,20 +121,6 @@ public final class ContextManager implements AutoCloseable {
         metaDataContexts.getMetaData().addDatabase(databaseName, protocolType);
     }
     
-    /**
-     * Add database and persist.
-     *
-     * @param databaseName database name
-     */
-    public synchronized void addDatabaseAndPersist(final String databaseName) {
-        if (metaDataContexts.getMetaData().containsDatabase(databaseName)) {
-            return;
-        }
-        DatabaseType protocolType = DatabaseTypeEngine.getProtocolType(Collections.emptyMap(), metaDataContexts.getMetaData().getProps());
-        metaDataContexts.getMetaData().addDatabase(databaseName, protocolType);
-        metaDataContexts.getPersistService().getDatabaseMetaDataService().addDatabase(databaseName);
-    }
-    
     /**
      * Drop database.
      *
@@ -149,30 +135,29 @@ public final class ContextManager implements AutoCloseable {
     }
     
     /**
-     * Drop database and persist.
+     * Add schema.
      *
      * @param databaseName database name
+     * @param schemaName schema name
      */
-    public synchronized void dropDatabaseAndPersist(final String databaseName) {
-        if (!metaDataContexts.getMetaData().containsDatabase(databaseName)) {
+    public synchronized void addSchema(final String databaseName, final String schemaName) {
+        if (metaDataContexts.getMetaData().getDatabase(databaseName).containsSchema(schemaName)) {
             return;
         }
-        String actualDatabaseName = metaDataContexts.getMetaData().getActualDatabaseName(databaseName);
-        metaDataContexts.getMetaData().dropDatabase(actualDatabaseName);
-        metaDataContexts.getPersistService().getDatabaseMetaDataService().dropDatabase(actualDatabaseName);
+        metaDataContexts.getMetaData().getDatabase(databaseName).putSchema(schemaName, new ShardingSphereSchema());
     }
     
     /**
-     * Add schema.
+     * Drop schema.
      *
      * @param databaseName database name
      * @param schemaName schema name
      */
-    public synchronized void addSchema(final String databaseName, final String schemaName) {
-        if (metaDataContexts.getMetaData().getDatabase(databaseName).containsSchema(schemaName)) {
+    public synchronized void dropSchema(final String databaseName, final String schemaName) {
+        if (!metaDataContexts.getMetaData().getDatabase(databaseName).containsSchema(schemaName)) {
             return;
         }
-        metaDataContexts.getMetaData().getDatabase(databaseName).putSchema(schemaName, new ShardingSphereSchema());
+        metaDataContexts.getMetaData().getDatabase(databaseName).removeSchema(schemaName);
     }
     
     /**
@@ -184,9 +169,6 @@ public final class ContextManager implements AutoCloseable {
      * @param toBeDeletedViewName to be deleted view name
      */
     public synchronized void alterSchema(final String databaseName, final String schemaName, final String toBeDeletedTableName, final String toBeDeletedViewName) {
-        if (!metaDataContexts.getMetaData().containsDatabase(databaseName) || !metaDataContexts.getMetaData().getDatabase(databaseName).containsSchema(schemaName)) {
-            return;
-        }
         Optional.ofNullable(toBeDeletedTableName).ifPresent(optional -> dropTable(databaseName, schemaName, optional));
         Optional.ofNullable(toBeDeletedViewName).ifPresent(optional -> dropView(databaseName, schemaName, optional));
     }
@@ -240,102 +222,6 @@ public final class ContextManager implements AutoCloseable {
                 .filter(each -> !(each instanceof MutableDataNodeRule)).anyMatch(each -> each.getAllTables().contains(tableName));
     }
     
-    /**
-     * Drop schema.
-     *
-     * @param databaseName database name
-     * @param schemaName schema name
-     */
-    public synchronized void dropSchema(final String databaseName, final String schemaName) {
-        ShardingSphereDatabase database = metaDataContexts.getMetaData().getDatabase(databaseName);
-        if (null == database || !database.containsSchema(schemaName)) {
-            return;
-        }
-        database.removeSchema(schemaName);
-    }
-    
-    /**
-     * Add resources.
-     *
-     * @param databaseName database name
-     * @param toBeAddedDataSourcePropsMap to be added data source properties map
-     * @throws SQLException SQL exception
-     */
-    public synchronized void addResources(final String databaseName, final Map<String, DataSourceProperties> toBeAddedDataSourcePropsMap) throws SQLException {
-        SwitchingResource switchingResource = new ResourceSwitchManager().create(metaDataContexts.getMetaData().getDatabase(databaseName).getResourceMetaData(), toBeAddedDataSourcePropsMap);
-        metaDataContexts.getMetaData().getDatabases().putAll(createChangedDatabases(databaseName, switchingResource, null));
-        metaDataContexts.getMetaData().getGlobalRuleMetaData().findRules(ResourceHeldRule.class).forEach(each -> each.addResource(metaDataContexts.getMetaData().getDatabase(databaseName)));
-        metaDataContexts.getMetaData().getDatabase(databaseName).getSchemas().forEach((schemaName, schema) -> metaDataContexts.getPersistService().getDatabaseMetaDataService()
-                .persist(metaDataContexts.getMetaData().getActualDatabaseName(databaseName), schemaName, schema));
-        metaDataContexts.getPersistService().getDataSourceService().append(metaDataContexts.getMetaData().getActualDatabaseName(databaseName), toBeAddedDataSourcePropsMap);
-        switchingResource.closeStaleDataSources();
-    }
-    
-    /**
-     * Update resources.
-     *
-     * @param databaseName database name
-     * @param toBeUpdatedDataSourcePropsMap to be updated data source properties map
-     * @throws SQLException SQL exception
-     */
-    public synchronized void updateResources(final String databaseName, final Map<String, DataSourceProperties> toBeUpdatedDataSourcePropsMap) throws SQLException {
-        SwitchingResource switchingResource = new ResourceSwitchManager().create(metaDataContexts.getMetaData().getDatabase(databaseName).getResourceMetaData(), toBeUpdatedDataSourcePropsMap);
-        metaDataContexts.getMetaData().getDatabases().putAll(createChangedDatabases(databaseName, switchingResource, null));
-        metaDataContexts.getMetaData().getGlobalRuleMetaData().findRules(ResourceHeldRule.class).forEach(each -> each.addResource(metaDataContexts.getMetaData().getDatabase(databaseName)));
-        metaDataContexts.getMetaData().getDatabases().putAll(newShardingSphereDatabase(metaDataContexts.getMetaData().getDatabase(databaseName)));
-        metaDataContexts.getPersistService().getDataSourceService().append(metaDataContexts.getMetaData().getActualDatabaseName(databaseName), toBeUpdatedDataSourcePropsMap);
-        switchingResource.closeStaleDataSources();
-    }
-    
-    /**
-     * Drop resources.
-     *
-     * @param databaseName database name
-     * @param toBeDroppedResourceNames to be dropped resource names
-     * @throws SQLException SQL exception
-     */
-    public synchronized void dropResources(final String databaseName, final Collection<String> toBeDroppedResourceNames) throws SQLException {
-        // TODO should check to be dropped resources are unused here. ContextManager is atomic domain to maintain metadata, not DistSQL handler
-        Map<String, DataSourceProperties> dataSourcePropsMap = metaDataContexts.getPersistService().getDataSourceService().load(metaDataContexts.getMetaData().getActualDatabaseName(databaseName));
-        Map<String, DataSourceProperties> toBeDeletedDataSourcePropsMap = getToBeDeletedDataSourcePropsMap(dataSourcePropsMap, toBeDroppedResourceNames);
-        SwitchingResource switchingResource =
-                new ResourceSwitchManager().createByDropResource(metaDataContexts.getMetaData().getDatabase(databaseName).getResourceMetaData(), toBeDeletedDataSourcePropsMap);
-        metaDataContexts.getMetaData().getDatabases().putAll(renewDatabase(metaDataContexts.getMetaData().getDatabase(databaseName), switchingResource));
-        MetaDataContexts reloadMetaDataContexts = createMetaDataContexts(databaseName, switchingResource, null);
-        alterSchemaMetaData(databaseName, reloadMetaDataContexts.getMetaData().getDatabase(databaseName), metaDataContexts.getMetaData().getDatabase(databaseName));
-        deletedSchemaNames(databaseName, reloadMetaDataContexts.getMetaData().getDatabase(databaseName), metaDataContexts.getMetaData().getDatabase(databaseName));
-        metaDataContexts = reloadMetaDataContexts;
-        Map<String, DataSourceProperties> toBeReversedDataSourcePropsMap = getToBeReversedDataSourcePropsMap(dataSourcePropsMap, toBeDroppedResourceNames);
-        metaDataContexts.getPersistService().getDataSourceService().persist(metaDataContexts.getMetaData().getActualDatabaseName(databaseName), toBeReversedDataSourcePropsMap);
-        switchingResource.closeStaleDataSources();
-    }
-    
-    private Map<String, ShardingSphereDatabase> renewDatabase(final ShardingSphereDatabase database, final SwitchingResource resource) {
-        Map<String, ShardingSphereDatabase> result = new LinkedHashMap<>(1, 1);
-        Map<String, DataSource> newDataSource =
-                database.getResourceMetaData().getDataSources().entrySet().stream().filter(entry -> !resource.getStaleDataSources().containsKey(entry.getKey()))
-                        .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (oldValue, currentValue) -> oldValue, LinkedHashMap::new));
-        result.put(database.getName().toLowerCase(),
-                new ShardingSphereDatabase(database.getName(), database.getProtocolType(), new ShardingSphereResourceMetaData(database.getName(), newDataSource),
-                        database.getRuleMetaData(), database.getSchemas()));
-        return result;
-    }
-    
-    private Map<String, DataSourceProperties> getToBeDeletedDataSourcePropsMap(final Map<String, DataSourceProperties> dataSourcePropsMap, final Collection<String> toBeDroppedResourceNames) {
-        return dataSourcePropsMap.entrySet().stream().filter(entry -> toBeDroppedResourceNames.contains(entry.getKey())).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
-    }
-    
-    private Map<String, DataSourceProperties> getToBeReversedDataSourcePropsMap(final Map<String, DataSourceProperties> dataSourcePropsMap, final Collection<String> toBeDroppedResourceNames) {
-        return dataSourcePropsMap.entrySet().stream().filter(entry -> !toBeDroppedResourceNames.contains(entry.getKey())).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
-    }
-    
-    private synchronized void alterSchemaMetaData(final String databaseName, final ShardingSphereDatabase reloadDatabase, final ShardingSphereDatabase currentDatabase) {
-        Map<String, ShardingSphereSchema> toBeDeletedTables = SchemaManager.getToBeDeletedTablesBySchemas(reloadDatabase.getSchemas(), currentDatabase.getSchemas());
-        Map<String, ShardingSphereSchema> toBeAddedTables = SchemaManager.getToBeAddedTablesBySchemas(reloadDatabase.getSchemas(), currentDatabase.getSchemas());
-        toBeAddedTables.forEach((key, value) -> metaDataContexts.getPersistService().getDatabaseMetaDataService().persist(databaseName, key, value));
-        toBeDeletedTables.forEach((key, value) -> metaDataContexts.getPersistService().getDatabaseMetaDataService().delete(databaseName, key, value));
-    }
-    
     /**
      * Alter rule configuration.
      *
@@ -356,6 +242,20 @@ public final class ContextManager implements AutoCloseable {
         }
     }
     
+    /**
+     * Alter schema meta data.
+     *
+     * @param databaseName database name
+     * @param reloadDatabase reload database
+     * @param currentDatabase current database
+     */
+    public synchronized void alterSchemaMetaData(final String databaseName, final ShardingSphereDatabase reloadDatabase, final ShardingSphereDatabase currentDatabase) {
+        Map<String, ShardingSphereSchema> toBeDeletedTables = SchemaManager.getToBeDeletedTablesBySchemas(reloadDatabase.getSchemas(), currentDatabase.getSchemas());
+        Map<String, ShardingSphereSchema> toBeAddedTables = SchemaManager.getToBeAddedTablesBySchemas(reloadDatabase.getSchemas(), currentDatabase.getSchemas());
+        toBeAddedTables.forEach((key, value) -> metaDataContexts.getPersistService().getDatabaseMetaDataService().persist(databaseName, key, value));
+        toBeDeletedTables.forEach((key, value) -> metaDataContexts.getPersistService().getDatabaseMetaDataService().delete(databaseName, key, value));
+    }
+    
     /**
      * Alter data source configuration.
      *
@@ -378,6 +278,24 @@ public final class ContextManager implements AutoCloseable {
         }
     }
     
+    /**
+     * Renew ShardingSphere databases.
+     *
+     * @param database database
+     * @param resource resource
+     * @return ShardingSphere databases
+     */
+    public synchronized Map<String, ShardingSphereDatabase> renewDatabase(final ShardingSphereDatabase database, final SwitchingResource resource) {
+        Map<String, ShardingSphereDatabase> result = new LinkedHashMap<>(1, 1);
+        Map<String, DataSource> newDataSource =
+                database.getResourceMetaData().getDataSources().entrySet().stream().filter(entry -> !resource.getStaleDataSources().containsKey(entry.getKey()))
+                        .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (oldValue, currentValue) -> oldValue, LinkedHashMap::new));
+        result.put(database.getName().toLowerCase(),
+                new ShardingSphereDatabase(database.getName(), database.getProtocolType(), new ShardingSphereResourceMetaData(database.getName(), newDataSource),
+                        database.getRuleMetaData(), database.getSchemas()));
+        return result;
+    }
+    
     /**
      * Alter data source and rule configuration.
      *
@@ -408,7 +326,17 @@ public final class ContextManager implements AutoCloseable {
         return result;
     }
     
-    private MetaDataContexts createMetaDataContexts(final String databaseName, final SwitchingResource switchingResource, final Collection<RuleConfiguration> ruleConfigs) throws SQLException {
+    /**
+     * Create meta data contexts.
+     *
+     * @param databaseName database name
+     * @param switchingResource switching resource
+     * @param ruleConfigs rule configs
+     * @return MetaDataContexts meta data contexts
+     * @throws SQLException SQL exception
+     */
+    public synchronized MetaDataContexts createMetaDataContexts(final String databaseName, final SwitchingResource switchingResource,
+                                                                final Collection<RuleConfiguration> ruleConfigs) throws SQLException {
         Map<String, ShardingSphereDatabase> changedDatabases = createChangedDatabases(databaseName, switchingResource, ruleConfigs);
         ConfigurationProperties props = metaDataContexts.getMetaData().getProps();
         ShardingSphereRuleMetaData changedGlobalMetaData = new ShardingSphereRuleMetaData(
@@ -425,7 +353,16 @@ public final class ContextManager implements AutoCloseable {
         return newMetaDataContexts(new ShardingSphereMetaData(changedDatabases, changedGlobalMetaData, props));
     }
     
-    private Map<String, ShardingSphereDatabase> createChangedDatabases(final String databaseName,
+    /**
+     * Create changed databases.
+     *
+     * @param databaseName database name
+     * @param switchingResource switching resource
+     * @param ruleConfigs rule configs
+     * @return ShardingSphere databases
+     * @throws SQLException SQL exception
+     */
+    public synchronized Map<String, ShardingSphereDatabase> createChangedDatabases(final String databaseName,
                                                                        final SwitchingResource switchingResource, final Collection<RuleConfiguration> ruleConfigs) throws SQLException {
         if (null != switchingResource && !switchingResource.getNewDataSources().isEmpty()) {
             metaDataContexts.getMetaData().getDatabase(databaseName).getResourceMetaData().getDataSources().putAll(switchingResource.getNewDataSources());
@@ -454,7 +391,13 @@ public final class ContextManager implements AutoCloseable {
         return result;
     }
     
-    private Map<String, ShardingSphereDatabase> newShardingSphereDatabase(final ShardingSphereDatabase originalDatabase) {
+    /**
+     * Create new ShardingSphere database.
+     *
+     * @param originalDatabase original database
+     * @return ShardingSphere databases
+     */
+    public synchronized Map<String, ShardingSphereDatabase> newShardingSphereDatabase(final ShardingSphereDatabase originalDatabase) {
         Map<String, ShardingSphereDatabase> result = new LinkedHashMap<>(1, 1);
         result.put(originalDatabase.getName().toLowerCase(), new ShardingSphereDatabase(originalDatabase.getName(),
                 originalDatabase.getProtocolType(), originalDatabase.getResourceMetaData(), originalDatabase.getRuleMetaData(),
@@ -492,11 +435,6 @@ public final class ContextManager implements AutoCloseable {
         metaDataContexts = newMetaDataContexts(toBeChangedMetaData);
     }
     
-    private void deletedSchemaNames(final String databaseName, final ShardingSphereDatabase reloadDatabase, final ShardingSphereDatabase currentDatabase) {
-        SchemaManager.getToBeDeletedSchemaNames(reloadDatabase.getSchemas(), currentDatabase.getSchemas()).keySet()
-                .forEach(each -> metaDataContexts.getPersistService().getDatabaseMetaDataService().dropSchema(databaseName, each));
-    }
-    
     /**
      * Reload database metadata from governance center.
      *
@@ -519,6 +457,18 @@ public final class ContextManager implements AutoCloseable {
         }
     }
     
+    /**
+     * Delete schema names.
+     *
+     * @param databaseName database name
+     * @param reloadDatabase reload database
+     * @param currentDatabase current database
+     */
+    public synchronized void deletedSchemaNames(final String databaseName, final ShardingSphereDatabase reloadDatabase, final ShardingSphereDatabase currentDatabase) {
+        SchemaManager.getToBeDeletedSchemaNames(reloadDatabase.getSchemas(), currentDatabase.getSchemas()).keySet()
+                .forEach(each -> metaDataContexts.getPersistService().getDatabaseMetaDataService().dropSchema(databaseName, each));
+    }
+    
     /**
      * Reload schema.
      *
@@ -576,7 +526,7 @@ public final class ContextManager implements AutoCloseable {
      * @param dataSourceName data source name
      * @param tableName to be reloaded table name
      */
-    public void reloadTable(final String databaseName, final String schemaName, final String dataSourceName, final String tableName) {
+    public synchronized void reloadTable(final String databaseName, final String schemaName, final String dataSourceName, final String tableName) {
         Map<String, DataSource> dataSourceMap = Collections.singletonMap(
                 dataSourceName, metaDataContexts.getMetaData().getDatabase(databaseName).getResourceMetaData().getDataSources().get(dataSourceName));
         try {
diff --git a/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManagerAware.java b/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManagerAware.java
new file mode 100644
index 00000000000..e8845bd2f0d
--- /dev/null
+++ b/mode/core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManagerAware.java
@@ -0,0 +1,31 @@
+/*
+ * 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.shardingsphere.mode.manager;
+
+/**
+ * Context manager aware.
+ */
+public interface ContextManagerAware {
+    
+    /**
+     * Set context manager aware.
+     *
+     * @param contextManager context manager
+     */
+    void setContextManagerAware(ContextManager contextManager);
+}
diff --git a/mode/core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java b/mode/core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
index 0dc0e33dcb5..ad998d2b1a1 100644
--- a/mode/core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
+++ b/mode/core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
@@ -40,13 +40,10 @@ import org.apache.shardingsphere.mode.metadata.persist.service.DatabaseMetaDataP
 import org.apache.shardingsphere.test.fixture.jdbc.MockedDataSource;
 import org.apache.shardingsphere.transaction.config.TransactionRuleConfiguration;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 
 import javax.sql.DataSource;
-import java.sql.SQLException;
 import java.sql.Types;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
@@ -116,28 +113,15 @@ public final class ContextManagerTest {
     }
     
     @Test
-    public void assertAddDatabase() throws SQLException {
-        contextManager.addDatabaseAndPersist("new_db");
+    public void assertAddDatabase() {
+        contextManager.addDatabase("new_db");
         verify(metaDataContexts.getMetaData()).addDatabase(eq("new_db"), any(DatabaseType.class));
     }
     
     @Test
-    public void assertAddDatabaseAndPersist() throws SQLException {
-        contextManager.addDatabaseAndPersist("new_db");
-        verify(metaDataContexts.getMetaData()).addDatabase(eq("new_db"), any(DatabaseType.class));
-    }
-    
-    @Test
-    public void assertAddExistedDatabase() throws SQLException {
+    public void assertAddExistedDatabase() {
         when(metaDataContexts.getMetaData().containsDatabase("foo_db")).thenReturn(true);
-        contextManager.addDatabaseAndPersist("foo_db");
-        verify(metaDataContexts.getMetaData(), times(0)).addDatabase(eq("foo_db"), any(DatabaseType.class));
-    }
-    
-    @Test
-    public void assertAddExistedDatabaseAndPersist() throws SQLException {
-        when(metaDataContexts.getMetaData().containsDatabase("foo_db")).thenReturn(true);
-        contextManager.addDatabaseAndPersist("foo_db");
+        contextManager.addDatabase("foo_db");
         verify(metaDataContexts.getMetaData(), times(0)).addDatabase(eq("foo_db"), any(DatabaseType.class));
     }
     
@@ -145,27 +129,13 @@ public final class ContextManagerTest {
     public void assertDropDatabase() {
         when(metaDataContexts.getMetaData().getActualDatabaseName("foo_db")).thenReturn("foo_db");
         when(metaDataContexts.getMetaData().containsDatabase("foo_db")).thenReturn(true);
-        contextManager.dropDatabaseAndPersist("foo_db");
-        verify(metaDataContexts.getMetaData()).dropDatabase("foo_db");
-    }
-    
-    @Test
-    public void assertDropDatabaseAndPersist() {
-        when(metaDataContexts.getMetaData().getActualDatabaseName("foo_db")).thenReturn("foo_db");
-        when(metaDataContexts.getMetaData().containsDatabase("foo_db")).thenReturn(true);
-        contextManager.dropDatabaseAndPersist("foo_db");
+        contextManager.dropDatabase("foo_db");
         verify(metaDataContexts.getMetaData()).dropDatabase("foo_db");
     }
     
     @Test
     public void assertDropNotExistedDatabase() {
-        contextManager.dropDatabaseAndPersist("not_existed_db");
-        verify(metaDataContexts.getMetaData(), times(0)).dropDatabase("not_existed_db");
-    }
-    
-    @Test
-    public void assertDropNotExistedDatabaseAndPersist() {
-        contextManager.dropDatabaseAndPersist("not_existed_db");
+        contextManager.dropDatabase("not_existed_db");
         verify(metaDataContexts.getMetaData(), times(0)).dropDatabase("not_existed_db");
     }
     
@@ -227,19 +197,6 @@ public final class ContextManagerTest {
         return new ShardingSphereSchema(Collections.singletonMap("foo_tbl", beforeChangedTable), Collections.singletonMap("foo_view", beforeChangedView));
     }
     
-    @Ignore
-    @Test
-    public void assertUpdateResources() throws SQLException {
-        ShardingSphereDatabase originalDatabase = createOriginalDatabaseMetaData();
-        ShardingSphereResourceMetaData originalResourceMetaData = originalDatabase.getResourceMetaData();
-        DataSource originalDataSource = originalResourceMetaData.getDataSources().get("bar_ds");
-        when(metaDataContexts.getMetaData().getDatabase("foo_db")).thenReturn(originalDatabase);
-        contextManager.updateResources("foo_db", Collections.singletonMap("bar_ds", new DataSourceProperties(MockedDataSource.class.getName(),
-                createProperties("test", "test"))));
-        verify(originalResourceMetaData, times(1)).close(originalDataSource);
-        assertAlteredDataSource((MockedDataSource) contextManager.getMetaDataContexts().getMetaData().getDatabase("foo_db").getResourceMetaData().getDataSources().get("bar_ds"));
-    }
-    
     private ShardingSphereDatabase createOriginalDatabaseMetaData() {
         ShardingSphereResourceMetaData resourceMetaData = mock(ShardingSphereResourceMetaData.class);
         when(resourceMetaData.getDataSources()).thenReturn(Collections.singletonMap("bar_ds", new MockedDataSource()));
@@ -254,24 +211,6 @@ public final class ContextManagerTest {
         assertThat(actual.getUsername(), is("test"));
     }
     
-    @Test
-    public void assertDropResources() throws SQLException {
-        ShardingSphereDatabase database = new ShardingSphereDatabase(
-                "foo_db", new MySQLDatabaseType(), createOriginalResource(), createOriginalRuleMetaData(), Collections.emptyMap());
-        when(metaDataContexts.getMetaData().getDatabase("foo_db")).thenReturn(database);
-        Map<String, ShardingSphereDatabase> databases = new LinkedHashMap<>(1, 1);
-        databases.put("foo_db", database);
-        when(metaDataContexts.getMetaData().getDatabases()).thenReturn(databases);
-        when(metaDataContexts.getMetaData().getActualDatabaseName("foo_db")).thenReturn("foo_db");
-        when(metaDataContexts.getPersistService()).thenReturn(mock(MetaDataPersistService.class, RETURNS_DEEP_STUBS));
-        Map<String, DataSourceProperties> dataSourcePropertiesMap = new LinkedHashMap<>(1, 1);
-        dataSourcePropertiesMap.put("ds_1", mock(DataSourceProperties.class));
-        dataSourcePropertiesMap.put("ds_2", mock(DataSourceProperties.class));
-        when(metaDataContexts.getPersistService().getDataSourceService().load("foo_db")).thenReturn(dataSourcePropertiesMap);
-        contextManager.dropResources("foo_db", Arrays.asList("ds_1", "ds_2"));
-        assertTrue(metaDataContexts.getMetaData().getDatabases().get("foo_db").getResourceMetaData().getDataSources().isEmpty());
-    }
-    
     @Test
     public void assertAlterRuleConfiguration() {
         ShardingSphereResourceMetaData resourceMetaData = mock(ShardingSphereResourceMetaData.class);
diff --git a/mode/type/cluster/core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/ClusterContextManagerBuilder.java b/mode/type/cluster/core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/ClusterContextManagerBuilder.java
index 6e08b085d5b..b3537a9b270 100644
--- a/mode/type/cluster/core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/ClusterContextManagerBuilder.java
+++ b/mode/type/cluster/core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/ClusterContextManagerBuilder.java
@@ -48,13 +48,14 @@ public final class ClusterContextManagerBuilder implements ContextManagerBuilder
         MetaDataPersistService persistService = new MetaDataPersistService(repository);
         persistConfigurations(persistService, param);
         RegistryCenter registryCenter = new RegistryCenter(repository, new EventBusContext(), param.getInstanceMetaData(), param.getDatabaseConfigs());
-        InstanceContext instanceContext = buildInstanceContext(registryCenter, param);
+        InstanceContext instanceContext = buildInstanceContext(persistService, registryCenter, param);
         if (registryCenter.getRepository() instanceof InstanceContextAware) {
             ((InstanceContextAware) registryCenter.getRepository()).setInstanceContext(instanceContext);
         }
         MetaDataContexts metaDataContexts = MetaDataContextsFactory.create(persistService, param, instanceContext, registryCenter.getStorageNodeStatusService().loadStorageNodes());
         persistMetaData(metaDataContexts);
         ContextManager result = new ContextManager(metaDataContexts, instanceContext);
+        setContextManagerAware(result);
         registerOnline(persistService, registryCenter, param, result);
         return result;
     }
@@ -65,9 +66,9 @@ public final class ClusterContextManagerBuilder implements ContextManagerBuilder
         }
     }
     
-    private InstanceContext buildInstanceContext(final RegistryCenter registryCenter, final ContextManagerBuilderParameter param) {
+    private InstanceContext buildInstanceContext(final MetaDataPersistService persistService, final RegistryCenter registryCenter, final ContextManagerBuilderParameter param) {
         return new InstanceContext(new ComputeNodeInstance(param.getInstanceMetaData()), new ClusterWorkerIdGenerator(registryCenter, param.getInstanceMetaData()),
-                param.getModeConfiguration(), new GlobalLockContext(registryCenter.getGlobalLockPersistService()), registryCenter.getEventBusContext());
+                param.getModeConfiguration(), new ClusterModeContextManager(), new GlobalLockContext(registryCenter.getGlobalLockPersistService()), registryCenter.getEventBusContext());
     }
     
     private void persistMetaData(final MetaDataContexts metaDataContexts) {
@@ -77,6 +78,10 @@ public final class ClusterContextManagerBuilder implements ContextManagerBuilder
                 .getPersistService().getShardingSphereDataPersistService().persist(databaseName, schemaName, schemaData, metaDataContexts.getMetaData().getDatabases())));
     }
     
+    private void setContextManagerAware(final ContextManager contextManager) {
+        ((ClusterModeContextManager) contextManager.getInstanceContext().getModeContextManager()).setContextManagerAware(contextManager);
+    }
+    
     private void registerOnline(final MetaDataPersistService persistService, final RegistryCenter registryCenter, final ContextManagerBuilderParameter param, final ContextManager contextManager) {
         contextManager.getInstanceContext().getInstance().setLabels(param.getLabels());
         contextManager.getInstanceContext().getAllClusterInstances().addAll(registryCenter.getComputeNodeStatusService().loadAllComputeNodeInstances());
diff --git a/mode/type/cluster/core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/ClusterModeContextManager.java b/mode/type/cluster/core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/ClusterModeContextManager.java
new file mode 100644
index 00000000000..65d541b5c53
--- /dev/null
+++ b/mode/type/cluster/core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/ClusterModeContextManager.java
@@ -0,0 +1,89 @@
+/*
+ * 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.shardingsphere.mode.manager.cluster;
+
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
+import org.apache.shardingsphere.infra.datasource.props.DataSourceProperties;
+import org.apache.shardingsphere.infra.instance.mode.ModeContextManager;
+import org.apache.shardingsphere.mode.manager.ContextManager;
+import org.apache.shardingsphere.mode.manager.ContextManagerAware;
+
+import java.util.Collection;
+import java.util.Map;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
+/**
+ * Cluster mode context manager.
+ */
+@RequiredArgsConstructor
+public final class ClusterModeContextManager implements ModeContextManager, ContextManagerAware {
+    
+    private ContextManager contextManager;
+    
+    @Override
+    public void createDatabase(final String databaseName) {
+        contextManager.getMetaDataContexts().getPersistService().getDatabaseMetaDataService().addDatabase(databaseName);
+    }
+    
+    @Override
+    public void dropDatabase(final String databaseName) {
+        contextManager.getMetaDataContexts().getPersistService().getDatabaseMetaDataService().dropDatabase(databaseName);
+    }
+    
+    @Override
+    public void registerStorageUnits(final String databaseName, final Map<String, DataSourceProperties> toBeRegisterStorageUnitProps) {
+        contextManager.getMetaDataContexts().getPersistService().getDataSourceService().append(databaseName, toBeRegisterStorageUnitProps);
+    }
+    
+    @Override
+    public void alterStorageUnits(final String databaseName, final Map<String, DataSourceProperties> toBeUpdatedStorageUnitProps) {
+        contextManager.getMetaDataContexts().getPersistService().getDataSourceService().append(databaseName, toBeUpdatedStorageUnitProps);
+    }
+    
+    @Override
+    public void unregisterStorageUnits(final String databaseName, final Collection<String> toBeDroppedStorageUnitNames) {
+        contextManager.getMetaDataContexts().getPersistService().getDataSourceService().persist(databaseName,
+                getToBeReversedDataSourcePropsMap(contextManager.getMetaDataContexts().getPersistService().getDataSourceService().load(databaseName), toBeDroppedStorageUnitNames));
+    }
+    
+    private Map<String, DataSourceProperties> getToBeReversedDataSourcePropsMap(final Map<String, DataSourceProperties> dataSourcePropsMap, final Collection<String> toBeDroppedResourceNames) {
+        return dataSourcePropsMap.entrySet().stream().filter(entry -> !toBeDroppedResourceNames.contains(entry.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+    }
+    
+    @Override
+    public void alterRuleConfiguration(final String databaseName, final Collection<RuleConfiguration> ruleConfigs) {
+        contextManager.getMetaDataContexts().getPersistService().getDatabaseRulePersistService().persist(databaseName, ruleConfigs);
+    }
+    
+    @Override
+    public void alterGlobalRuleConfiguration(final Collection<RuleConfiguration> globalRuleConfigs) {
+        contextManager.getMetaDataContexts().getPersistService().getGlobalRuleService().persist(globalRuleConfigs);
+    }
+    
+    @Override
+    public void alterProperties(final Properties props) {
+        contextManager.getMetaDataContexts().getPersistService().getPropsService().persist(props);
+    }
+    
+    @Override
+    public void setContextManagerAware(final ContextManager contextManager) {
+        this.contextManager = contextManager;
+    }
+}
diff --git a/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneContextManagerBuilder.java b/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneContextManagerBuilder.java
index 7b705b9dbed..26e7a922933 100644
--- a/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneContextManagerBuilder.java
+++ b/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneContextManagerBuilder.java
@@ -47,7 +47,9 @@ public final class StandaloneContextManagerBuilder implements ContextManagerBuil
         InstanceContext instanceContext = buildInstanceContext(param);
         new ProcessStandaloneSubscriber(instanceContext.getEventBusContext());
         MetaDataContexts metaDataContexts = MetaDataContextsFactory.create(persistService, param, instanceContext);
-        return new ContextManager(metaDataContexts, instanceContext);
+        ContextManager result = new ContextManager(metaDataContexts, instanceContext);
+        setContextManagerAware(result);
+        return result;
     }
     
     private void persistConfigurations(final MetaDataPersistService persistService, final ContextManagerBuilderParameter param) {
@@ -58,7 +60,11 @@ public final class StandaloneContextManagerBuilder implements ContextManagerBuil
     
     private InstanceContext buildInstanceContext(final ContextManagerBuilderParameter param) {
         return new InstanceContext(new ComputeNodeInstance(param.getInstanceMetaData()),
-                new StandaloneWorkerIdGenerator(), param.getModeConfiguration(), new GlobalLockContext(null), new EventBusContext());
+                new StandaloneWorkerIdGenerator(), param.getModeConfiguration(), new StandaloneModeContextManager(), new GlobalLockContext(null), new EventBusContext());
+    }
+    
+    private void setContextManagerAware(final ContextManager contextManager) {
+        ((StandaloneModeContextManager) contextManager.getInstanceContext().getModeContextManager()).setContextManagerAware(contextManager);
     }
     
     @Override
diff --git a/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneModeContextManager.java b/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneModeContextManager.java
new file mode 100644
index 00000000000..1e5661b1313
--- /dev/null
+++ b/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/StandaloneModeContextManager.java
@@ -0,0 +1,131 @@
+/*
+ * 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.shardingsphere.mode.manager.standalone;
+
+import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
+import org.apache.shardingsphere.infra.datasource.props.DataSourceProperties;
+import org.apache.shardingsphere.infra.instance.mode.ModeContextManager;
+import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.rule.identifier.type.ResourceHeldRule;
+import org.apache.shardingsphere.mode.manager.ContextManager;
+import org.apache.shardingsphere.mode.manager.ContextManagerAware;
+import org.apache.shardingsphere.mode.manager.switcher.ResourceSwitchManager;
+import org.apache.shardingsphere.mode.manager.switcher.SwitchingResource;
+import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
+
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
+/**
+ * Standalone mode context manager.
+ */
+public final class StandaloneModeContextManager implements ModeContextManager, ContextManagerAware {
+    
+    private ContextManager contextManager;
+    
+    private volatile MetaDataContexts metaDataContexts;
+    
+    @Override
+    public void createDatabase(final String databaseName) {
+        contextManager.addDatabase(databaseName);
+        contextManager.getMetaDataContexts().getPersistService().getDatabaseMetaDataService().addDatabase(databaseName);
+    }
+    
+    @Override
+    public void dropDatabase(final String databaseName) {
+        contextManager.dropDatabase(databaseName);
+        contextManager.getMetaDataContexts().getPersistService().getDatabaseMetaDataService().dropDatabase(databaseName);
+    }
+    
+    @Override
+    public void registerStorageUnits(final String databaseName, final Map<String, DataSourceProperties> toBeRegisterStorageUnitProps) throws SQLException {
+        SwitchingResource switchingResource = new ResourceSwitchManager().create(metaDataContexts.getMetaData().getDatabase(databaseName).getResourceMetaData(), toBeRegisterStorageUnitProps);
+        metaDataContexts.getMetaData().getDatabases().putAll(contextManager.createChangedDatabases(databaseName, switchingResource, null));
+        metaDataContexts.getMetaData().getGlobalRuleMetaData().findRules(ResourceHeldRule.class).forEach(each -> each.addResource(metaDataContexts.getMetaData().getDatabase(databaseName)));
+        metaDataContexts.getMetaData().getDatabase(databaseName).getSchemas().forEach((schemaName, schema) -> metaDataContexts.getPersistService().getDatabaseMetaDataService()
+                .persist(metaDataContexts.getMetaData().getActualDatabaseName(databaseName), schemaName, schema));
+        metaDataContexts.getPersistService().getDataSourceService().append(metaDataContexts.getMetaData().getActualDatabaseName(databaseName), toBeRegisterStorageUnitProps);
+    }
+    
+    @Override
+    public void alterStorageUnits(final String databaseName, final Map<String, DataSourceProperties> toBeUpdatedStorageUnitProps) throws SQLException {
+        SwitchingResource switchingResource = new ResourceSwitchManager().create(metaDataContexts.getMetaData().getDatabase(databaseName).getResourceMetaData(), toBeUpdatedStorageUnitProps);
+        metaDataContexts.getMetaData().getDatabases().putAll(contextManager.createChangedDatabases(databaseName, switchingResource, null));
+        metaDataContexts.getMetaData().getGlobalRuleMetaData().findRules(ResourceHeldRule.class).forEach(each -> each.addResource(metaDataContexts.getMetaData().getDatabase(databaseName)));
+        metaDataContexts.getMetaData().getDatabases().putAll(contextManager.newShardingSphereDatabase(metaDataContexts.getMetaData().getDatabase(databaseName)));
+        metaDataContexts.getPersistService().getDataSourceService().append(metaDataContexts.getMetaData().getActualDatabaseName(databaseName), toBeUpdatedStorageUnitProps);
+        switchingResource.closeStaleDataSources();
+    }
+    
+    @Override
+    public void unregisterStorageUnits(final String databaseName, final Collection<String> toBeDroppedStorageUnitNames) throws SQLException {
+        Map<String, DataSourceProperties> dataSourcePropsMap = metaDataContexts.getPersistService().getDataSourceService().load(metaDataContexts.getMetaData().getActualDatabaseName(databaseName));
+        Map<String, DataSourceProperties> toBeDeletedDataSourcePropsMap = getToBeDeletedDataSourcePropsMap(dataSourcePropsMap, toBeDroppedStorageUnitNames);
+        SwitchingResource switchingResource =
+                new ResourceSwitchManager().createByDropResource(metaDataContexts.getMetaData().getDatabase(databaseName).getResourceMetaData(), toBeDeletedDataSourcePropsMap);
+        metaDataContexts.getMetaData().getDatabases().putAll(contextManager.renewDatabase(metaDataContexts.getMetaData().getDatabase(databaseName), switchingResource));
+        MetaDataContexts reloadMetaDataContexts = contextManager.createMetaDataContexts(databaseName, switchingResource, null);
+        contextManager.alterSchemaMetaData(databaseName, reloadMetaDataContexts.getMetaData().getDatabase(databaseName), metaDataContexts.getMetaData().getDatabase(databaseName));
+        contextManager.deletedSchemaNames(databaseName, reloadMetaDataContexts.getMetaData().getDatabase(databaseName), metaDataContexts.getMetaData().getDatabase(databaseName));
+        metaDataContexts = reloadMetaDataContexts;
+        Map<String, DataSourceProperties> toBeReversedDataSourcePropsMap = getToBeReversedDataSourcePropsMap(dataSourcePropsMap, toBeDroppedStorageUnitNames);
+        metaDataContexts.getPersistService().getDataSourceService().persist(metaDataContexts.getMetaData().getActualDatabaseName(databaseName), toBeReversedDataSourcePropsMap);
+        switchingResource.closeStaleDataSources();
+    }
+    
+    private Map<String, DataSourceProperties> getToBeDeletedDataSourcePropsMap(final Map<String, DataSourceProperties> dataSourcePropsMap, final Collection<String> toBeDroppedResourceNames) {
+        return dataSourcePropsMap.entrySet().stream().filter(entry -> toBeDroppedResourceNames.contains(entry.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+    }
+    
+    private Map<String, DataSourceProperties> getToBeReversedDataSourcePropsMap(final Map<String, DataSourceProperties> dataSourcePropsMap, final Collection<String> toBeDroppedResourceNames) {
+        return dataSourcePropsMap.entrySet().stream().filter(entry -> !toBeDroppedResourceNames.contains(entry.getKey())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+    }
+    
+    @Override
+    public void alterRuleConfiguration(final String databaseName, final Collection<RuleConfiguration> ruleConfigs) {
+        // TODO Verify it
+        ShardingSphereDatabase currentDatabase = metaDataContexts.getMetaData().getDatabase(databaseName);
+        contextManager.alterRuleConfiguration(databaseName, ruleConfigs);
+        ShardingSphereDatabase reloadDatabase = metaDataContexts.getMetaData().getDatabase(databaseName);
+        contextManager.alterSchemaMetaData(databaseName, reloadDatabase, currentDatabase);
+        metaDataContexts.getPersistService().getDatabaseRulePersistService().persist(metaDataContexts.getMetaData().getActualDatabaseName(databaseName), ruleConfigs);
+    }
+    
+    @Override
+    public void alterGlobalRuleConfiguration(final Collection<RuleConfiguration> globalRuleConfigs) {
+        contextManager.alterGlobalRuleConfiguration(globalRuleConfigs);
+        metaDataContexts.getPersistService().getGlobalRuleService().persist(metaDataContexts.getMetaData().getGlobalRuleMetaData().getConfigurations());
+    }
+    
+    @Override
+    public void alterProperties(final Properties props) {
+        contextManager.alterProperties(props);
+        if (null != metaDataContexts.getPersistService().getPropsService()) {
+            metaDataContexts.getPersistService().getPropsService().persist(props);
+        }
+    }
+    
+    @Override
+    public void setContextManagerAware(final ContextManager contextManager) {
+        this.contextManager = contextManager;
+        this.metaDataContexts = contextManager.getMetaDataContexts();
+    }
+}
diff --git a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/CreateDatabaseBackendHandler.java b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/CreateDatabaseBackendHandler.java
index 861d688f9bc..fd8f4da509c 100644
--- a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/CreateDatabaseBackendHandler.java
+++ b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/CreateDatabaseBackendHandler.java
@@ -38,7 +38,7 @@ public final class CreateDatabaseBackendHandler implements ProxyBackendHandler {
     @Override
     public ResponseHeader execute() throws SQLException {
         check(sqlStatement);
-        ProxyContext.getInstance().getContextManager().addDatabaseAndPersist(sqlStatement.getDatabaseName());
+        ProxyContext.getInstance().getContextManager().getInstanceContext().getModeContextManager().createDatabase(sqlStatement.getDatabaseName());
         return new UpdateResponseHeader(sqlStatement);
     }
     
diff --git a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/DropDatabaseBackendHandler.java b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/DropDatabaseBackendHandler.java
index 1566d13c8d9..2e9104d9124 100644
--- a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/DropDatabaseBackendHandler.java
+++ b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/DropDatabaseBackendHandler.java
@@ -51,7 +51,7 @@ public final class DropDatabaseBackendHandler implements ProxyBackendHandler {
         if (isDropCurrentDatabase(sqlStatement.getDatabaseName())) {
             connectionSession.setCurrentDatabase(null);
         }
-        ProxyContext.getInstance().getContextManager().dropDatabaseAndPersist(sqlStatement.getDatabaseName());
+        ProxyContext.getInstance().getContextManager().getInstanceContext().getModeContextManager().dropDatabase(sqlStatement.getDatabaseName());
         return new UpdateResponseHeader(sqlStatement);
     }
     
diff --git a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/UpdatableGlobalRuleRALBackendHandler.java b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/UpdatableGlobalRuleRALBackendHandler.java
index 3d8042d059d..f5747c64fa6 100644
--- a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/UpdatableGlobalRuleRALBackendHandler.java
+++ b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/UpdatableGlobalRuleRALBackendHandler.java
@@ -19,7 +19,7 @@ package org.apache.shardingsphere.proxy.backend.handler.distsql.ral;
 
 import org.apache.shardingsphere.distsql.parser.statement.ral.RALStatement;
 import org.apache.shardingsphere.distsql.handler.update.GlobalRuleRALUpdater;
-import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
+import org.apache.shardingsphere.mode.manager.ContextManager;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandler;
 import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader;
@@ -42,12 +42,8 @@ public final class UpdatableGlobalRuleRALBackendHandler implements ProxyBackendH
     @Override
     public ResponseHeader execute() {
         updater.executeUpdate(ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData(), sqlStatement);
-        persistNewRuleConfigurations();
+        ContextManager contextManager = ProxyContext.getInstance().getContextManager();
+        contextManager.getInstanceContext().getModeContextManager().alterGlobalRuleConfiguration(contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().getConfigurations());
         return new UpdateResponseHeader(sqlStatement);
     }
-    
-    private void persistNewRuleConfigurations() {
-        MetaDataContexts metaDataContexts = ProxyContext.getInstance().getContextManager().getMetaDataContexts();
-        metaDataContexts.getPersistService().getGlobalRuleService().persist(metaDataContexts.getMetaData().getGlobalRuleMetaData().getConfigurations());
-    }
 }
diff --git a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportDatabaseConfigurationHandler.java b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportDatabaseConfigurationHandler.java
index e3568c916c7..f99800d0cb5 100644
--- a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportDatabaseConfigurationHandler.java
+++ b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/ImportDatabaseConfigurationHandler.java
@@ -115,7 +115,7 @@ public final class ImportDatabaseConfigurationHandler extends UpdatableRALBacken
     }
     
     private void addDatabase(final String databaseName) {
-        ProxyContext.getInstance().getContextManager().addDatabaseAndPersist(databaseName);
+        ProxyContext.getInstance().getContextManager().getInstanceContext().getModeContextManager().createDatabase(databaseName);
     }
     
     private void addResources(final String databaseName, final Map<String, YamlProxyDataSourceConfiguration> yamlDataSourceMap) {
@@ -125,7 +125,7 @@ public final class ImportDatabaseConfigurationHandler extends UpdatableRALBacken
         }
         validateHandler.validate(dataSourcePropsMap);
         try {
-            ProxyContext.getInstance().getContextManager().addResources(databaseName, dataSourcePropsMap);
+            ProxyContext.getInstance().getContextManager().getInstanceContext().getModeContextManager().registerStorageUnits(databaseName, dataSourcePropsMap);
         } catch (final SQLException ex) {
             throw new InvalidResourcesException(Collections.singleton(ex.getMessage()));
         }
@@ -167,6 +167,6 @@ public final class ImportDatabaseConfigurationHandler extends UpdatableRALBacken
     }
     
     private void dropDatabase(final String databaseName) {
-        ProxyContext.getInstance().getContextManager().dropDatabaseAndPersist(databaseName);
+        ProxyContext.getInstance().getContextManager().getInstanceContext().getModeContextManager().dropDatabase(databaseName);
     }
 }
diff --git a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/SetDistVariableHandler.java b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/SetDistVariableHandler.java
index 4bcbf84f967..435bc067940 100644
--- a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/SetDistVariableHandler.java
+++ b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/SetDistVariableHandler.java
@@ -24,7 +24,6 @@ import org.apache.shardingsphere.infra.util.props.TypedPropertyValue;
 import org.apache.shardingsphere.infra.util.props.exception.TypedPropertyValueException;
 import org.apache.shardingsphere.mode.manager.ContextManager;
 import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
-import org.apache.shardingsphere.mode.metadata.persist.MetaDataPersistService;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import org.apache.shardingsphere.proxy.backend.exception.InvalidValueException;
 import org.apache.shardingsphere.proxy.backend.exception.UnsupportedVariableException;
@@ -66,11 +65,7 @@ public final class SetDistVariableHandler extends UpdatableRALBackendHandler<Set
         Properties props = new Properties();
         props.putAll(metaDataContexts.getMetaData().getProps().getProps());
         props.put(propertyKey.getKey(), getValue(propertyKey, value));
-        contextManager.alterProperties(props);
-        MetaDataPersistService persistService = metaDataContexts.getPersistService();
-        if (null != persistService.getPropsService()) {
-            persistService.getPropsService().persist(props);
-        }
+        contextManager.getInstanceContext().getModeContextManager().alterProperties(props);
     }
     
     private Object getValue(final ConfigurationPropertyKey propertyKey, final String value) {
diff --git a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterStorageUnitBackendHandler.java b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterStorageUnitBackendHandler.java
index 175df0aec80..fbab6054c71 100644
--- a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterStorageUnitBackendHandler.java
+++ b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/AlterStorageUnitBackendHandler.java
@@ -71,7 +71,7 @@ public final class AlterStorageUnitBackendHandler extends DatabaseRequiredBacken
         Map<String, DataSourceProperties> dataSourcePropsMap = ResourceSegmentsConverter.convert(databaseType, sqlStatement.getStorageUnits());
         validateHandler.validate(dataSourcePropsMap);
         try {
-            ProxyContext.getInstance().getContextManager().updateResources(databaseName, dataSourcePropsMap);
+            ProxyContext.getInstance().getContextManager().getInstanceContext().getModeContextManager().alterStorageUnits(databaseName, dataSourcePropsMap);
         } catch (final SQLException | ShardingSphereServerException ex) {
             log.error("Alter storage unit failed", ex);
             throw new InvalidResourcesException(Collections.singleton(ex.getMessage()));
diff --git a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandler.java b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandler.java
index 6ad5b81f5ac..b1165c6b0c9 100644
--- a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandler.java
+++ b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/RegisterStorageUnitBackendHandler.java
@@ -68,7 +68,7 @@ public final class RegisterStorageUnitBackendHandler extends DatabaseRequiredBac
         Map<String, DataSourceProperties> dataSourcePropsMap = ResourceSegmentsConverter.convert(databaseType, sqlStatement.getStorageUnits());
         validateHandler.validate(dataSourcePropsMap);
         try {
-            ProxyContext.getInstance().getContextManager().addResources(databaseName, dataSourcePropsMap);
+            ProxyContext.getInstance().getContextManager().getInstanceContext().getModeContextManager().registerStorageUnits(databaseName, dataSourcePropsMap);
         } catch (final SQLException | ShardingSphereServerException ex) {
             log.error("Register storage unit failed", ex);
             throw new InvalidResourcesException(Collections.singleton(ex.getMessage()));
diff --git a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitBackendHandler.java b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitBackendHandler.java
index fa8d88a9ae8..950e15da8a9 100644
--- a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitBackendHandler.java
+++ b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitBackendHandler.java
@@ -59,7 +59,7 @@ public final class UnregisterStorageUnitBackendHandler extends DatabaseRequiredB
     public ResponseHeader execute(final String databaseName, final UnregisterStorageUnitStatement sqlStatement) {
         checkSQLStatement(databaseName, sqlStatement);
         try {
-            ProxyContext.getInstance().getContextManager().dropResources(databaseName, sqlStatement.getStorageUnitNames());
+            ProxyContext.getInstance().getContextManager().getInstanceContext().getModeContextManager().unregisterStorageUnits(databaseName, sqlStatement.getStorageUnitNames());
         } catch (final SQLException | ShardingSphereServerException ex) {
             log.error("Unregister storage unit failed", ex);
             throw new InvalidResourcesException(Collections.singleton(ex.getMessage()));
diff --git a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/rule/RuleDefinitionBackendHandler.java b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/rule/RuleDefinitionBackendHandler.java
index 35587f920ac..4e643aa9142 100644
--- a/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/rule/RuleDefinitionBackendHandler.java
+++ b/proxy/backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/rule/RuleDefinitionBackendHandler.java
@@ -26,7 +26,6 @@ import org.apache.shardingsphere.distsql.handler.update.RuleDefinitionUpdater;
 import org.apache.shardingsphere.distsql.handler.update.RuleDefinitionUpdaterFactory;
 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import org.apache.shardingsphere.infra.util.exception.external.sql.type.generic.UnsupportedSQLOperationException;
-import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import org.apache.shardingsphere.proxy.backend.handler.DatabaseRequiredBackendHandler;
 import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader;
@@ -58,8 +57,8 @@ public final class RuleDefinitionBackendHandler<T extends RuleDefinitionStatemen
         RuleConfiguration currentRuleConfig = findCurrentRuleConfiguration(database, ruleConfigClass).orElse(null);
         ruleDefinitionUpdater.checkSQLStatement(database, sqlStatement, currentRuleConfig);
         if (getRefreshStatus(sqlStatement, currentRuleConfig, ruleDefinitionUpdater)) {
-            Collection<RuleConfiguration> alteredConfigs = processSQLStatement(database, sqlStatement, ruleDefinitionUpdater, currentRuleConfig);
-            persistRuleConfigurationChange(databaseName, alteredConfigs);
+            ProxyContext.getInstance().getContextManager().getInstanceContext().getModeContextManager().alterRuleConfiguration(databaseName,
+                    processSQLStatement(database, sqlStatement, ruleDefinitionUpdater, currentRuleConfig));
         }
         return new UpdateResponseHeader(sqlStatement);
     }
@@ -121,11 +120,6 @@ public final class RuleDefinitionBackendHandler<T extends RuleDefinitionStatemen
         }
     }
     
-    private void persistRuleConfigurationChange(final String databaseName, final Collection<RuleConfiguration> alteredConfigs) {
-        MetaDataContexts metaDataContexts = ProxyContext.getInstance().getContextManager().getMetaDataContexts();
-        metaDataContexts.getPersistService().getDatabaseRulePersistService().persist(metaDataContexts.getMetaData().getActualDatabaseName(databaseName), alteredConfigs);
-    }
-    
     private boolean getRefreshStatus(final SQLStatement sqlStatement, final RuleConfiguration currentRuleConfig, final RuleDefinitionUpdater<?, ?> updater) {
         return !(updater instanceof RuleDefinitionDropUpdater) || ((RuleDefinitionDropUpdater) updater).hasAnyOneToBeDropped(sqlStatement, currentRuleConfig);
     }
diff --git a/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/DistSQLBackendHandlerFactoryTest.java b/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/DistSQLBackendHandlerFactoryTest.java
index dd4f3f1fd60..e14f9b8670e 100644
--- a/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/DistSQLBackendHandlerFactoryTest.java
+++ b/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/DistSQLBackendHandlerFactoryTest.java
@@ -24,6 +24,7 @@ import org.apache.shardingsphere.distsql.parser.statement.rdl.drop.UnregisterSto
 import org.apache.shardingsphere.distsql.parser.statement.rql.show.ShowStorageUnitsStatement;
 import org.apache.shardingsphere.infra.config.algorithm.AlgorithmConfiguration;
 import org.apache.shardingsphere.distsql.handler.exception.rule.MissingRequiredRuleException;
+import org.apache.shardingsphere.infra.instance.mode.ModeContextManager;
 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import org.apache.shardingsphere.infra.metadata.database.resource.ShardingSphereResourceMetaData;
 import org.apache.shardingsphere.infra.metadata.database.rule.ShardingSphereRuleMetaData;
@@ -80,9 +81,10 @@ public final class DistSQLBackendHandlerFactoryTest extends ProxyContextRestorer
     }
     
     private ContextManager mockContextManager() {
-        ContextManager result = mock(ContextManager.class);
+        ContextManager result = mock(ContextManager.class, RETURNS_DEEP_STUBS);
         MetaDataContexts metaDataContexts = mockMetaDataContexts();
         when(result.getMetaDataContexts()).thenReturn(metaDataContexts);
+        when(result.getInstanceContext().getModeContextManager()).thenReturn(mock(ModeContextManager.class));
         return result;
     }
     
diff --git a/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/SetDistVariableExecutorTest.java b/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/SetDistVariableExecutorTest.java
index ef3586f7f74..61c2e511ad9 100644
--- a/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/SetDistVariableExecutorTest.java
+++ b/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/updatable/SetDistVariableExecutorTest.java
@@ -18,9 +18,17 @@
 package org.apache.shardingsphere.proxy.backend.handler.distsql.ral.updatable;
 
 import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.SetDistVariableStatement;
+import org.apache.shardingsphere.infra.config.mode.ModeConfiguration;
 import org.apache.shardingsphere.infra.config.props.ConfigurationPropertyKey;
+import org.apache.shardingsphere.infra.instance.ComputeNodeInstance;
+import org.apache.shardingsphere.infra.instance.InstanceContext;
+import org.apache.shardingsphere.infra.instance.metadata.InstanceMetaData;
+import org.apache.shardingsphere.infra.instance.workerid.WorkerIdGenerator;
+import org.apache.shardingsphere.infra.lock.LockContext;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
+import org.apache.shardingsphere.infra.util.eventbus.EventBusContext;
 import org.apache.shardingsphere.mode.manager.ContextManager;
+import org.apache.shardingsphere.mode.manager.standalone.StandaloneModeContextManager;
 import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
 import org.apache.shardingsphere.mode.metadata.persist.MetaDataPersistService;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
@@ -70,7 +78,11 @@ public final class SetDistVariableExecutorTest extends ProxyContextRestorer {
     
     @Test
     public void assertExecuteWithConfigurationKey() throws SQLException {
-        ContextManager contextManager = new ContextManager(new MetaDataContexts(mock(MetaDataPersistService.class), new ShardingSphereMetaData()), null);
+        StandaloneModeContextManager standaloneModeContextManager = new StandaloneModeContextManager();
+        ContextManager contextManager = new ContextManager(new MetaDataContexts(mock(MetaDataPersistService.class), new ShardingSphereMetaData()),
+                new InstanceContext(new ComputeNodeInstance(mock(InstanceMetaData.class)), mock(WorkerIdGenerator.class),
+                        new ModeConfiguration("Standalone", null), standaloneModeContextManager, mock(LockContext.class), new EventBusContext()));
+        standaloneModeContextManager.setContextManagerAware(contextManager);
         ProxyContext.init(contextManager);
         SetDistVariableStatement statement = new SetDistVariableStatement("proxy_frontend_flush_threshold", "1024");
         SetDistVariableHandler handler = new SetDistVariableHandler();
diff --git a/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitBackendHandlerTest.java b/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitBackendHandlerTest.java
index e826b582f32..bb626cfaf34 100644
--- a/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitBackendHandlerTest.java
+++ b/proxy/backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/distsql/rdl/resource/UnregisterStorageUnitBackendHandlerTest.java
@@ -22,6 +22,7 @@ import org.apache.shardingsphere.infra.datanode.DataNode;
 import org.apache.shardingsphere.distsql.handler.exception.DistSQLException;
 import org.apache.shardingsphere.distsql.handler.exception.resource.MissingRequiredResourcesException;
 import org.apache.shardingsphere.distsql.handler.exception.resource.ResourceInUsedException;
+import org.apache.shardingsphere.infra.instance.mode.ModeContextManager;
 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import org.apache.shardingsphere.infra.metadata.database.resource.ShardingSphereResourceMetaData;
 import org.apache.shardingsphere.infra.metadata.database.rule.ShardingSphereRuleMetaData;
@@ -79,6 +80,9 @@ public final class UnregisterStorageUnitBackendHandlerTest extends ProxyContextR
     
     private ContextManager contextManager;
     
+    @Mock
+    private ModeContextManager modeContextManager;
+    
     private UnregisterStorageUnitBackendHandler unregisterStorageUnitBackendHandler;
     
     @Before
@@ -92,6 +96,7 @@ public final class UnregisterStorageUnitBackendHandlerTest extends ProxyContextR
         when(metaDataContexts.getMetaData().containsDatabase("test")).thenReturn(true);
         contextManager = mock(ContextManager.class, RETURNS_DEEP_STUBS);
         when(contextManager.getMetaDataContexts()).thenReturn(metaDataContexts);
+        when(contextManager.getInstanceContext().getModeContextManager()).thenReturn(modeContextManager);
         ProxyContext.init(contextManager);
         unregisterStorageUnitBackendHandler = new UnregisterStorageUnitBackendHandler(unregisterStorageUnitStatement, connectionSession);
     }
@@ -104,7 +109,7 @@ public final class UnregisterStorageUnitBackendHandlerTest extends ProxyContextR
         when(contextManager.getMetaDataContexts().getMetaData().getDatabase("test")).thenReturn(database);
         UnregisterStorageUnitStatement unregisterStorageUnitStatement = new UnregisterStorageUnitStatement(Collections.singleton("foo_ds"), false);
         assertThat(unregisterStorageUnitBackendHandler.execute("test", unregisterStorageUnitStatement), instanceOf(UpdateResponseHeader.class));
-        verify(contextManager).dropResources("test", unregisterStorageUnitStatement.getStorageUnitNames());
+        verify(modeContextManager).unregisterStorageUnits("test", unregisterStorageUnitStatement.getStorageUnitNames());
     }
     
     @Test(expected = MissingRequiredResourcesException.class)
@@ -148,14 +153,14 @@ public final class UnregisterStorageUnitBackendHandlerTest extends ProxyContextR
         when(contextManager.getMetaDataContexts().getMetaData().getDatabase("test")).thenReturn(database);
         UnregisterStorageUnitStatement unregisterStorageUnitStatement = new UnregisterStorageUnitStatement(Collections.singleton("foo_ds"), true);
         assertThat(unregisterStorageUnitBackendHandler.execute("test", unregisterStorageUnitStatement), instanceOf(UpdateResponseHeader.class));
-        verify(contextManager).dropResources("test", unregisterStorageUnitStatement.getStorageUnitNames());
+        verify(modeContextManager).unregisterStorageUnits("test", unregisterStorageUnitStatement.getStorageUnitNames());
     }
     
     @Test
     public void assertExecuteWithIfExists() throws SQLException {
         UnregisterStorageUnitStatement unregisterStorageUnitStatement = new UnregisterStorageUnitStatement(true, Collections.singleton("foo_ds"), true);
         assertThat(unregisterStorageUnitBackendHandler.execute("test", unregisterStorageUnitStatement), instanceOf(UpdateResponseHeader.class));
-        verify(contextManager).dropResources("test", unregisterStorageUnitStatement.getStorageUnitNames());
+        verify(modeContextManager).unregisterStorageUnits("test", unregisterStorageUnitStatement.getStorageUnitNames());
     }
     
     @Test(expected = DistSQLException.class)
diff --git a/test/e2e/discovery/src/test/java/org/apache/shardingsphere/test/e2e/discovery/cases/base/BaseDiscoveryE2EIT.java b/test/e2e/discovery/src/test/java/org/apache/shardingsphere/test/e2e/discovery/cases/base/BaseDiscoveryE2EIT.java
index 3e1a623deea..55bda35ae23 100644
--- a/test/e2e/discovery/src/test/java/org/apache/shardingsphere/test/e2e/discovery/cases/base/BaseDiscoveryE2EIT.java
+++ b/test/e2e/discovery/src/test/java/org/apache/shardingsphere/test/e2e/discovery/cases/base/BaseDiscoveryE2EIT.java
@@ -122,7 +122,7 @@ public abstract class BaseDiscoveryE2EIT {
                 Statement statement = connection.createStatement()) {
             statement.execute("SHUTDOWN");
         }
-        ThreadUtil.sleep(30, TimeUnit.SECONDS);
+        ThreadUtil.sleep(35, TimeUnit.SECONDS);
     }
     
     private void assertPrimaryDataSourceChanged(final String oldPrimaryDataSourceName, final String newPrimaryDataSourceName) {
diff --git a/test/e2e/suite/src/test/java/org/apache/shardingsphere/test/e2e/engine/ral/BaseRALE2EIT.java b/test/e2e/suite/src/test/java/org/apache/shardingsphere/test/e2e/engine/ral/BaseRALE2EIT.java
index 44d5aa87e19..39099ccbe58 100644
--- a/test/e2e/suite/src/test/java/org/apache/shardingsphere/test/e2e/engine/ral/BaseRALE2EIT.java
+++ b/test/e2e/suite/src/test/java/org/apache/shardingsphere/test/e2e/engine/ral/BaseRALE2EIT.java
@@ -34,6 +34,7 @@ import java.sql.SQLException;
 import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 import static org.hamcrest.CoreMatchers.is;
@@ -86,6 +87,13 @@ public abstract class BaseRALE2EIT extends SingleE2EIT {
         }
     }
     
+    protected void sleep() {
+        try {
+            TimeUnit.SECONDS.sleep(2);
+        } catch (final InterruptedException ignored) {
+        }
+    }
+    
     protected final void assertResultSet(final ResultSet resultSet) throws SQLException {
         assertMetaData(resultSet.getMetaData(), getExpectedColumns());
         assertRows(resultSet, getNotAssertionColumns(), getDataSet().getRows());
diff --git a/test/e2e/suite/src/test/java/org/apache/shardingsphere/test/e2e/engine/ral/GeneralRALE2EIT.java b/test/e2e/suite/src/test/java/org/apache/shardingsphere/test/e2e/engine/ral/GeneralRALE2EIT.java
index a47fc7b7d09..520cccc6b36 100644
--- a/test/e2e/suite/src/test/java/org/apache/shardingsphere/test/e2e/engine/ral/GeneralRALE2EIT.java
+++ b/test/e2e/suite/src/test/java/org/apache/shardingsphere/test/e2e/engine/ral/GeneralRALE2EIT.java
@@ -59,6 +59,7 @@ public final class GeneralRALE2EIT extends BaseRALE2EIT {
             assertResultSet(statement, getSQL());
         } else {
             statement.execute(getSQL());
+            sleep();
             assertResultSet(statement, getAssertion().getAssertionSQL().getSql());
         }
     }