You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2023/06/20 02:02:56 UTC

[shardingsphere] branch master updated: Add version to feature rule event. (#26436)

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

zhaojinchao 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 a920b29c4de Add version to feature rule event. (#26436)
a920b29c4de is described below

commit a920b29c4def6e664a773e901ba3fa7d98d52bf2
Author: Chuxin Chen <ch...@qq.com>
AuthorDate: Tue Jun 20 10:02:50 2023 +0800

    Add version to feature rule event. (#26436)
---
 .../EncryptRuleConfigurationEventBuilder.java      |  24 +--
 .../event/config/AddEncryptConfigurationEvent.java |   4 +
 .../config/AlterEncryptConfigurationEvent.java     |   4 +
 .../config/DeleteEncryptConfigurationEvent.java    |   4 +
 .../event/encryptor/AlterEncryptorEvent.java       |   4 +
 .../event/encryptor/DeleteEncryptorEvent.java      |   4 +
 .../metadata/converter/EncryptNodeConverter.java   |  26 ++++
 .../subscriber/EncryptConfigurationSubscriber.java |   9 ++
 .../converter/EncryptNodeConverterTest.java        |  14 ++
 .../event/MaskRuleConfigurationEventBuilder.java   |  24 +--
 .../event/algorithm/AlterMaskAlgorithmEvent.java   |   4 +
 .../event/algorithm/DeleteMaskAlgorithmEvent.java  |   4 +
 .../event/config/AddMaskConfigurationEvent.java    |   4 +
 .../event/config/AlterMaskConfigurationEvent.java  |   4 +
 .../event/config/DeleteMaskConfigurationEvent.java |   4 +
 .../mask/metadata/converter/MaskNodeConverter.java |  26 ++++
 .../subscriber/MaskConfigurationSubscriber.java    |   9 ++
 .../metadata/converter/MaskNodeConverterTest.java  |  14 ++
 .../event/ShadowRuleConfigurationEventBuilder.java |  37 +++--
 .../event/algorithm/AlterShadowAlgorithmEvent.java |   4 +
 .../algorithm/DeleteShadowAlgorithmEvent.java      |   4 +
 .../event/config/AddShadowConfigurationEvent.java  |   4 +
 .../config/AlterShadowConfigurationEvent.java      |   4 +
 .../config/DeleteShadowConfigurationEvent.java     |   4 +
 .../shadow/event/table/AddShadowTableEvent.java    |   4 +
 .../shadow/event/table/AlterShadowTableEvent.java  |   4 +
 .../shadow/event/table/DeleteShadowTableEvent.java |   4 +
 .../metadata/converter/ShadowNodeConverter.java    |  38 +++++
 .../subscriber/ShadowConfigurationSubscriber.java  |   9 ++
 .../converter/ShadowNodeConverterTest.java         |  21 +++
 .../ShardingRuleConfigurationEventBuilder.java     | 161 +++++++++++--------
 .../event/algorithm/auditor/AlterAuditorEvent.java |   4 +
 .../algorithm/auditor/DeleteAuditorEvent.java      |   4 +
 .../keygenerator/AlterKeyGeneratorEvent.java       |   4 +
 .../keygenerator/DeleteKeyGeneratorEvent.java      |   4 +
 .../sharding/AlterShardingAlgorithmEvent.java      |   4 +
 .../sharding/DeleteShardingAlgorithmEvent.java     |   4 +
 .../cache/AddShardingCacheConfigurationEvent.java  |   4 +
 .../AlterShardingCacheConfigurationEvent.java      |   4 +
 .../DeleteShardingCacheConfigurationEvent.java     |   4 +
 ...dShardingAuditorStrategyConfigurationEvent.java |   4 +
 ...rShardingAuditorStrategyConfigurationEvent.java |   4 +
 ...eShardingAuditorStrategyConfigurationEvent.java |   4 +
 ...DatabaseShardingStrategyConfigurationEvent.java |   4 +
 ...DatabaseShardingStrategyConfigurationEvent.java |   4 +
 ...DatabaseShardingStrategyConfigurationEvent.java |   4 +
 .../AddKeyGenerateStrategyConfigurationEvent.java  |   4 +
 ...AlterKeyGenerateStrategyConfigurationEvent.java |   4 +
 ...eleteKeyGenerateStrategyConfigurationEvent.java |   4 +
 .../AddDefaultShardingColumnEvent.java             |   4 +
 .../AlterDefaultShardingColumnEvent.java           |   4 +
 .../DeleteDefaultShardingColumnEvent.java          |   4 +
 ...AddTableShardingStrategyConfigurationEvent.java |   4 +
 ...terTableShardingStrategyConfigurationEvent.java |   4 +
 ...eteTableShardingStrategyConfigurationEvent.java |   4 +
 .../AddShardingAutoTableConfigurationEvent.java    |   4 +
 .../AlterShardingAutoTableConfigurationEvent.java  |   4 +
 .../DeleteShardingAutoTableConfigurationEvent.java |   4 +
 .../AddBroadcastTableConfigurationEvent.java       |   4 +
 .../AlterBroadcastTableConfigurationEvent.java     |   4 +
 .../DeleteBroadcastTableConfigurationEvent.java    |   4 +
 .../AddShardingTableConfigurationEvent.java        |   4 +
 .../AlterShardingTableConfigurationEvent.java      |   4 +
 .../DeleteShardingTableConfigurationEvent.java     |   4 +
 .../metadata/converter/ShardingNodeConverter.java  | 170 ++++++++++++++++++---
 .../ShardingTableConfigurationSubscriber.java      |  27 ++++
 .../converter/ShardingNodeConverterTest.java       |  91 ++++++++++-
 67 files changed, 778 insertions(+), 126 deletions(-)

diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/EncryptRuleConfigurationEventBuilder.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/EncryptRuleConfigurationEventBuilder.java
index 84b86ea9ee1..2ef655ab341 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/EncryptRuleConfigurationEventBuilder.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/EncryptRuleConfigurationEventBuilder.java
@@ -50,34 +50,40 @@ public final class EncryptRuleConfigurationEventBuilder implements RuleConfigura
         }
         Optional<String> tableName = EncryptNodeConverter.getTableName(event.getKey());
         if (tableName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
-            return createEncryptConfigEvent(databaseName, tableName.get(), event);
+            Optional<String> encryptTableVersion = EncryptNodeConverter.getEncryptTableVersion(event.getKey());
+            if (encryptTableVersion.isPresent()) {
+                return createEncryptConfigEvent(databaseName, tableName.get(), Integer.parseInt(encryptTableVersion.get()), event);
+            }
         }
         Optional<String> encryptorName = EncryptNodeConverter.getEncryptorName(event.getKey());
         if (encryptorName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
-            return createEncryptorEvent(databaseName, encryptorName.get(), event);
+            Optional<String> encryptorVersion = EncryptNodeConverter.getEncryptorVersion(event.getKey());
+            if (encryptorVersion.isPresent()) {
+                return createEncryptorEvent(databaseName, encryptorName.get(), Integer.parseInt(encryptorVersion.get()), event);   
+            }
         }
         return Optional.empty();
     }
     
-    private Optional<GovernanceEvent> createEncryptConfigEvent(final String databaseName, final String groupName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createEncryptConfigEvent(final String databaseName, final String groupName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType()) {
-            return Optional.of(new AddEncryptConfigurationEvent(databaseName, swapEncryptTableRuleConfig(event.getValue())));
+            return Optional.of(new AddEncryptConfigurationEvent(databaseName, swapEncryptTableRuleConfig(event.getValue()), event.getKey(), version));
         }
         if (Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterEncryptConfigurationEvent(databaseName, groupName, swapEncryptTableRuleConfig(event.getValue())));
+            return Optional.of(new AlterEncryptConfigurationEvent(databaseName, groupName, swapEncryptTableRuleConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteEncryptConfigurationEvent(databaseName, groupName));
+        return Optional.of(new DeleteEncryptConfigurationEvent(databaseName, groupName, event.getKey(), version));
     }
     
     private EncryptTableRuleConfiguration swapEncryptTableRuleConfig(final String yamlContext) {
         return new YamlEncryptTableRuleConfigurationSwapper().swapToObject(YamlEngine.unmarshal(yamlContext, YamlEncryptTableRuleConfiguration.class));
     }
     
-    private Optional<GovernanceEvent> createEncryptorEvent(final String databaseName, final String encryptorName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createEncryptorEvent(final String databaseName, final String encryptorName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType() || Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterEncryptorEvent(databaseName, encryptorName, swapToAlgorithmConfig(event.getValue())));
+            return Optional.of(new AlterEncryptorEvent(databaseName, encryptorName, swapToAlgorithmConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteEncryptorEvent(databaseName, encryptorName));
+        return Optional.of(new DeleteEncryptorEvent(databaseName, encryptorName, event.getKey(), version));
     }
     
     private AlgorithmConfiguration swapToAlgorithmConfig(final String yamlContext) {
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/config/AddEncryptConfigurationEvent.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/config/AddEncryptConfigurationEvent.java
index ef7f9676a9c..153c4585435 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/config/AddEncryptConfigurationEvent.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/config/AddEncryptConfigurationEvent.java
@@ -32,4 +32,8 @@ public final class AddEncryptConfigurationEvent implements GovernanceEvent {
     private final String databaseName;
     
     private final EncryptTableRuleConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/config/AlterEncryptConfigurationEvent.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/config/AlterEncryptConfigurationEvent.java
index 512c63c52df..8cab6a51665 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/config/AlterEncryptConfigurationEvent.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/config/AlterEncryptConfigurationEvent.java
@@ -34,4 +34,8 @@ public final class AlterEncryptConfigurationEvent implements GovernanceEvent {
     private final String tableName;
     
     private final EncryptTableRuleConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/config/DeleteEncryptConfigurationEvent.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/config/DeleteEncryptConfigurationEvent.java
index d68a64ec9bc..58574cc8587 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/config/DeleteEncryptConfigurationEvent.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/config/DeleteEncryptConfigurationEvent.java
@@ -31,4 +31,8 @@ public final class DeleteEncryptConfigurationEvent implements GovernanceEvent {
     private final String databaseName;
     
     private final String tableName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/encryptor/AlterEncryptorEvent.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/encryptor/AlterEncryptorEvent.java
index 4a3e5e141a2..a23891bb3b5 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/encryptor/AlterEncryptorEvent.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/encryptor/AlterEncryptorEvent.java
@@ -34,4 +34,8 @@ public final class AlterEncryptorEvent implements GovernanceEvent {
     private final String encryptorName;
     
     private final AlgorithmConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/encryptor/DeleteEncryptorEvent.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/encryptor/DeleteEncryptorEvent.java
index ecd264bd64e..9ced8866498 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/encryptor/DeleteEncryptorEvent.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/event/encryptor/DeleteEncryptorEvent.java
@@ -31,4 +31,8 @@ public final class DeleteEncryptorEvent implements GovernanceEvent {
     private final String databaseName;
     
     private final String encryptorName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/converter/EncryptNodeConverter.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/converter/EncryptNodeConverter.java
index 84678344f98..1f560b9ab7f 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/converter/EncryptNodeConverter.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/metadata/converter/EncryptNodeConverter.java
@@ -40,6 +40,8 @@ public final class EncryptNodeConverter {
     
     private static final String RULE_NAME_PATTERN = "/([\\w\\-]+)?";
     
+    private static final String RULE_VERSION = "/([\\w\\-]+)/versions/([\\w\\-]+)$";
+    
     /**
      * Get table name path.
      *
@@ -119,4 +121,28 @@ public final class EncryptNodeConverter {
         Matcher matcher = pattern.matcher(rulePath);
         return matcher.find() ? Optional.of(matcher.group(3)) : Optional.empty();
     }
+    
+    /**
+     * Get encrypt table version.
+     * 
+     * @param rulePath rule path
+     * @return encrypt table version
+     */
+    public static Optional<String> getEncryptTableVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + TABLES_NODE + RULE_VERSION, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(4)) : Optional.empty();
+    }
+    
+    /**
+     * Get encryptor version.
+     *
+     * @param rulePath rule path
+     * @return encryptor version
+     */
+    public static Optional<String> getEncryptorVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + ENCRYPTORS_NODE + RULE_VERSION, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(4)) : Optional.empty();
+    }
 }
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/subscriber/EncryptConfigurationSubscriber.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/subscriber/EncryptConfigurationSubscriber.java
index d94a94e88f7..88da97bd91c 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/subscriber/EncryptConfigurationSubscriber.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/subscriber/EncryptConfigurationSubscriber.java
@@ -59,6 +59,9 @@ public final class EncryptConfigurationSubscriber implements RuleConfigurationSu
      */
     @Subscribe
     public synchronized void renew(final AddEncryptConfigurationEvent event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         EncryptTableRuleConfiguration needToAddedConfig = event.getConfig();
         Optional<EncryptRule> rule = database.getRuleMetaData().findSingleRule(EncryptRule.class);
@@ -79,6 +82,9 @@ public final class EncryptConfigurationSubscriber implements RuleConfigurationSu
      */
     @Subscribe
     public synchronized void renew(final AlterEncryptConfigurationEvent event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         EncryptTableRuleConfiguration needToAlteredConfig = event.getConfig();
         EncryptRuleConfiguration config = (EncryptRuleConfiguration) database.getRuleMetaData().getSingleRule(EncryptRule.class).getConfiguration();
@@ -94,6 +100,9 @@ public final class EncryptConfigurationSubscriber implements RuleConfigurationSu
      */
     @Subscribe
     public synchronized void renew(final DeleteEncryptConfigurationEvent event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         EncryptRuleConfiguration config = (EncryptRuleConfiguration) database.getRuleMetaData().getSingleRule(EncryptRule.class).getConfiguration();
         config.getTables().removeIf(each -> each.getName().equals(event.getTableName()));
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/metadata/converter/EncryptNodeConverterTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/metadata/converter/EncryptNodeConverterTest.java
index 13e3fce0cdb..8cbe8b14c80 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/metadata/converter/EncryptNodeConverterTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/metadata/converter/EncryptNodeConverterTest.java
@@ -61,4 +61,18 @@ class EncryptNodeConverterTest {
         assertTrue(actual.isPresent());
         assertThat(actual.get(), is("AES"));
     }
+    
+    @Test
+    void assertGetEncryptTableVersion() {
+        Optional<String> actual = EncryptNodeConverter.getEncryptTableVersion("/metadata/foo_db/rules/encrypt/tables/foo_table/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
+    
+    @Test
+    void assertGetEncryptAlgorithmVersion() {
+        Optional<String> actual = EncryptNodeConverter.getEncryptorVersion("/metadata/foo_db/rules/encrypt/encryptors/aes_algorithm/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
 }
diff --git a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/MaskRuleConfigurationEventBuilder.java b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/MaskRuleConfigurationEventBuilder.java
index af37673c8f6..7206bc693ad 100644
--- a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/MaskRuleConfigurationEventBuilder.java
+++ b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/MaskRuleConfigurationEventBuilder.java
@@ -50,34 +50,40 @@ public final class MaskRuleConfigurationEventBuilder implements RuleConfiguratio
         }
         Optional<String> tableName = MaskNodeConverter.getTableName(event.getKey());
         if (tableName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
-            return createMaskConfigEvent(databaseName, tableName.get(), event);
+            Optional<String> version = MaskNodeConverter.getMaskTableVersion(event.getKey());
+            if (version.isPresent()) {
+                return createMaskConfigEvent(databaseName, tableName.get(), Integer.parseInt(version.get()), event);
+            }
         }
         Optional<String> algorithmName = MaskNodeConverter.getAlgorithmName(event.getKey());
         if (algorithmName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
-            return createMaskAlgorithmEvent(databaseName, algorithmName.get(), event);
+            Optional<String> algorithmVersion = MaskNodeConverter.getMaskAlgorithmVersion(event.getKey());
+            if (algorithmVersion.isPresent()) {
+                return createMaskAlgorithmEvent(databaseName, algorithmName.get(), Integer.parseInt(algorithmVersion.get()), event);
+            }
         }
         return Optional.empty();
     }
     
-    private Optional<GovernanceEvent> createMaskConfigEvent(final String databaseName, final String tableName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createMaskConfigEvent(final String databaseName, final String tableName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType()) {
-            return Optional.of(new AddMaskConfigurationEvent(databaseName, swapMaskTableRuleConfig(event.getValue())));
+            return Optional.of(new AddMaskConfigurationEvent(databaseName, swapMaskTableRuleConfig(event.getValue()), event.getKey(), version));
         }
         if (Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterMaskConfigurationEvent(databaseName, tableName, swapMaskTableRuleConfig(event.getValue())));
+            return Optional.of(new AlterMaskConfigurationEvent(databaseName, tableName, swapMaskTableRuleConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteMaskConfigurationEvent(databaseName, tableName));
+        return Optional.of(new DeleteMaskConfigurationEvent(databaseName, tableName, event.getKey(), version));
     }
     
     private MaskTableRuleConfiguration swapMaskTableRuleConfig(final String yamlContext) {
         return new YamlMaskTableRuleConfigurationSwapper().swapToObject(YamlEngine.unmarshal(yamlContext, YamlMaskTableRuleConfiguration.class));
     }
     
-    private Optional<GovernanceEvent> createMaskAlgorithmEvent(final String databaseName, final String algorithmName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createMaskAlgorithmEvent(final String databaseName, final String algorithmName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType() || Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterMaskAlgorithmEvent(databaseName, algorithmName, swapToAlgorithmConfig(event.getValue())));
+            return Optional.of(new AlterMaskAlgorithmEvent(databaseName, algorithmName, swapToAlgorithmConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteMaskAlgorithmEvent(databaseName, algorithmName));
+        return Optional.of(new DeleteMaskAlgorithmEvent(databaseName, algorithmName, event.getKey(), version));
     }
     
     private AlgorithmConfiguration swapToAlgorithmConfig(final String yamlContext) {
diff --git a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/algorithm/AlterMaskAlgorithmEvent.java b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/algorithm/AlterMaskAlgorithmEvent.java
index 227a18898a1..b3a9edc7cd6 100644
--- a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/algorithm/AlterMaskAlgorithmEvent.java
+++ b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/algorithm/AlterMaskAlgorithmEvent.java
@@ -34,4 +34,8 @@ public final class AlterMaskAlgorithmEvent implements GovernanceEvent {
     private final String algorithmName;
     
     private final AlgorithmConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/algorithm/DeleteMaskAlgorithmEvent.java b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/algorithm/DeleteMaskAlgorithmEvent.java
index 07f484e4e86..1aebedbbdbf 100644
--- a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/algorithm/DeleteMaskAlgorithmEvent.java
+++ b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/algorithm/DeleteMaskAlgorithmEvent.java
@@ -31,4 +31,8 @@ public final class DeleteMaskAlgorithmEvent implements GovernanceEvent {
     private final String databaseName;
     
     private final String algorithmName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/config/AddMaskConfigurationEvent.java b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/config/AddMaskConfigurationEvent.java
index fe51c29e4e3..6c891575c71 100644
--- a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/config/AddMaskConfigurationEvent.java
+++ b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/config/AddMaskConfigurationEvent.java
@@ -32,4 +32,8 @@ public final class AddMaskConfigurationEvent implements GovernanceEvent {
     private final String databaseName;
     
     private final MaskTableRuleConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/config/AlterMaskConfigurationEvent.java b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/config/AlterMaskConfigurationEvent.java
index 0990677c1cd..4600e76c7f2 100644
--- a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/config/AlterMaskConfigurationEvent.java
+++ b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/config/AlterMaskConfigurationEvent.java
@@ -34,4 +34,8 @@ public final class AlterMaskConfigurationEvent implements GovernanceEvent {
     private final String tableName;
     
     private final MaskTableRuleConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/config/DeleteMaskConfigurationEvent.java b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/config/DeleteMaskConfigurationEvent.java
index af3123e9246..7302194d2fa 100644
--- a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/config/DeleteMaskConfigurationEvent.java
+++ b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/event/config/DeleteMaskConfigurationEvent.java
@@ -31,4 +31,8 @@ public final class DeleteMaskConfigurationEvent implements GovernanceEvent {
     private final String databaseName;
     
     private final String tableName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/metadata/converter/MaskNodeConverter.java b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/metadata/converter/MaskNodeConverter.java
index 1f42eec981f..d08b45d470e 100644
--- a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/metadata/converter/MaskNodeConverter.java
+++ b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/metadata/converter/MaskNodeConverter.java
@@ -40,6 +40,8 @@ public final class MaskNodeConverter {
     
     private static final String RULE_NAME_PATTERN = "/([\\w\\-]+)?";
     
+    private static final String RULE_VERSION = "/([\\w\\-]+)/versions/([\\w\\-]+)$";
+    
     /**
      * Get table name path.
      * 
@@ -119,4 +121,28 @@ public final class MaskNodeConverter {
         Matcher matcher = pattern.matcher(rulePath);
         return matcher.find() ? Optional.of(matcher.group(3)) : Optional.empty();
     }
+    
+    /**
+     * Get mask table version.
+     *
+     * @param rulePath rule path
+     * @return mask table version
+     */
+    public static Optional<String> getMaskTableVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + TABLES_NODE + RULE_VERSION, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(4)) : Optional.empty();
+    }
+    
+    /**
+     * Get mask algorithm version.
+     *
+     * @param rulePath rule path
+     * @return mask algorithm version
+     */
+    public static Optional<String> getMaskAlgorithmVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + ALGORITHMS_NODE + RULE_VERSION, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(4)) : Optional.empty();
+    }
 }
diff --git a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/subscriber/MaskConfigurationSubscriber.java b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/subscriber/MaskConfigurationSubscriber.java
index 78380af7fc5..4cd32d4ef0d 100644
--- a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/subscriber/MaskConfigurationSubscriber.java
+++ b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/subscriber/MaskConfigurationSubscriber.java
@@ -59,6 +59,9 @@ public final class MaskConfigurationSubscriber implements RuleConfigurationSubsc
      */
     @Subscribe
     public synchronized void renew(final AddMaskConfigurationEvent event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         MaskTableRuleConfiguration needToAddedConfig = event.getConfig();
         Optional<MaskRule> rule = database.getRuleMetaData().findSingleRule(MaskRule.class);
@@ -80,6 +83,9 @@ public final class MaskConfigurationSubscriber implements RuleConfigurationSubsc
      */
     @Subscribe
     public synchronized void renew(final AlterMaskConfigurationEvent event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         MaskTableRuleConfiguration needToAlteredConfig = event.getConfig();
         MaskRuleConfiguration config = (MaskRuleConfiguration) database.getRuleMetaData().getSingleRule(MaskRule.class).getConfiguration();
@@ -95,6 +101,9 @@ public final class MaskConfigurationSubscriber implements RuleConfigurationSubsc
      */
     @Subscribe
     public synchronized void renew(final DeleteMaskConfigurationEvent event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         MaskRuleConfiguration config = (MaskRuleConfiguration) database.getRuleMetaData().getSingleRule(MaskRule.class).getConfiguration();
         config.getTables().removeIf(each -> each.getName().equals(event.getTableName()));
diff --git a/features/mask/core/src/test/java/org/apache/shardingsphere/mask/metadata/converter/MaskNodeConverterTest.java b/features/mask/core/src/test/java/org/apache/shardingsphere/mask/metadata/converter/MaskNodeConverterTest.java
index 5ea8603207e..b8a61aea3dd 100644
--- a/features/mask/core/src/test/java/org/apache/shardingsphere/mask/metadata/converter/MaskNodeConverterTest.java
+++ b/features/mask/core/src/test/java/org/apache/shardingsphere/mask/metadata/converter/MaskNodeConverterTest.java
@@ -61,4 +61,18 @@ class MaskNodeConverterTest {
         assertTrue(actual.isPresent());
         assertThat(actual.get(), is("MD5"));
     }
+    
+    @Test
+    void assertGetMaskTableVersion() {
+        Optional<String> actual = MaskNodeConverter.getMaskTableVersion("/metadata/foo_db/rules/mask/tables/foo_table/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
+    
+    @Test
+    void assertGetMaskAlgorithmVersion() {
+        Optional<String> actual = MaskNodeConverter.getMaskAlgorithmVersion("/metadata/foo_db/rules/mask/algorithms/md5_mask/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
 }
diff --git a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/ShadowRuleConfigurationEventBuilder.java b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/ShadowRuleConfigurationEventBuilder.java
index 97de25a7392..935d53cf873 100644
--- a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/ShadowRuleConfigurationEventBuilder.java
+++ b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/ShadowRuleConfigurationEventBuilder.java
@@ -55,27 +55,36 @@ public final class ShadowRuleConfigurationEventBuilder implements RuleConfigurat
         }
         Optional<String> dataSourceName = ShadowNodeConverter.getDataSourceName(event.getKey());
         if (dataSourceName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
-            return createShadowConfigEvent(databaseName, dataSourceName.get(), event);
+            Optional<String> dataSourceVersion = ShadowNodeConverter.getDataSourceVersion(event.getKey());
+            if (dataSourceVersion.isPresent()) {
+                return createShadowConfigEvent(databaseName, dataSourceName.get(), Integer.parseInt(dataSourceVersion.get()), event);
+            }
         }
         Optional<String> tableName = ShadowNodeConverter.getTableName(event.getKey());
         if (tableName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
-            return createShadowTableConfigEvent(databaseName, tableName.get(), event);
+            Optional<String> tableVersion = ShadowNodeConverter.getTableVersion(event.getKey());
+            if (tableVersion.isPresent()) {
+                return createShadowTableConfigEvent(databaseName, tableName.get(), Integer.parseInt(tableVersion.get()), event);
+            }
         }
         Optional<String> algorithmName = ShadowNodeConverter.getAlgorithmName(event.getKey());
         if (algorithmName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
-            return createShadowAlgorithmEvent(databaseName, algorithmName.get(), event);
+            Optional<String> algorithmVersion = ShadowNodeConverter.getAlgorithmVersion(event.getKey());
+            if (algorithmVersion.isPresent()) {
+                return createShadowAlgorithmEvent(databaseName, algorithmName.get(), Integer.parseInt(algorithmVersion.get()), event);
+            }
         }
         return Optional.empty();
     }
     
-    private Optional<GovernanceEvent> createShadowConfigEvent(final String databaseName, final String dataSourceName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createShadowConfigEvent(final String databaseName, final String dataSourceName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType()) {
-            return Optional.of(new AddShadowConfigurationEvent(databaseName, swapShadowDataSourceRuleConfig(dataSourceName, event.getValue())));
+            return Optional.of(new AddShadowConfigurationEvent(databaseName, swapShadowDataSourceRuleConfig(dataSourceName, event.getValue()), event.getKey(), version));
         }
         if (Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterShadowConfigurationEvent(databaseName, dataSourceName, swapShadowDataSourceRuleConfig(dataSourceName, event.getValue())));
+            return Optional.of(new AlterShadowConfigurationEvent(databaseName, dataSourceName, swapShadowDataSourceRuleConfig(dataSourceName, event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteShadowConfigurationEvent(databaseName, dataSourceName));
+        return Optional.of(new DeleteShadowConfigurationEvent(databaseName, dataSourceName, event.getKey(), version));
     }
     
     private ShadowDataSourceConfiguration swapShadowDataSourceRuleConfig(final String dataSourceName, final String yamlContext) {
@@ -83,25 +92,25 @@ public final class ShadowRuleConfigurationEventBuilder implements RuleConfigurat
         return new ShadowDataSourceConfiguration(dataSourceName, yamlConfig.getProductionDataSourceName(), yamlConfig.getShadowDataSourceName());
     }
     
-    private Optional<GovernanceEvent> createShadowTableConfigEvent(final String databaseName, final String tableName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createShadowTableConfigEvent(final String databaseName, final String tableName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType()) {
-            return Optional.of(new AddShadowTableEvent(databaseName, tableName, swapToTableConfig(event.getValue())));
+            return Optional.of(new AddShadowTableEvent(databaseName, tableName, swapToTableConfig(event.getValue()), event.getKey(), version));
         }
         if (Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterShadowTableEvent(databaseName, tableName, swapToTableConfig(event.getValue())));
+            return Optional.of(new AlterShadowTableEvent(databaseName, tableName, swapToTableConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteShadowTableEvent(databaseName, tableName));
+        return Optional.of(new DeleteShadowTableEvent(databaseName, tableName, event.getKey(), version));
     }
     
     private ShadowTableConfiguration swapToTableConfig(final String yamlContext) {
         return new YamlShadowTableConfigurationSwapper().swapToObject(YamlEngine.unmarshal(yamlContext, YamlShadowTableConfiguration.class));
     }
     
-    private Optional<GovernanceEvent> createShadowAlgorithmEvent(final String databaseName, final String algorithmName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createShadowAlgorithmEvent(final String databaseName, final String algorithmName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType() || Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterShadowAlgorithmEvent(databaseName, algorithmName, swapToAlgorithmConfig(event.getValue())));
+            return Optional.of(new AlterShadowAlgorithmEvent(databaseName, algorithmName, swapToAlgorithmConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteShadowAlgorithmEvent(databaseName, algorithmName));
+        return Optional.of(new DeleteShadowAlgorithmEvent(databaseName, algorithmName, event.getKey(), version));
     }
     
     private AlgorithmConfiguration swapToAlgorithmConfig(final String yamlContext) {
diff --git a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/algorithm/AlterShadowAlgorithmEvent.java b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/algorithm/AlterShadowAlgorithmEvent.java
index 5886567078c..685097c9e78 100644
--- a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/algorithm/AlterShadowAlgorithmEvent.java
+++ b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/algorithm/AlterShadowAlgorithmEvent.java
@@ -34,4 +34,8 @@ public final class AlterShadowAlgorithmEvent implements GovernanceEvent {
     private final String algorithmName;
     
     private final AlgorithmConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/algorithm/DeleteShadowAlgorithmEvent.java b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/algorithm/DeleteShadowAlgorithmEvent.java
index 8f4a2365ac5..ed6c2bb9cf7 100644
--- a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/algorithm/DeleteShadowAlgorithmEvent.java
+++ b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/algorithm/DeleteShadowAlgorithmEvent.java
@@ -31,4 +31,8 @@ public final class DeleteShadowAlgorithmEvent implements GovernanceEvent {
     private final String databaseName;
     
     private final String algorithmName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/config/AddShadowConfigurationEvent.java b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/config/AddShadowConfigurationEvent.java
index 697a5a50461..55e191f4ade 100644
--- a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/config/AddShadowConfigurationEvent.java
+++ b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/config/AddShadowConfigurationEvent.java
@@ -32,4 +32,8 @@ public final class AddShadowConfigurationEvent implements GovernanceEvent {
     private final String databaseName;
     
     private final ShadowDataSourceConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/config/AlterShadowConfigurationEvent.java b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/config/AlterShadowConfigurationEvent.java
index f4a21dcca8a..ea79962a159 100644
--- a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/config/AlterShadowConfigurationEvent.java
+++ b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/config/AlterShadowConfigurationEvent.java
@@ -34,4 +34,8 @@ public final class AlterShadowConfigurationEvent implements GovernanceEvent {
     private final String dataSourceName;
     
     private final ShadowDataSourceConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/config/DeleteShadowConfigurationEvent.java b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/config/DeleteShadowConfigurationEvent.java
index 302bfd91a31..c20d9e88843 100644
--- a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/config/DeleteShadowConfigurationEvent.java
+++ b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/config/DeleteShadowConfigurationEvent.java
@@ -31,4 +31,8 @@ public final class DeleteShadowConfigurationEvent implements GovernanceEvent {
     private final String databaseName;
     
     private final String dataSourceName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/table/AddShadowTableEvent.java b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/table/AddShadowTableEvent.java
index 7e6e97d6cc7..41e0472cdd3 100644
--- a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/table/AddShadowTableEvent.java
+++ b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/table/AddShadowTableEvent.java
@@ -34,4 +34,8 @@ public final class AddShadowTableEvent implements GovernanceEvent {
     private final String tableName;
     
     private final ShadowTableConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/table/AlterShadowTableEvent.java b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/table/AlterShadowTableEvent.java
index c9af997a24d..b7ff128e4d2 100644
--- a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/table/AlterShadowTableEvent.java
+++ b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/table/AlterShadowTableEvent.java
@@ -34,4 +34,8 @@ public final class AlterShadowTableEvent implements GovernanceEvent {
     private final String tableName;
     
     private final ShadowTableConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/table/DeleteShadowTableEvent.java b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/table/DeleteShadowTableEvent.java
index 583e0e4f662..1e992131e75 100644
--- a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/table/DeleteShadowTableEvent.java
+++ b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/event/table/DeleteShadowTableEvent.java
@@ -31,4 +31,8 @@ public final class DeleteShadowTableEvent implements GovernanceEvent {
     private final String databaseName;
     
     private final String tableName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/metadata/converter/ShadowNodeConverter.java b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/metadata/converter/ShadowNodeConverter.java
index 6d835268a08..39b9aeee763 100644
--- a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/metadata/converter/ShadowNodeConverter.java
+++ b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/metadata/converter/ShadowNodeConverter.java
@@ -44,6 +44,8 @@ public final class ShadowNodeConverter {
     
     private static final String RULE_NAME_PATTERN = "/([\\w\\-]+)?";
     
+    private static final String RULE_VERSION = "/([\\w\\-]+)/versions/([\\w\\-]+)$";
+    
     /**
      * Get data source path.
      *
@@ -178,4 +180,40 @@ public final class ShadowNodeConverter {
         Matcher matcher = pattern.matcher(rulePath);
         return matcher.find() ? Optional.of(matcher.group(3)) : Optional.empty();
     }
+    
+    /**
+     * Get data source version.
+     *
+     * @param rulePath rule path
+     * @return data source version
+     */
+    public static Optional<String> getDataSourceVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + DATA_SOURCES_NODE + RULE_VERSION, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(4)) : Optional.empty();
+    }
+    
+    /**
+     * Get table version.
+     *
+     * @param rulePath rule path
+     * @return table version
+     */
+    public static Optional<String> getTableVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + TABLES_NODE + RULE_VERSION, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(4)) : Optional.empty();
+    }
+    
+    /**
+     * Get algorithm version.
+     *
+     * @param rulePath rule path
+     * @return algorithm version
+     */
+    public static Optional<String> getAlgorithmVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + ALGORITHMS_NODE + RULE_VERSION, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(4)) : Optional.empty();
+    }
 }
diff --git a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/subscriber/ShadowConfigurationSubscriber.java b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/subscriber/ShadowConfigurationSubscriber.java
index ebb47aeb693..c87ed38eec5 100644
--- a/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/subscriber/ShadowConfigurationSubscriber.java
+++ b/features/shadow/core/src/main/java/org/apache/shardingsphere/shadow/subscriber/ShadowConfigurationSubscriber.java
@@ -58,6 +58,9 @@ public final class ShadowConfigurationSubscriber implements RuleConfigurationSub
      */
     @Subscribe
     public synchronized void renew(final AddShadowConfigurationEvent event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         ShadowDataSourceConfiguration needToAddedConfig = event.getConfig();
         Optional<ShadowRule> rule = database.getRuleMetaData().findSingleRule(ShadowRule.class);
@@ -80,6 +83,9 @@ public final class ShadowConfigurationSubscriber implements RuleConfigurationSub
      */
     @Subscribe
     public synchronized void renew(final AlterShadowConfigurationEvent event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         ShadowDataSourceConfiguration needToAlteredConfig = event.getConfig();
         ShadowRuleConfiguration config = (ShadowRuleConfiguration) database.getRuleMetaData().getSingleRule(ShadowRule.class).getConfiguration();
@@ -95,6 +101,9 @@ public final class ShadowConfigurationSubscriber implements RuleConfigurationSub
      */
     @Subscribe
     public synchronized void renew(final DeleteShadowConfigurationEvent event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         ShadowRuleConfiguration config = (ShadowRuleConfiguration) database.getRuleMetaData().getSingleRule(ShadowRule.class).getConfiguration();
         config.getDataSources().removeIf(each -> each.getName().equals(event.getDataSourceName()));
diff --git a/features/shadow/core/src/test/java/org/apache/shardingsphere/shadow/metadata/converter/ShadowNodeConverterTest.java b/features/shadow/core/src/test/java/org/apache/shardingsphere/shadow/metadata/converter/ShadowNodeConverterTest.java
index 2f8eadc0751..7c006b126cb 100644
--- a/features/shadow/core/src/test/java/org/apache/shardingsphere/shadow/metadata/converter/ShadowNodeConverterTest.java
+++ b/features/shadow/core/src/test/java/org/apache/shardingsphere/shadow/metadata/converter/ShadowNodeConverterTest.java
@@ -82,4 +82,25 @@ class ShadowNodeConverterTest {
         assertTrue(actual.isPresent());
         assertThat(actual.get(), is("SQL_HINT"));
     }
+    
+    @Test
+    void assertGetDataSourceVersion() {
+        Optional<String> actual = ShadowNodeConverter.getDataSourceVersion("/metadata/foo_db/rules/shadow/data_sources/shadow_database/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
+    
+    @Test
+    void assertGetTableVersion() {
+        Optional<String> actual = ShadowNodeConverter.getTableVersion("/metadata/foo_db/rules/shadow/tables/shadow_table/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
+    
+    @Test
+    void assertGetAlgorithmVersion() {
+        Optional<String> actual = ShadowNodeConverter.getAlgorithmVersion("/metadata/foo_db/rules/shadow/algorithms/user_id_insert_match_algorithm/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/ShardingRuleConfigurationEventBuilder.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/ShardingRuleConfigurationEventBuilder.java
index 6c43f0e07ec..106e10f330a 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/ShardingRuleConfigurationEventBuilder.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/ShardingRuleConfigurationEventBuilder.java
@@ -96,88 +96,121 @@ public final class ShardingRuleConfigurationEventBuilder implements RuleConfigur
         }
         Optional<String> tableName = ShardingNodeConverter.getTableName(event.getKey());
         if (tableName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
-            return createShardingTableConfigEvent(databaseName, tableName.get(), event);
+            Optional<String> tableNameVersion = ShardingNodeConverter.getTableNameVersion(event.getKey());
+            if (tableNameVersion.isPresent()) {
+                return createShardingTableConfigEvent(databaseName, tableName.get(), Integer.parseInt(tableNameVersion.get()), event);   
+            }
         }
         Optional<String> autoTableName = ShardingNodeConverter.getAutoTableName(event.getKey());
         if (autoTableName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
-            return createShardingAutoTableConfigEvent(databaseName, autoTableName.get(), event);
+            Optional<String> autoTableNameVersion = ShardingNodeConverter.getAutoTableNameVersion(event.getKey());
+            if (autoTableNameVersion.isPresent()) {
+                return createShardingAutoTableConfigEvent(databaseName, autoTableName.get(), Integer.parseInt(autoTableNameVersion.get()), event);   
+            }
         }
         Optional<String> bindingTableName = ShardingNodeConverter.getBindingTableName(event.getKey());
         if (bindingTableName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
-            return createShardingTableReferenceConfigEvent(databaseName, bindingTableName.get(), event);
-        }
-        if (ShardingNodeConverter.isBroadcastTablePath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
-            return createBroadcastTableConfigEvent(databaseName, event);
+            Optional<String> bingingTableNameVersion = ShardingNodeConverter.getBindingTableNameVersion(event.getKey());
+            if (bingingTableNameVersion.isPresent()) {
+                return createShardingTableReferenceConfigEvent(databaseName, bindingTableName.get(), Integer.parseInt(bingingTableNameVersion.get()), event);
+            }
         }
         if (ShardingNodeConverter.isDefaultDatabaseStrategyPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
-            return createDefaultDatabaseStrategyConfigEvent(databaseName, event);
+            Optional<String> defaultDatabaseStrategyVersion = ShardingNodeConverter.getDefaultDatabaseStrategyVersion(event.getKey());
+            if (defaultDatabaseStrategyVersion.isPresent()) {
+                return createDefaultDatabaseStrategyConfigEvent(databaseName, Integer.parseInt(defaultDatabaseStrategyVersion.get()), event);   
+            }
         }
         if (ShardingNodeConverter.isDefaultTableStrategyPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
-            return createDefaultTableStrategyConfigEvent(databaseName, event);
+            Optional<String> defaultTableStrategyVersion = ShardingNodeConverter.getDefaultTableStrategyVersion(event.getKey());
+            if (defaultTableStrategyVersion.isPresent()) {
+                return createDefaultTableStrategyConfigEvent(databaseName, Integer.parseInt(defaultTableStrategyVersion.get()), event);   
+            }
         }
         if (ShardingNodeConverter.isDefaultKeyGenerateStrategyPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
-            return createDefaultKeyGenerateStrategyConfigEvent(databaseName, event);
+            Optional<String> defaultKeyGenerateStrategyVersion = ShardingNodeConverter.getDefaultKeyGenerateStrategyVersion(event.getKey());
+            if (defaultKeyGenerateStrategyVersion.isPresent()) {
+                return createDefaultKeyGenerateStrategyConfigEvent(databaseName, Integer.parseInt(defaultKeyGenerateStrategyVersion.get()), event);   
+            }
         }
         if (ShardingNodeConverter.isDefaultAuditStrategyPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
-            return createDefaultShardingAuditorStrategyConfigEvent(databaseName, event);
+            Optional<String> defaultAuditStrategyVersion = ShardingNodeConverter.getDefaultAuditStrategyVersion(event.getKey());
+            if (defaultAuditStrategyVersion.isPresent()) {
+                return createDefaultShardingAuditorStrategyConfigEvent(databaseName, Integer.parseInt(defaultAuditStrategyVersion.get()), event);   
+            }
         }
         if (ShardingNodeConverter.isDefaultShardingColumnPath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
-            return createDefaultShardingColumnEvent(databaseName, event);
+            Optional<String> defaultShardingColumnVersion = ShardingNodeConverter.getDefaultShardingColumnVersion(event.getKey());
+            if (defaultShardingColumnVersion.isPresent()) {
+                return createDefaultShardingColumnEvent(databaseName, Integer.parseInt(defaultShardingColumnVersion.get()), event);   
+            }
         }
         Optional<String> algorithmName = ShardingNodeConverter.getShardingAlgorithmName(event.getKey());
         if (algorithmName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
-            return createShardingAlgorithmEvent(databaseName, algorithmName.get(), event);
+            Optional<String> algorithmVersion = ShardingNodeConverter.getShardingAlgorithmVersion(event.getKey());
+            if (algorithmVersion.isPresent()) {
+                return createShardingAlgorithmEvent(databaseName, algorithmName.get(), Integer.parseInt(algorithmVersion.get()), event);   
+            }
         }
         Optional<String> keyGeneratorName = ShardingNodeConverter.getKeyGeneratorName(event.getKey());
         if (keyGeneratorName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
-            return createKeyGeneratorEvent(databaseName, keyGeneratorName.get(), event);
+            Optional<String> keyGeneratorVersion = ShardingNodeConverter.getKeyGeneratorVersion(event.getKey());
+            if (keyGeneratorVersion.isPresent()) {
+                return createKeyGeneratorEvent(databaseName, keyGeneratorName.get(), Integer.parseInt(keyGeneratorVersion.get()), event);   
+            }
         }
         Optional<String> auditorName = ShardingNodeConverter.getAuditorName(event.getKey());
         if (auditorName.isPresent() && !Strings.isNullOrEmpty(event.getValue())) {
-            return createAuditorEvent(databaseName, auditorName.get(), event);
+            Optional<String> auditorVersion = ShardingNodeConverter.getAuditorVersion(event.getKey());
+            if (auditorVersion.isPresent()) {
+                return createAuditorEvent(databaseName, auditorName.get(), Integer.parseInt(auditorVersion.get()), event);   
+            }
         }
         if (ShardingNodeConverter.isShardingCachePath(event.getKey()) && !Strings.isNullOrEmpty(event.getValue())) {
-            return createShardingCacheEvent(databaseName, event);
+            Optional<String> shardingCacheVersion = ShardingNodeConverter.getShardingCacheVersion(event.getKey());
+            if (shardingCacheVersion.isPresent()) {
+                return createShardingCacheEvent(databaseName, Integer.parseInt(shardingCacheVersion.get()), event);   
+            }
         }
         return Optional.empty();
     }
     
-    private Optional<GovernanceEvent> createShardingTableConfigEvent(final String databaseName, final String tableName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createShardingTableConfigEvent(final String databaseName, final String tableName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType()) {
-            return Optional.of(new AddShardingTableConfigurationEvent<>(databaseName, swapShardingTableRuleConfig(event.getValue())));
+            return Optional.of(new AddShardingTableConfigurationEvent<>(databaseName, swapShardingTableRuleConfig(event.getValue()), event.getKey(), version));
         }
         if (Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterShardingTableConfigurationEvent<>(databaseName, tableName, swapShardingTableRuleConfig(event.getValue())));
+            return Optional.of(new AlterShardingTableConfigurationEvent<>(databaseName, tableName, swapShardingTableRuleConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteShardingTableConfigurationEvent(databaseName, tableName));
+        return Optional.of(new DeleteShardingTableConfigurationEvent(databaseName, tableName, event.getKey(), version));
     }
     
     private ShardingTableRuleConfiguration swapShardingTableRuleConfig(final String yamlContext) {
         return new YamlShardingTableRuleConfigurationSwapper().swapToObject(YamlEngine.unmarshal(yamlContext, YamlTableRuleConfiguration.class));
     }
     
-    private Optional<GovernanceEvent> createShardingAutoTableConfigEvent(final String databaseName, final String tableName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createShardingAutoTableConfigEvent(final String databaseName, final String tableName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType()) {
-            return Optional.of(new AddShardingAutoTableConfigurationEvent<>(databaseName, swapShardingAutoTableRuleConfig(event.getValue())));
+            return Optional.of(new AddShardingAutoTableConfigurationEvent<>(databaseName, swapShardingAutoTableRuleConfig(event.getValue()), event.getKey(), version));
         }
         if (Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterShardingAutoTableConfigurationEvent<>(databaseName, tableName, swapShardingAutoTableRuleConfig(event.getValue())));
+            return Optional.of(new AlterShardingAutoTableConfigurationEvent<>(databaseName, tableName, swapShardingAutoTableRuleConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteShardingAutoTableConfigurationEvent(databaseName, tableName));
+        return Optional.of(new DeleteShardingAutoTableConfigurationEvent(databaseName, tableName, event.getKey(), version));
     }
     
     private ShardingAutoTableRuleConfiguration swapShardingAutoTableRuleConfig(final String yamlContext) {
         return new YamlShardingAutoTableRuleConfigurationSwapper().swapToObject(YamlEngine.unmarshal(yamlContext, YamlShardingAutoTableRuleConfiguration.class));
     }
     
-    private Optional<GovernanceEvent> createShardingTableReferenceConfigEvent(final String databaseName, final String tableName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createShardingTableReferenceConfigEvent(final String databaseName, final String tableName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType()) {
-            return Optional.of(new AddShardingAutoTableConfigurationEvent<>(databaseName, swapShardingTableReferenceRuleConfig(event.getValue())));
+            return Optional.of(new AddShardingAutoTableConfigurationEvent<>(databaseName, swapShardingTableReferenceRuleConfig(event.getValue()), event.getKey(), version));
         }
         if (Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterShardingAutoTableConfigurationEvent<>(databaseName, tableName, swapShardingTableReferenceRuleConfig(event.getValue())));
+            return Optional.of(new AlterShardingAutoTableConfigurationEvent<>(databaseName, tableName, swapShardingTableReferenceRuleConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteShardingAutoTableConfigurationEvent(databaseName, tableName));
+        return Optional.of(new DeleteShardingAutoTableConfigurationEvent(databaseName, tableName, event.getKey(), version));
     }
     
     private ShardingTableReferenceRuleConfiguration swapShardingTableReferenceRuleConfig(final String yamlContext) {
@@ -185,111 +218,111 @@ public final class ShardingRuleConfigurationEventBuilder implements RuleConfigur
     }
     
     @SuppressWarnings("unchecked")
-    private Optional<GovernanceEvent> createBroadcastTableConfigEvent(final String databaseName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createBroadcastTableConfigEvent(final String databaseName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType()) {
-            return Optional.of(new AddBroadcastTableConfigurationEvent(databaseName, YamlEngine.unmarshal(event.getValue(), Collection.class)));
+            return Optional.of(new AddBroadcastTableConfigurationEvent(databaseName, YamlEngine.unmarshal(event.getValue(), Collection.class), event.getKey(), version));
         }
         if (Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterBroadcastTableConfigurationEvent(databaseName, YamlEngine.unmarshal(event.getValue(), Collection.class)));
+            return Optional.of(new AlterBroadcastTableConfigurationEvent(databaseName, YamlEngine.unmarshal(event.getValue(), Collection.class), event.getKey(), version));
         }
-        return Optional.of(new DeleteBroadcastTableConfigurationEvent(databaseName));
+        return Optional.of(new DeleteBroadcastTableConfigurationEvent(databaseName, event.getKey(), version));
     }
     
-    private Optional<GovernanceEvent> createDefaultDatabaseStrategyConfigEvent(final String databaseName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createDefaultDatabaseStrategyConfigEvent(final String databaseName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType()) {
-            return Optional.of(new AddDatabaseShardingStrategyConfigurationEvent(databaseName, swapShardingStrategyConfig(event.getValue())));
+            return Optional.of(new AddDatabaseShardingStrategyConfigurationEvent(databaseName, swapShardingStrategyConfig(event.getValue()), event.getKey(), version));
         }
         if (Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterDatabaseShardingStrategyConfigurationEvent(databaseName, swapShardingStrategyConfig(event.getValue())));
+            return Optional.of(new AlterDatabaseShardingStrategyConfigurationEvent(databaseName, swapShardingStrategyConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteDatabaseShardingStrategyConfigurationEvent(databaseName));
+        return Optional.of(new DeleteDatabaseShardingStrategyConfigurationEvent(databaseName, event.getKey(), version));
     }
     
-    private Optional<GovernanceEvent> createDefaultTableStrategyConfigEvent(final String databaseName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createDefaultTableStrategyConfigEvent(final String databaseName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType()) {
-            return Optional.of(new AddTableShardingStrategyConfigurationEvent(databaseName, swapShardingStrategyConfig(event.getValue())));
+            return Optional.of(new AddTableShardingStrategyConfigurationEvent(databaseName, swapShardingStrategyConfig(event.getValue()), event.getKey(), version));
         }
         if (Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterTableShardingStrategyConfigurationEvent(databaseName, swapShardingStrategyConfig(event.getValue())));
+            return Optional.of(new AlterTableShardingStrategyConfigurationEvent(databaseName, swapShardingStrategyConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteTableShardingStrategyConfigurationEvent(databaseName));
+        return Optional.of(new DeleteTableShardingStrategyConfigurationEvent(databaseName, event.getKey(), version));
     }
     
     private ShardingStrategyConfiguration swapShardingStrategyConfig(final String yamlContext) {
         return new YamlShardingStrategyConfigurationSwapper().swapToObject(YamlEngine.unmarshal(yamlContext, YamlShardingStrategyConfiguration.class));
     }
     
-    private Optional<GovernanceEvent> createDefaultKeyGenerateStrategyConfigEvent(final String databaseName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createDefaultKeyGenerateStrategyConfigEvent(final String databaseName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType()) {
-            return Optional.of(new AddKeyGenerateStrategyConfigurationEvent(databaseName, swapKeyGenerateStrategyConfig(event.getValue())));
+            return Optional.of(new AddKeyGenerateStrategyConfigurationEvent(databaseName, swapKeyGenerateStrategyConfig(event.getValue()), event.getKey(), version));
         }
         if (Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterKeyGenerateStrategyConfigurationEvent(databaseName, swapKeyGenerateStrategyConfig(event.getValue())));
+            return Optional.of(new AlterKeyGenerateStrategyConfigurationEvent(databaseName, swapKeyGenerateStrategyConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteKeyGenerateStrategyConfigurationEvent(databaseName));
+        return Optional.of(new DeleteKeyGenerateStrategyConfigurationEvent(databaseName, event.getKey(), version));
     }
     
     private KeyGenerateStrategyConfiguration swapKeyGenerateStrategyConfig(final String yamlContext) {
         return new YamlKeyGenerateStrategyConfigurationSwapper().swapToObject(YamlEngine.unmarshal(yamlContext, YamlKeyGenerateStrategyConfiguration.class));
     }
     
-    private Optional<GovernanceEvent> createDefaultShardingAuditorStrategyConfigEvent(final String databaseName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createDefaultShardingAuditorStrategyConfigEvent(final String databaseName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType()) {
-            return Optional.of(new AddShardingAuditorStrategyConfigurationEvent(databaseName, swapShardingAuditorStrategyConfig(event.getValue())));
+            return Optional.of(new AddShardingAuditorStrategyConfigurationEvent(databaseName, swapShardingAuditorStrategyConfig(event.getValue()), event.getKey(), version));
         }
         if (Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterShardingAuditorStrategyConfigurationEvent(databaseName, swapShardingAuditorStrategyConfig(event.getValue())));
+            return Optional.of(new AlterShardingAuditorStrategyConfigurationEvent(databaseName, swapShardingAuditorStrategyConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteShardingAuditorStrategyConfigurationEvent(databaseName));
+        return Optional.of(new DeleteShardingAuditorStrategyConfigurationEvent(databaseName, event.getKey(), version));
     }
     
     private ShardingAuditStrategyConfiguration swapShardingAuditorStrategyConfig(final String yamlContext) {
         return new YamlShardingAuditStrategyConfigurationSwapper().swapToObject(YamlEngine.unmarshal(yamlContext, YamlShardingAuditStrategyConfiguration.class));
     }
     
-    private Optional<GovernanceEvent> createDefaultShardingColumnEvent(final String databaseName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createDefaultShardingColumnEvent(final String databaseName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType()) {
-            return Optional.of(new AddDefaultShardingColumnEvent(databaseName, event.getValue()));
+            return Optional.of(new AddDefaultShardingColumnEvent(databaseName, event.getValue(), event.getKey(), version));
         }
         if (Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterDefaultShardingColumnEvent(databaseName, event.getValue()));
+            return Optional.of(new AlterDefaultShardingColumnEvent(databaseName, event.getValue(), event.getKey(), version));
         }
-        return Optional.of(new DeleteDefaultShardingColumnEvent(databaseName));
+        return Optional.of(new DeleteDefaultShardingColumnEvent(databaseName, event.getKey(), version));
     }
     
-    private Optional<GovernanceEvent> createShardingAlgorithmEvent(final String databaseName, final String algorithmName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createShardingAlgorithmEvent(final String databaseName, final String algorithmName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType() || Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterShardingAlgorithmEvent(databaseName, algorithmName, swapToAlgorithmConfig(event.getValue())));
+            return Optional.of(new AlterShardingAlgorithmEvent(databaseName, algorithmName, swapToAlgorithmConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteShardingAlgorithmEvent(databaseName, algorithmName));
+        return Optional.of(new DeleteShardingAlgorithmEvent(databaseName, algorithmName, event.getKey(), version));
     }
     
-    private Optional<GovernanceEvent> createKeyGeneratorEvent(final String databaseName, final String algorithmName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createKeyGeneratorEvent(final String databaseName, final String algorithmName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType() || Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterKeyGeneratorEvent(databaseName, algorithmName, swapToAlgorithmConfig(event.getValue())));
+            return Optional.of(new AlterKeyGeneratorEvent(databaseName, algorithmName, swapToAlgorithmConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteKeyGeneratorEvent(databaseName, algorithmName));
+        return Optional.of(new DeleteKeyGeneratorEvent(databaseName, algorithmName, event.getKey(), version));
     }
     
-    private Optional<GovernanceEvent> createAuditorEvent(final String databaseName, final String algorithmName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createAuditorEvent(final String databaseName, final String algorithmName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType() || Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterAuditorEvent(databaseName, algorithmName, swapToAlgorithmConfig(event.getValue())));
+            return Optional.of(new AlterAuditorEvent(databaseName, algorithmName, swapToAlgorithmConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteAuditorEvent(databaseName, algorithmName));
+        return Optional.of(new DeleteAuditorEvent(databaseName, algorithmName, event.getKey(), version));
     }
     
     private AlgorithmConfiguration swapToAlgorithmConfig(final String yamlContext) {
         return new YamlAlgorithmConfigurationSwapper().swapToObject(YamlEngine.unmarshal(yamlContext, YamlAlgorithmConfiguration.class));
     }
     
-    private Optional<GovernanceEvent> createShardingCacheEvent(final String databaseName, final DataChangedEvent event) {
+    private Optional<GovernanceEvent> createShardingCacheEvent(final String databaseName, final int version, final DataChangedEvent event) {
         if (Type.ADDED == event.getType()) {
-            return Optional.of(new AddShardingCacheConfigurationEvent(databaseName, swapToShardingCacheConfig(event.getValue())));
+            return Optional.of(new AddShardingCacheConfigurationEvent(databaseName, swapToShardingCacheConfig(event.getValue()), event.getKey(), version));
         }
         if (Type.UPDATED == event.getType()) {
-            return Optional.of(new AlterShardingCacheConfigurationEvent(databaseName, swapToShardingCacheConfig(event.getValue())));
+            return Optional.of(new AlterShardingCacheConfigurationEvent(databaseName, swapToShardingCacheConfig(event.getValue()), event.getKey(), version));
         }
-        return Optional.of(new DeleteShardingCacheConfigurationEvent(databaseName));
+        return Optional.of(new DeleteShardingCacheConfigurationEvent(databaseName, event.getKey(), version));
     }
     
     private ShardingCacheConfiguration swapToShardingCacheConfig(final String yamlContext) {
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/auditor/AlterAuditorEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/auditor/AlterAuditorEvent.java
index 732befe03fd..3cec62e0bdc 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/auditor/AlterAuditorEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/auditor/AlterAuditorEvent.java
@@ -34,4 +34,8 @@ public final class AlterAuditorEvent implements GovernanceEvent {
     private final String auditorName;
     
     private final AlgorithmConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/auditor/DeleteAuditorEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/auditor/DeleteAuditorEvent.java
index 0d18f6f42cb..4af20de8d8d 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/auditor/DeleteAuditorEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/auditor/DeleteAuditorEvent.java
@@ -31,4 +31,8 @@ public final class DeleteAuditorEvent implements GovernanceEvent {
     private final String databaseName;
     
     private final String auditorName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/keygenerator/AlterKeyGeneratorEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/keygenerator/AlterKeyGeneratorEvent.java
index 8851eedb6f4..3d296a4a4bd 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/keygenerator/AlterKeyGeneratorEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/keygenerator/AlterKeyGeneratorEvent.java
@@ -34,4 +34,8 @@ public final class AlterKeyGeneratorEvent implements GovernanceEvent {
     private final String keyGeneratorName;
     
     private final AlgorithmConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/keygenerator/DeleteKeyGeneratorEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/keygenerator/DeleteKeyGeneratorEvent.java
index a56bfa0d959..10adf800c7e 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/keygenerator/DeleteKeyGeneratorEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/keygenerator/DeleteKeyGeneratorEvent.java
@@ -31,4 +31,8 @@ public final class DeleteKeyGeneratorEvent implements GovernanceEvent {
     private final String databaseName;
     
     private final String keyGeneratorName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/sharding/AlterShardingAlgorithmEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/sharding/AlterShardingAlgorithmEvent.java
index bc3b22dd77b..9d384e5993b 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/sharding/AlterShardingAlgorithmEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/sharding/AlterShardingAlgorithmEvent.java
@@ -34,4 +34,8 @@ public final class AlterShardingAlgorithmEvent implements GovernanceEvent {
     private final String algorithmName;
     
     private final AlgorithmConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/sharding/DeleteShardingAlgorithmEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/sharding/DeleteShardingAlgorithmEvent.java
index ec6363a8eb0..e514033d67d 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/sharding/DeleteShardingAlgorithmEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/algorithm/sharding/DeleteShardingAlgorithmEvent.java
@@ -31,4 +31,8 @@ public final class DeleteShardingAlgorithmEvent implements GovernanceEvent {
     private final String databaseName;
     
     private final String algorithmName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/cache/AddShardingCacheConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/cache/AddShardingCacheConfigurationEvent.java
index dfaeea32231..0195fc1263a 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/cache/AddShardingCacheConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/cache/AddShardingCacheConfigurationEvent.java
@@ -32,4 +32,8 @@ public final class AddShardingCacheConfigurationEvent implements GovernanceEvent
     private final String databaseName;
     
     private final ShardingCacheConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/cache/AlterShardingCacheConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/cache/AlterShardingCacheConfigurationEvent.java
index beaea70f09c..c99f3e890e1 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/cache/AlterShardingCacheConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/cache/AlterShardingCacheConfigurationEvent.java
@@ -32,4 +32,8 @@ public final class AlterShardingCacheConfigurationEvent implements GovernanceEve
     private final String databaseName;
     
     private final ShardingCacheConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/cache/DeleteShardingCacheConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/cache/DeleteShardingCacheConfigurationEvent.java
index 9e0878bc652..c3aa7931194 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/cache/DeleteShardingCacheConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/cache/DeleteShardingCacheConfigurationEvent.java
@@ -29,4 +29,8 @@ import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 public final class DeleteShardingCacheConfigurationEvent implements GovernanceEvent {
     
     private final String databaseName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/audit/AddShardingAuditorStrategyConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/audit/AddShardingAuditorStrategyConfigurationEvent.java
index b27f665c1de..332fa8c66a4 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/audit/AddShardingAuditorStrategyConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/audit/AddShardingAuditorStrategyConfigurationEvent.java
@@ -32,4 +32,8 @@ public final class AddShardingAuditorStrategyConfigurationEvent implements Gover
     private final String databaseName;
     
     private final ShardingAuditStrategyConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/audit/AlterShardingAuditorStrategyConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/audit/AlterShardingAuditorStrategyConfigurationEvent.java
index b3123e7797b..2ef6ce7318d 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/audit/AlterShardingAuditorStrategyConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/audit/AlterShardingAuditorStrategyConfigurationEvent.java
@@ -32,4 +32,8 @@ public final class AlterShardingAuditorStrategyConfigurationEvent implements Gov
     private final String databaseName;
     
     private final ShardingAuditStrategyConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/audit/DeleteShardingAuditorStrategyConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/audit/DeleteShardingAuditorStrategyConfigurationEvent.java
index 8f30a81b869..1f9b02def80 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/audit/DeleteShardingAuditorStrategyConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/audit/DeleteShardingAuditorStrategyConfigurationEvent.java
@@ -29,4 +29,8 @@ import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 public final class DeleteShardingAuditorStrategyConfigurationEvent implements GovernanceEvent {
     
     private final String databaseName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/database/AddDatabaseShardingStrategyConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/database/AddDatabaseShardingStrategyConfigurationEvent.java
index 7b3bf1148bc..04e01af0f49 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/database/AddDatabaseShardingStrategyConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/database/AddDatabaseShardingStrategyConfigurationEvent.java
@@ -32,4 +32,8 @@ public final class AddDatabaseShardingStrategyConfigurationEvent implements Gove
     private final String databaseName;
     
     private final ShardingStrategyConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/database/AlterDatabaseShardingStrategyConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/database/AlterDatabaseShardingStrategyConfigurationEvent.java
index eaed724e4ee..7733e3d24fe 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/database/AlterDatabaseShardingStrategyConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/database/AlterDatabaseShardingStrategyConfigurationEvent.java
@@ -32,4 +32,8 @@ public final class AlterDatabaseShardingStrategyConfigurationEvent implements Go
     private final String databaseName;
     
     private final ShardingStrategyConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/database/DeleteDatabaseShardingStrategyConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/database/DeleteDatabaseShardingStrategyConfigurationEvent.java
index a6043d15ad9..d83cad340ef 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/database/DeleteDatabaseShardingStrategyConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/database/DeleteDatabaseShardingStrategyConfigurationEvent.java
@@ -29,4 +29,8 @@ import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 public final class DeleteDatabaseShardingStrategyConfigurationEvent implements GovernanceEvent {
     
     private final String databaseName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/keygenerate/AddKeyGenerateStrategyConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/keygenerate/AddKeyGenerateStrategyConfigurationEvent.java
index 7fb4ac0b231..d934edd1f5d 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/keygenerate/AddKeyGenerateStrategyConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/keygenerate/AddKeyGenerateStrategyConfigurationEvent.java
@@ -32,4 +32,8 @@ public final class AddKeyGenerateStrategyConfigurationEvent implements Governanc
     private final String databaseName;
     
     private final KeyGenerateStrategyConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/keygenerate/AlterKeyGenerateStrategyConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/keygenerate/AlterKeyGenerateStrategyConfigurationEvent.java
index 920ef33a744..9bd670da19e 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/keygenerate/AlterKeyGenerateStrategyConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/keygenerate/AlterKeyGenerateStrategyConfigurationEvent.java
@@ -32,4 +32,8 @@ public final class AlterKeyGenerateStrategyConfigurationEvent implements Governa
     private final String databaseName;
     
     private final KeyGenerateStrategyConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/keygenerate/DeleteKeyGenerateStrategyConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/keygenerate/DeleteKeyGenerateStrategyConfigurationEvent.java
index 5ea261f2bdc..30e61a61472 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/keygenerate/DeleteKeyGenerateStrategyConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/keygenerate/DeleteKeyGenerateStrategyConfigurationEvent.java
@@ -29,4 +29,8 @@ import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 public final class DeleteKeyGenerateStrategyConfigurationEvent implements GovernanceEvent {
     
     private final String databaseName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/shardingcolumn/AddDefaultShardingColumnEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/shardingcolumn/AddDefaultShardingColumnEvent.java
index 1367b535c50..7b6dc682ef1 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/shardingcolumn/AddDefaultShardingColumnEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/shardingcolumn/AddDefaultShardingColumnEvent.java
@@ -31,4 +31,8 @@ public final class AddDefaultShardingColumnEvent implements GovernanceEvent {
     private final String databaseName;
     
     private final String config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/shardingcolumn/AlterDefaultShardingColumnEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/shardingcolumn/AlterDefaultShardingColumnEvent.java
index f71cbfaafba..96f87c7bce1 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/shardingcolumn/AlterDefaultShardingColumnEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/shardingcolumn/AlterDefaultShardingColumnEvent.java
@@ -31,4 +31,8 @@ public final class AlterDefaultShardingColumnEvent implements GovernanceEvent {
     private final String databaseName;
     
     private final String config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/shardingcolumn/DeleteDefaultShardingColumnEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/shardingcolumn/DeleteDefaultShardingColumnEvent.java
index 5b68a6f910c..8a48e126d9c 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/shardingcolumn/DeleteDefaultShardingColumnEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/shardingcolumn/DeleteDefaultShardingColumnEvent.java
@@ -29,4 +29,8 @@ import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 public final class DeleteDefaultShardingColumnEvent implements GovernanceEvent {
     
     private final String databaseName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/table/AddTableShardingStrategyConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/table/AddTableShardingStrategyConfigurationEvent.java
index ec135c56f5d..47f74b96091 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/table/AddTableShardingStrategyConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/table/AddTableShardingStrategyConfigurationEvent.java
@@ -32,4 +32,8 @@ public final class AddTableShardingStrategyConfigurationEvent implements Governa
     private final String databaseName;
     
     private final ShardingStrategyConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/table/AlterTableShardingStrategyConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/table/AlterTableShardingStrategyConfigurationEvent.java
index 29750e304ab..75e511608fe 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/table/AlterTableShardingStrategyConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/table/AlterTableShardingStrategyConfigurationEvent.java
@@ -32,4 +32,8 @@ public final class AlterTableShardingStrategyConfigurationEvent implements Gover
     private final String databaseName;
     
     private final ShardingStrategyConfiguration config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/table/DeleteTableShardingStrategyConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/table/DeleteTableShardingStrategyConfigurationEvent.java
index 146b9445aeb..06edf5c322a 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/table/DeleteTableShardingStrategyConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/strategy/table/DeleteTableShardingStrategyConfigurationEvent.java
@@ -29,4 +29,8 @@ import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 public final class DeleteTableShardingStrategyConfigurationEvent implements GovernanceEvent {
     
     private final String databaseName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/auto/AddShardingAutoTableConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/auto/AddShardingAutoTableConfigurationEvent.java
index 2e158285274..5ec27146340 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/auto/AddShardingAutoTableConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/auto/AddShardingAutoTableConfigurationEvent.java
@@ -33,4 +33,8 @@ public final class AddShardingAutoTableConfigurationEvent<T> implements Governan
     private final String databaseName;
     
     private final T config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/auto/AlterShardingAutoTableConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/auto/AlterShardingAutoTableConfigurationEvent.java
index 6b1593e789f..40296c7bf46 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/auto/AlterShardingAutoTableConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/auto/AlterShardingAutoTableConfigurationEvent.java
@@ -35,4 +35,8 @@ public final class AlterShardingAutoTableConfigurationEvent<T> implements Govern
     private final String tableName;
     
     private final T config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/auto/DeleteShardingAutoTableConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/auto/DeleteShardingAutoTableConfigurationEvent.java
index b41ff63eb70..68f8f854720 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/auto/DeleteShardingAutoTableConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/auto/DeleteShardingAutoTableConfigurationEvent.java
@@ -31,4 +31,8 @@ public final class DeleteShardingAutoTableConfigurationEvent implements Governan
     private final String databaseName;
     
     private final String tableName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/broadcast/AddBroadcastTableConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/broadcast/AddBroadcastTableConfigurationEvent.java
index d91d41e4e9b..035f18b59a0 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/broadcast/AddBroadcastTableConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/broadcast/AddBroadcastTableConfigurationEvent.java
@@ -33,4 +33,8 @@ public final class AddBroadcastTableConfigurationEvent implements GovernanceEven
     private final String databaseName;
     
     private final Collection<String> config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/broadcast/AlterBroadcastTableConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/broadcast/AlterBroadcastTableConfigurationEvent.java
index 13a0fd4397a..67e75bb3bd1 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/broadcast/AlterBroadcastTableConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/broadcast/AlterBroadcastTableConfigurationEvent.java
@@ -33,4 +33,8 @@ public final class AlterBroadcastTableConfigurationEvent implements GovernanceEv
     private final String databaseName;
     
     private final Collection<String> config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/broadcast/DeleteBroadcastTableConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/broadcast/DeleteBroadcastTableConfigurationEvent.java
index 53d197cf0b7..dd0e82b9f1a 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/broadcast/DeleteBroadcastTableConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/broadcast/DeleteBroadcastTableConfigurationEvent.java
@@ -29,4 +29,8 @@ import org.apache.shardingsphere.infra.rule.event.GovernanceEvent;
 public final class DeleteBroadcastTableConfigurationEvent implements GovernanceEvent {
     
     private final String databaseName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/sharding/AddShardingTableConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/sharding/AddShardingTableConfigurationEvent.java
index ce0c1a7f31a..71870cc9c93 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/sharding/AddShardingTableConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/sharding/AddShardingTableConfigurationEvent.java
@@ -33,4 +33,8 @@ public final class AddShardingTableConfigurationEvent<T> implements GovernanceEv
     private final String databaseName;
     
     private final T config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/sharding/AlterShardingTableConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/sharding/AlterShardingTableConfigurationEvent.java
index f60a0c44445..2f0470f1ec5 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/sharding/AlterShardingTableConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/sharding/AlterShardingTableConfigurationEvent.java
@@ -35,4 +35,8 @@ public final class AlterShardingTableConfigurationEvent<T> implements Governance
     private final String tableName;
     
     private final T config;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/sharding/DeleteShardingTableConfigurationEvent.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/sharding/DeleteShardingTableConfigurationEvent.java
index 53ed30de9af..3ee92742afd 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/sharding/DeleteShardingTableConfigurationEvent.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/event/table/sharding/DeleteShardingTableConfigurationEvent.java
@@ -31,4 +31,8 @@ public final class DeleteShardingTableConfigurationEvent implements GovernanceEv
     private final String databaseName;
     
     private final String tableName;
+    
+    private final String versionKey;
+    
+    private final int version;
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/metadata/converter/ShardingNodeConverter.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/metadata/converter/ShardingNodeConverter.java
index 59d82486a5a..f19297654ab 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/metadata/converter/ShardingNodeConverter.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/metadata/converter/ShardingNodeConverter.java
@@ -38,8 +38,6 @@ public final class ShardingNodeConverter {
     
     private static final String BINDING_TABLES_NODE = "binding_tables";
     
-    private static final String BROADCAST_TABLES_NODE = "broadcast_tables";
-    
     private static final String DEFAULT_STRATEGIES_NODE = "default_strategies";
     
     private static final String DEFAULT_DATABASE_STRATEGY_NODE = "default_database_strategy";
@@ -64,6 +62,8 @@ public final class ShardingNodeConverter {
     
     private static final String RULE_NAME_PATTERN = "/([\\w\\-]+)?";
     
+    private static final String RULE_VERSION = "/([\\w\\-]+)/versions/([\\w\\-]+)$";
+    
     /**
      * Get table name path.
      *
@@ -94,15 +94,6 @@ public final class ShardingNodeConverter {
         return String.join("/", BINDING_TABLES_NODE, tableName);
     }
     
-    /**
-     * Get broadcast tables path.
-     *
-     * @return broadcast tables path
-     */
-    public static String getBroadcastTablesPath() {
-        return String.join("/", BROADCAST_TABLES_NODE);
-    }
-    
     /**
      * Get default database strategy path.
      *
@@ -235,18 +226,6 @@ public final class ShardingNodeConverter {
         return matcher.find();
     }
     
-    /**
-     * Is broadcast table path.
-     *
-     * @param rulePath rule path
-     * @return true or false
-     */
-    public static boolean isBroadcastTablePath(final String rulePath) {
-        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + BROADCAST_TABLES_NODE + "$", Pattern.CASE_INSENSITIVE);
-        Matcher matcher = pattern.matcher(rulePath);
-        return matcher.find();
-    }
-    
     /**
      * Is default database strategy path.
      *
@@ -426,4 +405,149 @@ public final class ShardingNodeConverter {
         Matcher matcher = pattern.matcher(rulePath);
         return matcher.find() ? Optional.of(matcher.group(3)) : Optional.empty();
     }
+    
+    /**
+     * Get table name version.
+     *
+     * @param rulePath rule path
+     * @return table name version
+     */
+    public static Optional<String> getTableNameVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + TABLES_NODE + RULE_VERSION, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(4)) : Optional.empty();
+    }
+    
+    /**
+     * Get auto table name version.
+     *
+     * @param rulePath rule path
+     * @return auto table name version
+     */
+    public static Optional<String> getAutoTableNameVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + AUTO_TABLES_NODE + RULE_VERSION, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(4)) : Optional.empty();
+    }
+    
+    /**
+     * Get binding table name version.
+     *
+     * @param rulePath rule path
+     * @return binding table name version
+     */
+    public static Optional<String> getBindingTableNameVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + BINDING_TABLES_NODE + RULE_VERSION, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(4)) : Optional.empty();
+    }
+    
+    /**
+     * Get sharding algorithm version.
+     *
+     * @param rulePath rule path
+     * @return sharding algorithm version
+     */
+    public static Optional<String> getDefaultDatabaseStrategyVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + DEFAULT_STRATEGIES_NODE + "/" + DEFAULT_DATABASE_STRATEGY_NODE + "/versions/([\\w\\-]+)$", Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(3)) : Optional.empty();
+    }
+    
+    /**
+     * Get default table strategy version.
+     *
+     * @param rulePath rule path
+     * @return default table strategy version
+     */
+    public static Optional<String> getDefaultTableStrategyVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + DEFAULT_STRATEGIES_NODE + "/" + DEFAULT_TABLE_STRATEGY_NODE + "/versions/([\\w\\-]+)$", Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(3)) : Optional.empty();
+    }
+    
+    /**
+     * Get default key generate strategy version.
+     *
+     * @param rulePath rule path
+     * @return default key generate strategy version
+     */
+    public static Optional<String> getDefaultKeyGenerateStrategyVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + DEFAULT_STRATEGIES_NODE + "/" + DEFAULT_KEY_GENERATE_STRATEGY_NODE + "/versions/([\\w\\-]+)$",
+                Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(3)) : Optional.empty();
+    }
+    
+    /**
+     * Get default audit strategy version.
+     *
+     * @param rulePath rule path
+     * @return default audit strategy version
+     */
+    public static Optional<String> getDefaultAuditStrategyVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + DEFAULT_STRATEGIES_NODE + "/" + DEFAULT_AUDIT_STRATEGY_NODE + "/versions/([\\w\\-]+)$", Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(3)) : Optional.empty();
+    }
+    
+    /**
+     * Get default sharding column version.
+     *
+     * @param rulePath rule path
+     * @return default sharding column version
+     */
+    public static Optional<String> getDefaultShardingColumnVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + DEFAULT_STRATEGIES_NODE + "/" + DEFAULT_SHARDING_COLUMN_NODE + "/versions/([\\w\\-]+)$", Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(3)) : Optional.empty();
+    }
+    
+    /**
+     * Get sharding algorithm version.
+     *
+     * @param rulePath rule path
+     * @return sharding algorithm version
+     */
+    public static Optional<String> getShardingAlgorithmVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + SHARDING_ALGORITHMS_NODE + RULE_VERSION, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(4)) : Optional.empty();
+    }
+    
+    /**
+     * Get key generator version.
+     *
+     * @param rulePath rule path
+     * @return key generator version
+     */
+    public static Optional<String> getKeyGeneratorVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + KEY_GENERATORS_NODE + RULE_VERSION, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(4)) : Optional.empty();
+    }
+    
+    /**
+     * Get auditor version.
+     *
+     * @param rulePath rule path
+     * @return auditor version
+     */
+    public static Optional<String> getAuditorVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + AUDITORS_NODE + RULE_VERSION, Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(4)) : Optional.empty();
+    }
+    
+    /**
+     * Get sharding cache version.
+     *
+     * @param rulePath rule path
+     * @return sharding cache version
+     */
+    public static Optional<String> getShardingCacheVersion(final String rulePath) {
+        Pattern pattern = Pattern.compile(RULES_NODE_PREFIX + ROOT_NODE + "/" + SHARDING_CACHE_NODE + "/versions/([\\w\\-]+)$", Pattern.CASE_INSENSITIVE);
+        Matcher matcher = pattern.matcher(rulePath);
+        return matcher.find() ? Optional.of(matcher.group(3)) : Optional.empty();
+    }
 }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/subscriber/ShardingTableConfigurationSubscriber.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/subscriber/ShardingTableConfigurationSubscriber.java
index 5e8df0bdcc7..74be7f6895a 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/subscriber/ShardingTableConfigurationSubscriber.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/subscriber/ShardingTableConfigurationSubscriber.java
@@ -69,6 +69,9 @@ public final class ShardingTableConfigurationSubscriber implements RuleConfigura
      */
     @Subscribe
     public synchronized void renew(final AddShardingTableConfigurationEvent<ShardingTableRuleConfiguration> event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         ShardingTableRuleConfiguration needToAddedConfig = event.getConfig();
         Optional<ShardingRule> rule = database.getRuleMetaData().findSingleRule(ShardingRule.class);
@@ -91,6 +94,9 @@ public final class ShardingTableConfigurationSubscriber implements RuleConfigura
      */
     @Subscribe
     public synchronized void renew(final AddShardingAutoTableConfigurationEvent<ShardingAutoTableRuleConfiguration> event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         ShardingAutoTableRuleConfiguration needToAddedConfig = event.getConfig();
         Optional<ShardingRule> rule = database.getRuleMetaData().findSingleRule(ShardingRule.class);
@@ -135,6 +141,9 @@ public final class ShardingTableConfigurationSubscriber implements RuleConfigura
      */
     @Subscribe
     public synchronized void renew(final AddBroadcastTableConfigurationEvent event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         Optional<ShardingRule> rule = database.getRuleMetaData().findSingleRule(ShardingRule.class);
         ShardingRuleConfiguration config;
@@ -153,6 +162,9 @@ public final class ShardingTableConfigurationSubscriber implements RuleConfigura
      */
     @Subscribe
     public synchronized void renew(final AlterShardingTableConfigurationEvent<ShardingTableRuleConfiguration> event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         ShardingTableRuleConfiguration needToAlteredConfig = event.getConfig();
         ShardingRuleConfiguration config = (ShardingRuleConfiguration) database.getRuleMetaData().getSingleRule(ShardingRule.class).getConfiguration();
@@ -168,6 +180,9 @@ public final class ShardingTableConfigurationSubscriber implements RuleConfigura
      */
     @Subscribe
     public synchronized void renew(final AlterShardingAutoTableConfigurationEvent<ShardingAutoTableRuleConfiguration> event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         ShardingAutoTableRuleConfiguration needToAlteredConfig = event.getConfig();
         ShardingRuleConfiguration config = (ShardingRuleConfiguration) database.getRuleMetaData().getSingleRule(ShardingRule.class).getConfiguration();
@@ -198,6 +213,9 @@ public final class ShardingTableConfigurationSubscriber implements RuleConfigura
      */
     @Subscribe
     public synchronized void renew(final AlterBroadcastTableConfigurationEvent event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         ShardingRuleConfiguration config = (ShardingRuleConfiguration) database.getRuleMetaData().getSingleRule(ShardingRule.class).getConfiguration();
         instanceContext.getEventBusContext().post(new DatabaseRuleConfigurationChangedEvent(event.getDatabaseName(), config));
@@ -210,6 +228,9 @@ public final class ShardingTableConfigurationSubscriber implements RuleConfigura
      */
     @Subscribe
     public synchronized void renew(final DeleteShardingTableConfigurationEvent event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         ShardingRuleConfiguration config = (ShardingRuleConfiguration) database.getRuleMetaData().getSingleRule(ShardingRule.class).getConfiguration();
         config.getTables().removeIf(each -> each.getLogicTable().equals(event.getTableName()));
@@ -223,6 +244,9 @@ public final class ShardingTableConfigurationSubscriber implements RuleConfigura
      */
     @Subscribe
     public synchronized void renew(final DeleteShardingAutoTableConfigurationEvent event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         ShardingRuleConfiguration config = (ShardingRuleConfiguration) database.getRuleMetaData().getSingleRule(ShardingRule.class).getConfiguration();
         config.getAutoTables().removeIf(each -> each.getLogicTable().equals(event.getTableName()));
@@ -249,6 +273,9 @@ public final class ShardingTableConfigurationSubscriber implements RuleConfigura
      */
     @Subscribe
     public synchronized void renew(final DeleteBroadcastTableConfigurationEvent event) {
+        if (event.getVersion() < instanceContext.getModeContextManager().getActiveVersionByKey(event.getVersionKey())) {
+            return;
+        }
         ShardingSphereDatabase database = databases.get(event.getDatabaseName());
         ShardingRuleConfiguration config = (ShardingRuleConfiguration) database.getRuleMetaData().getSingleRule(ShardingRule.class).getConfiguration();
         instanceContext.getEventBusContext().post(new DatabaseRuleConfigurationChangedEvent(event.getDatabaseName(), config));
diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/metadata/converter/ShardingNodeConverterTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/metadata/converter/ShardingNodeConverterTest.java
index 266e34f9a46..30708eaa0f8 100644
--- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/metadata/converter/ShardingNodeConverterTest.java
+++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/metadata/converter/ShardingNodeConverterTest.java
@@ -43,11 +43,6 @@ class ShardingNodeConverterTest {
         assertThat(ShardingNodeConverter.getBindingTableNamePath("foo_binding_table"), is("binding_tables/foo_binding_table"));
     }
     
-    @Test
-    void assertGetBroadcastTableNamePath() {
-        assertThat(ShardingNodeConverter.getBroadcastTablesPath(), is("broadcast_tables"));
-    }
-    
     @Test
     void assertGetDefaultDatabaseStrategyPath() {
         assertThat(ShardingNodeConverter.getDefaultDatabaseStrategyPath(), is("default_strategies/default_database_strategy"));
@@ -103,8 +98,6 @@ class ShardingNodeConverterTest {
         assertFalse(ShardingNodeConverter.isAutoTablePath("/metadata/foo_db/rules/sharding/algorithms/MD5"));
         assertTrue(ShardingNodeConverter.isBindingTablePath("/metadata/foo_db/rules/sharding/binding_tables/foo_table"));
         assertFalse(ShardingNodeConverter.isBindingTablePath("/metadata/foo_db/rules/sharding/algorithms/MD5"));
-        assertTrue(ShardingNodeConverter.isBroadcastTablePath("/metadata/foo_db/rules/sharding/broadcast_tables"));
-        assertFalse(ShardingNodeConverter.isBroadcastTablePath("/metadata/foo_db/rules/sharding/broadcast_tables/foo"));
         assertTrue(ShardingNodeConverter.isDefaultDatabaseStrategyPath("/metadata/foo_db/rules/sharding/default_strategies/default_database_strategy"));
         assertFalse(ShardingNodeConverter.isDefaultDatabaseStrategyPath("/metadata/foo_db/rules/sharding/default_strategies/default_database_strategy/foo"));
         assertTrue(ShardingNodeConverter.isDefaultTableStrategyPath("/metadata/foo_db/rules/sharding/default_strategies/default_table_strategy"));
@@ -166,4 +159,88 @@ class ShardingNodeConverterTest {
         assertTrue(actual.isPresent());
         assertThat(actual.get(), is("foo"));
     }
+    
+    @Test
+    void assertGetTableNameVersion() {
+        Optional<String> actual = ShardingNodeConverter.getTableNameVersion("/metadata/foo_db/rules/sharding/tables/foo_table/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
+    
+    @Test
+    void assertGetAutoTableNameVersion() {
+        Optional<String> actual = ShardingNodeConverter.getAutoTableNameVersion("/metadata/foo_db/rules/sharding/auto_tables/foo_table/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
+    
+    @Test
+    void assertGetBindingTableNameVersion() {
+        Optional<String> actual = ShardingNodeConverter.getBindingTableNameVersion("/metadata/foo_db/rules/sharding/binding_tables/c018fb3cd8e530dd/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
+    
+    @Test
+    void assertGetDefaultDatabaseStrategyVersion() {
+        Optional<String> actual = ShardingNodeConverter.getDefaultDatabaseStrategyVersion("/metadata/foo_db/rules/sharding/default_strategies/default_database_strategy/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
+    
+    @Test
+    void assertGetDefaultTableStrategyVersion() {
+        Optional<String> actual = ShardingNodeConverter.getDefaultTableStrategyVersion("/metadata/foo_db/rules/sharding/default_strategies/default_table_strategy/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
+    
+    @Test
+    void assertGetDefaultKeyGenerateStrategyVersion() {
+        Optional<String> actual = ShardingNodeConverter.getDefaultKeyGenerateStrategyVersion("/metadata/foo_db/rules/sharding/default_strategies/default_key_generate_strategy/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
+    
+    @Test
+    void assertGetDefaultAuditStrategyVersion() {
+        Optional<String> actual = ShardingNodeConverter.getDefaultAuditStrategyVersion("/metadata/foo_db/rules/sharding/default_strategies/default_audit_strategy/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
+    
+    @Test
+    void assertGetDefaultShardingColumnVersion() {
+        Optional<String> actual = ShardingNodeConverter.getDefaultShardingColumnVersion("/metadata/foo_db/rules/sharding/default_strategies/default_sharding_column/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
+    
+    @Test
+    void assertGetShardingAlgorithmVersion() {
+        Optional<String> actual = ShardingNodeConverter.getShardingAlgorithmVersion("/metadata/foo_db/rules/sharding/algorithms/foo_table_algorithm/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
+    
+    @Test
+    void assertGetKeyGeneratorVersion() {
+        Optional<String> actual = ShardingNodeConverter.getKeyGeneratorVersion("/metadata/foo_db/rules/sharding/key_generators/foo_table_key_generator/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
+    
+    @Test
+    void assertGetAuditorVersion() {
+        Optional<String> actual = ShardingNodeConverter.getAuditorVersion("/metadata/foo_db/rules/sharding/auditors/foo_table_auditor/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
+    
+    @Test
+    void assertGetShardingCacheVersion() {
+        Optional<String> actual = ShardingNodeConverter.getShardingCacheVersion("/metadata/foo_db/rules/sharding/sharding_cache/versions/1");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), is("1"));
+    }
 }