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 2020/12/03 06:18:55 UTC

[shardingsphere] branch master updated: #7318, first MGR runnable version (#8486)

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

zhangliang 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 de56971  #7318, first MGR runnable version (#8486)
de56971 is described below

commit de569712810d34ae61e6c60c8923110d9dcfd457
Author: Zhang Yonglun <zh...@apache.org>
AuthorDate: Thu Dec 3 14:18:13 2020 +0800

    #7318, first MGR runnable version (#8486)
    
    * #7318, persist primary data source
    
    * #7318, persist primary data source
    
    * #7318, change eventbus
    
    * #7318, integration test
---
 .../EncryptSQLRewriterParameterizedTest.java       |  2 +-
 .../config/rule/HADataSourceRuleConfiguration.java |  8 ++--
 .../org/apache/shardingsphere/ha/spi/HAType.java   |  9 ++--
 .../shardingsphere/ha/algorithm/MGRHAType.java     | 49 ++++++++++++++--------
 .../org/apache/shardingsphere/ha/rule/HARule.java  | 16 +++----
 .../biulder/AlgorithmProvidedHARuleBuilder.java    |  4 +-
 .../ha/rule/biulder/HARuleBuilder.java             |  4 +-
 .../ha/fixture/TestHATypeFixture.java              |  6 +--
 .../apache/shardingsphere/ha/rule/HARuleTest.java  |  4 +-
 .../ha/route/engine/HASQLRouterTest.java           |  3 +-
 .../ha/route/fixture/TestRouteHATypeFixture.java   |  6 +--
 .../MixSQLRewriterParameterizedTest.java           |  2 +-
 .../ShardingSQLRewriterParameterizedTest.java      |  2 +-
 .../governance/core/config/ConfigCenter.java       | 34 ++++++++++++++-
 .../rule/builder/ShardingSphereRulesBuilder.java   |  9 ++--
 .../infra/rule/builder/aware/ResourceAware.java    |  8 ++++
 .../event/impl/PrimaryDataSourceUpdateEvent.java   | 19 ++++-----
 .../infra/rule/ShardingSphereRulesBuilderTest.java |  2 +-
 .../context/metadata/MetaDataContextsBuilder.java  |  2 +-
 .../src/main/resources/conf/config-ha.yaml         |  4 +-
 20 files changed, 127 insertions(+), 66 deletions(-)

diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-rewrite/src/test/java/org/apache/shardingsphere/encrypt/rewrite/parameterized/EncryptSQLRewriterParameterizedTest.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-rewrite/src/test/java/org/apache/shardingsphere/encrypt/rewrite/parameterized/EncryptSQLRewriterParameterizedTest.java
index 88900fd..e9261ad 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-rewrite/src/test/java/org/apache/shardingsphere/encrypt/rewrite/parameterized/EncryptSQLRewriterParameterizedTest.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-rewrite/src/test/java/org/apache/shardingsphere/encrypt/rewrite/parameterized/EncryptSQLRewriterParameterizedTest.java
@@ -73,7 +73,7 @@ public final class EncryptSQLRewriterParameterizedTest extends AbstractSQLRewrit
         YamlRootRuleConfigurations ruleConfigurations = createRuleConfigurations();
         String databaseType = null == getTestParameters().getDatabaseType() ? "MySQL" : getTestParameters().getDatabaseType();
         Collection<ShardingSphereRule> rules = ShardingSphereRulesBuilder.build(new YamlRuleConfigurationSwapperEngine().swapToRuleConfigurations(
-                ruleConfigurations.getRules()), DatabaseTypeRegistry.getTrunkDatabaseType(databaseType), ruleConfigurations.getDataSources());
+                ruleConfigurations.getRules()), DatabaseTypeRegistry.getTrunkDatabaseType(databaseType), ruleConfigurations.getDataSources(), "schema_name");
         SQLStatementParserEngine sqlStatementParserEngine = new SQLStatementParserEngine(databaseType);
         ShardingSphereSchema schema = mockSchema();
         ConfigurationProperties props = new ConfigurationProperties(ruleConfigurations.getProps());
diff --git a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-api/src/main/java/org/apache/shardingsphere/ha/api/config/rule/HADataSourceRuleConfiguration.java b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-api/src/main/java/org/apache/shardingsphere/ha/api/config/rule/HADataSourceRuleConfiguration.java
index b858652..a3b9335 100644
--- a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-api/src/main/java/org/apache/shardingsphere/ha/api/config/rule/HADataSourceRuleConfiguration.java
+++ b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-api/src/main/java/org/apache/shardingsphere/ha/api/config/rule/HADataSourceRuleConfiguration.java
@@ -17,21 +17,23 @@
 
 package org.apache.shardingsphere.ha.api.config.rule;
 
+import lombok.AllArgsConstructor;
 import lombok.Getter;
-import lombok.RequiredArgsConstructor;
+import lombok.Setter;
 
 import java.util.List;
 
 /**
  * HA data source rule configuration.
  */
-@RequiredArgsConstructor
+@AllArgsConstructor
 @Getter
 public final class HADataSourceRuleConfiguration {
     
     private final String name;
     
-    private final String primaryDataSourceName;
+    @Setter
+    private String primaryDataSourceName;
     
     private final List<String> replicaDataSourceNames;
     
diff --git a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-api/src/main/java/org/apache/shardingsphere/ha/spi/HAType.java b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-api/src/main/java/org/apache/shardingsphere/ha/spi/HAType.java
index a57ea30..b56dfca 100644
--- a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-api/src/main/java/org/apache/shardingsphere/ha/spi/HAType.java
+++ b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-api/src/main/java/org/apache/shardingsphere/ha/spi/HAType.java
@@ -32,21 +32,24 @@ public interface HAType extends ShardingSphereAlgorithm {
      * Check HA config.
      *
      * @param dataSourceMap Data source map
+     * @param schemaName Schema name
      * @throws SQLException SQL Exception
      */
-    void checkHAConfig(Map<String, DataSource> dataSourceMap) throws SQLException;
+    void checkHAConfig(Map<String, DataSource> dataSourceMap, String schemaName) throws SQLException;
     
     /**
      * Update primary data source.
      *
      * @param dataSourceMap Data source map
+     * @param schemaName Schema name
      */
-    void updatePrimaryDataSource(Map<String, DataSource> dataSourceMap);
+    void updatePrimaryDataSource(Map<String, DataSource> dataSourceMap, String schemaName);
     
     /**
      * Periodical monitor.
      *
      * @param dataSourceMap Data source map
+     * @param schemaName Schema name
      */
-    void periodicalMonitor(Map<String, DataSource> dataSourceMap);
+    void periodicalMonitor(Map<String, DataSource> dataSourceMap, String schemaName);
 }
diff --git a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/algorithm/MGRHAType.java b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/algorithm/MGRHAType.java
index 5716f9d..a4a3b58 100644
--- a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/algorithm/MGRHAType.java
+++ b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/algorithm/MGRHAType.java
@@ -20,7 +20,9 @@ package org.apache.shardingsphere.ha.algorithm;
 import lombok.Getter;
 import lombok.Setter;
 import org.apache.shardingsphere.ha.spi.HAType;
+import org.apache.shardingsphere.infra.eventbus.ShardingSphereEventBus;
 import org.apache.shardingsphere.infra.exception.ShardingSphereException;
+import org.apache.shardingsphere.infra.rule.event.impl.PrimaryDataSourceUpdateEvent;
 
 import javax.sql.DataSource;
 import java.sql.Connection;
@@ -46,16 +48,18 @@ public final class MGRHAType implements HAType {
     
     private static final String SINGLE_PRIMARY = "SELECT * FROM performance_schema.global_variables WHERE VARIABLE_NAME='group_replication_single_primary_mode'";
     
-    private final ScheduledExecutorService scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
+    private static final ScheduledExecutorService SCHEDULED_EXECUTOR_SERVICE = Executors.newSingleThreadScheduledExecutor();
     
     private String primaryDataSource;
     
+    private String oldPrimaryDataSource;
+    
     @Getter
     @Setter
     private Properties props = new Properties();
     
     @Override
-    public void checkHAConfig(final Map<String, DataSource> dataSourceMap) throws SQLException {
+    public void checkHAConfig(final Map<String, DataSource> dataSourceMap, final String schemaName) throws SQLException {
         try (Connection connection = dataSourceMap.get(primaryDataSource).getConnection();
              Statement statement = connection.createStatement()) {
             ResultSet resultSet = statement.executeQuery(PLUGIN_STATUS);
@@ -93,42 +97,51 @@ public final class MGRHAType implements HAType {
     }
     
     @Override
-    public void updatePrimaryDataSource(final Map<String, DataSource> dataSourceMap) {
-        String primary = queryPrimaryDataSource(dataSourceMap);
-        if (!"".equals(primary)) {
+    public void updatePrimaryDataSource(final Map<String, DataSource> dataSourceMap, final String schemaName) {
+        String primary = determinePrimaryDataSource(dataSourceMap);
+        if ("".equals(primary)) {
+            return;
+        }
+        if (null == oldPrimaryDataSource && null == primaryDataSource) {
+            oldPrimaryDataSource = primary;
+            primaryDataSource = primary;
+            ShardingSphereEventBus.getInstance().post(new PrimaryDataSourceUpdateEvent(schemaName, primaryDataSource, oldPrimaryDataSource));
+            return;
+        }
+        if (!primary.equals(oldPrimaryDataSource)) {
+            oldPrimaryDataSource = primaryDataSource;
             primaryDataSource = primary;
+            ShardingSphereEventBus.getInstance().post(new PrimaryDataSourceUpdateEvent(schemaName, primaryDataSource, oldPrimaryDataSource));
         }
     }
     
-    private String queryPrimaryDataSource(final Map<String, DataSource> dataSourceMap) {
+    private String determinePrimaryDataSource(final Map<String, DataSource> dataSourceMap) {
         String result = "";
-        String urlResult = "";
+        String address = "";
         for (Map.Entry<String, DataSource> entry : dataSourceMap.entrySet()) {
             DataSource dataSource = entry.getValue();
-            String url = "";
             String sql = "SELECT MEMBER_HOST, MEMBER_PORT FROM performance_schema.replication_group_members WHERE MEMBER_ID = "
                     + "(SELECT VARIABLE_VALUE FROM performance_schema.global_status WHERE VARIABLE_NAME = 'group_replication_primary_member')";
             try (Connection connection = dataSource.getConnection();
                  Statement statement = connection.createStatement();
                  ResultSet resultSet = statement.executeQuery(sql)) {
                 while (resultSet.next()) {
-                    url = resultSet.getString("MEMBER_HOST");
-                    url += ":";
-                    url += resultSet.getString("MEMBER_PORT");
+                    address = resultSet.getString("MEMBER_HOST");
+                    address += ":";
+                    address += resultSet.getString("MEMBER_PORT");
                 }
                 // CHECKSTYLE:OFF
             } catch (final Exception ex) {
                 // CHECKSTYLE:ON
             }
-            if (null != url && !"".equals(url) && !"".equals(urlResult) && !urlResult.equals(url)) {
-                return result;
+            if (null != address && !"".equals(address)) {
+                break;
             }
-            urlResult = url;
         }
         for (Map.Entry<String, DataSource> entry : dataSourceMap.entrySet()) {
             DataSource dataSource = entry.getValue();
             try (Connection connection = dataSource.getConnection()) {
-                if (connection.getMetaData().getURL().contains(urlResult)) {
+                if (connection.getMetaData().getURL().contains(address)) {
                     result = entry.getKey();
                     break;
                 }
@@ -141,9 +154,9 @@ public final class MGRHAType implements HAType {
     }
     
     @Override
-    public void periodicalMonitor(final Map<String, DataSource> dataSourceMap) {
-        Runnable runnable = () -> updatePrimaryDataSource(dataSourceMap);
-        scheduledExecutorService.scheduleAtFixedRate(runnable, 0, Integer.parseInt(props.getProperty("keepAliveSeconds")), TimeUnit.SECONDS);
+    public void periodicalMonitor(final Map<String, DataSource> dataSourceMap, final String schemaName) {
+        Runnable runnable = () -> updatePrimaryDataSource(dataSourceMap, schemaName);
+        SCHEDULED_EXECUTOR_SERVICE.scheduleAtFixedRate(runnable, 0, Integer.parseInt(props.getProperty("keepAliveSeconds")), TimeUnit.SECONDS);
     }
     
     @Override
diff --git a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/rule/HARule.java b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/rule/HARule.java
index 3fa84ec..3eb0b2a 100644
--- a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/rule/HARule.java
+++ b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/rule/HARule.java
@@ -57,7 +57,7 @@ public final class HARule implements DataSourceContainedRule, StatusContainedRul
     
     private final Map<String, HADataSourceRule> dataSourceRules;
     
-    public HARule(final HARuleConfiguration config, final DatabaseType databaseType, final Map<String, DataSource> dataSourceMap) {
+    public HARule(final HARuleConfiguration config, final DatabaseType databaseType, final Map<String, DataSource> dataSourceMap, final String schemaName) {
         Preconditions.checkArgument(!config.getDataSources().isEmpty(), "HA data source rules can not be empty.");
         Preconditions.checkArgument(null != dataSourceMap && !dataSourceMap.isEmpty(), "Data sources cannot be empty.");
         Preconditions.checkArgument(null != databaseType, "Database type cannot be null.");
@@ -71,15 +71,15 @@ public final class HARule implements DataSourceContainedRule, StatusContainedRul
         }
         HAType haType = TypedSPIRegistry.getRegisteredService(HAType.class, config.getHaType().getType(), config.getHaType().getProps());
         try {
-            haType.updatePrimaryDataSource(dataSourceMap);
-            haType.checkHAConfig(dataSourceMap);
-            haType.periodicalMonitor(dataSourceMap);
+            haType.updatePrimaryDataSource(dataSourceMap, schemaName);
+            haType.checkHAConfig(dataSourceMap, schemaName);
+            haType.periodicalMonitor(dataSourceMap, schemaName);
         } catch (final SQLException ex) {
             throw new ShardingSphereException(ex);
         }
     }
     
-    public HARule(final AlgorithmProvidedHARuleConfiguration config, final DatabaseType databaseType, final Map<String, DataSource> dataSourceMap) {
+    public HARule(final AlgorithmProvidedHARuleConfiguration config, final DatabaseType databaseType, final Map<String, DataSource> dataSourceMap, final String schemaName) {
         Preconditions.checkArgument(!config.getDataSources().isEmpty(), "HA data source rules can not be empty.");
         Preconditions.checkArgument(null != dataSourceMap && !dataSourceMap.isEmpty(), "Data sources cannot be empty.");
         Preconditions.checkArgument(null != databaseType, "Database type cannot be null.");
@@ -93,9 +93,9 @@ public final class HARule implements DataSourceContainedRule, StatusContainedRul
         }
         HAType haType = TypedSPIRegistry.getRegisteredService(HAType.class, config.getHaType().getType(), config.getHaType().getProps());
         try {
-            haType.updatePrimaryDataSource(dataSourceMap);
-            haType.checkHAConfig(dataSourceMap);
-            haType.periodicalMonitor(dataSourceMap);
+            haType.updatePrimaryDataSource(dataSourceMap, schemaName);
+            haType.checkHAConfig(dataSourceMap, schemaName);
+            haType.periodicalMonitor(dataSourceMap, schemaName);
         } catch (final SQLException ex) {
             throw new ShardingSphereException(ex);
         }
diff --git a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/rule/biulder/AlgorithmProvidedHARuleBuilder.java b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/rule/biulder/AlgorithmProvidedHARuleBuilder.java
index 76c7bdc..ac19a25 100644
--- a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/rule/biulder/AlgorithmProvidedHARuleBuilder.java
+++ b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/rule/biulder/AlgorithmProvidedHARuleBuilder.java
@@ -38,9 +38,11 @@ public final class AlgorithmProvidedHARuleBuilder implements ShardingSphereRuleB
     
     private Map<String, DataSource> dataSourceMap;
     
+    private String schemaName;
+    
     @Override
     public HARule build(final AlgorithmProvidedHARuleConfiguration ruleConfig) {
-        return new HARule(ruleConfig, databaseType, dataSourceMap);
+        return new HARule(ruleConfig, databaseType, dataSourceMap, schemaName);
     }
     
     @Override
diff --git a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/rule/biulder/HARuleBuilder.java b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/rule/biulder/HARuleBuilder.java
index 0f0f294..b0a447d 100644
--- a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/rule/biulder/HARuleBuilder.java
+++ b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/main/java/org/apache/shardingsphere/ha/rule/biulder/HARuleBuilder.java
@@ -38,9 +38,11 @@ public final class HARuleBuilder implements ShardingSphereRuleBuilder<HARule, HA
     
     private Map<String, DataSource> dataSourceMap;
     
+    private String schemaName;
+    
     @Override
     public HARule build(final HARuleConfiguration ruleConfig) {
-        return new HARule(ruleConfig, databaseType, dataSourceMap);
+        return new HARule(ruleConfig, databaseType, dataSourceMap, schemaName);
     }
     
     @Override
diff --git a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/test/java/org/apache/shardingsphere/ha/fixture/TestHATypeFixture.java b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/test/java/org/apache/shardingsphere/ha/fixture/TestHATypeFixture.java
index 995aa4b..da00e82 100644
--- a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/test/java/org/apache/shardingsphere/ha/fixture/TestHATypeFixture.java
+++ b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/test/java/org/apache/shardingsphere/ha/fixture/TestHATypeFixture.java
@@ -28,15 +28,15 @@ import java.util.Map;
 public final class TestHATypeFixture implements HAType {
     
     @Override
-    public void checkHAConfig(final Map<String, DataSource> dataSourceMap) {
+    public void checkHAConfig(final Map<String, DataSource> dataSourceMap, final String schemaName) {
     }
     
     @Override
-    public void updatePrimaryDataSource(final Map<String, DataSource> dataSourceMap) {
+    public void updatePrimaryDataSource(final Map<String, DataSource> dataSourceMap, final String schemaName) {
     }
     
     @Override
-    public void periodicalMonitor(final Map<String, DataSource> dataSourceMap) {
+    public void periodicalMonitor(final Map<String, DataSource> dataSourceMap, final String schemaName) {
     }
     
     @Override
diff --git a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/test/java/org/apache/shardingsphere/ha/rule/HARuleTest.java b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/test/java/org/apache/shardingsphere/ha/rule/HARuleTest.java
index 733155b..119868c 100644
--- a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/test/java/org/apache/shardingsphere/ha/rule/HARuleTest.java
+++ b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-common/src/test/java/org/apache/shardingsphere/ha/rule/HARuleTest.java
@@ -44,7 +44,7 @@ public final class HARuleTest {
     
     @Test(expected = IllegalArgumentException.class)
     public void assertNewWithEmptyDataSourceRule() {
-        new HARule(new HARuleConfiguration(Collections.emptyList(), Collections.emptyMap(), mock(ShardingSphereAlgorithmConfiguration.class)), mock(DatabaseType.class), dataSourceMap);
+        new HARule(new HARuleConfiguration(Collections.emptyList(), Collections.emptyMap(), mock(ShardingSphereAlgorithmConfiguration.class)), mock(DatabaseType.class), dataSourceMap, "ha_db");
     }
     
     @Test
@@ -65,7 +65,7 @@ public final class HARuleTest {
         return new HARule(new HARuleConfiguration(
                 Collections.singleton(config), ImmutableMap.of("random", new ShardingSphereAlgorithmConfiguration("RANDOM", new Properties())),
                 new ShardingSphereAlgorithmConfiguration("Test", new Properties())),
-                mock(DatabaseType.class), dataSourceMap);
+                mock(DatabaseType.class), dataSourceMap, "ha_db");
     }
     
     private void assertDataSourceRule(final HADataSourceRule actual) {
diff --git a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-route/src/test/java/org/apache/shardingsphere/ha/route/engine/HASQLRouterTest.java b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-route/src/test/java/org/apache/shardingsphere/ha/route/engine/HASQLRouterTest.java
index 28da1df..413066f 100644
--- a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-route/src/test/java/org/apache/shardingsphere/ha/route/engine/HASQLRouterTest.java
+++ b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-route/src/test/java/org/apache/shardingsphere/ha/route/engine/HASQLRouterTest.java
@@ -85,7 +85,8 @@ public final class HASQLRouterTest {
     public void setUp() {
         rule = new HARule(new HARuleConfiguration(Collections.singleton(
                 new HADataSourceRuleConfiguration(DATASOURCE_NAME, PRIMARY_DATASOURCE, Collections.singletonList(REPLICA_DATASOURCE), null, true)),
-                Collections.emptyMap(), new ShardingSphereAlgorithmConfiguration("TestRoute", new Properties())), mock(DatabaseType.class), Collections.singletonMap("ds", mock(DataSource.class)));
+                Collections.emptyMap(), new ShardingSphereAlgorithmConfiguration("TestRoute", new Properties())), mock(DatabaseType.class),
+                Collections.singletonMap("ds", mock(DataSource.class)), "ha_db");
         sqlRouter = (HASQLRouter) OrderedSPIRegistry.getRegisteredServices(Collections.singleton(rule), SQLRouter.class).get(rule);
     }
     
diff --git a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-route/src/test/java/org/apache/shardingsphere/ha/route/fixture/TestRouteHATypeFixture.java b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-route/src/test/java/org/apache/shardingsphere/ha/route/fixture/TestRouteHATypeFixture.java
index 0dae609..12339c7 100644
--- a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-route/src/test/java/org/apache/shardingsphere/ha/route/fixture/TestRouteHATypeFixture.java
+++ b/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-route/src/test/java/org/apache/shardingsphere/ha/route/fixture/TestRouteHATypeFixture.java
@@ -28,16 +28,16 @@ import java.util.Map;
 public final class TestRouteHATypeFixture implements HAType {
     
     @Override
-    public void checkHAConfig(final Map<String, DataSource> dataSourceMap) {
+    public void checkHAConfig(final Map<String, DataSource> dataSourceMap, final String schemaName) {
     }
     
     @Override
-    public void updatePrimaryDataSource(final Map<String, DataSource> dataSourceMap) {
+    public void updatePrimaryDataSource(final Map<String, DataSource> dataSourceMap, final String schemaName) {
 
     }
     
     @Override
-    public void periodicalMonitor(final Map<String, DataSource> dataSourceMap) {
+    public void periodicalMonitor(final Map<String, DataSource> dataSourceMap, final String schemaName) {
     }
     
     @Override
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/MixSQLRewriterParameterizedTest.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/MixSQLRewriterParameterizedTest.java
index a72a6ba..6e01f2d 100644
--- a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/MixSQLRewriterParameterizedTest.java
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/MixSQLRewriterParameterizedTest.java
@@ -80,7 +80,7 @@ public final class MixSQLRewriterParameterizedTest extends AbstractSQLRewriterPa
         YamlRootRuleConfigurations ruleConfigurations = createRuleConfigurations();
         String databaseType = null == getTestParameters().getDatabaseType() ? "MySQL" : getTestParameters().getDatabaseType();
         Collection<ShardingSphereRule> rules = ShardingSphereRulesBuilder.build(new YamlRuleConfigurationSwapperEngine().swapToRuleConfigurations(
-                ruleConfigurations.getRules()), DatabaseTypeRegistry.getTrunkDatabaseType(databaseType), ruleConfigurations.getDataSources());
+                ruleConfigurations.getRules()), DatabaseTypeRegistry.getTrunkDatabaseType(databaseType), ruleConfigurations.getDataSources(), "schema_name");
         SQLStatementParserEngine sqlStatementParserEngine = new SQLStatementParserEngine(databaseType);
         ShardingSphereSchema schema = mockSchema();
         ConfigurationProperties props = new ConfigurationProperties(ruleConfigurations.getProps());
diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/ShardingSQLRewriterParameterizedTest.java b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/ShardingSQLRewriterParameterizedTest.java
index f7c3751..8608d13 100644
--- a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/ShardingSQLRewriterParameterizedTest.java
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-rewrite/src/test/java/org/apache/shardingsphere/sharding/rewrite/parameterized/ShardingSQLRewriterParameterizedTest.java
@@ -80,7 +80,7 @@ public final class ShardingSQLRewriterParameterizedTest extends AbstractSQLRewri
         YamlRootRuleConfigurations yamlRootRuleConfigs = createYamlRootRuleConfigurations();
         String databaseType = null == getTestParameters().getDatabaseType() ? "SQL92" : getTestParameters().getDatabaseType();
         Collection<ShardingSphereRule> rules = ShardingSphereRulesBuilder.build(new YamlRuleConfigurationSwapperEngine().swapToRuleConfigurations(
-                yamlRootRuleConfigs.getRules()), DatabaseTypeRegistry.getTrunkDatabaseType(databaseType), yamlRootRuleConfigs.getDataSources());
+                yamlRootRuleConfigs.getRules()), DatabaseTypeRegistry.getTrunkDatabaseType(databaseType), yamlRootRuleConfigs.getDataSources(), "schema_name");
         SQLStatementParserEngine sqlStatementParserEngine = new SQLStatementParserEngine(databaseType);
         ShardingSphereSchema schema = mockSchema();
         ConfigurationProperties props = new ConfigurationProperties(yamlRootRuleConfigs.getProps());
diff --git a/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/config/ConfigCenter.java b/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/config/ConfigCenter.java
index 0487b94..bfbf3e3 100644
--- a/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/config/ConfigCenter.java
+++ b/shardingsphere-governance/shardingsphere-governance-core/src/main/java/org/apache/shardingsphere/governance/core/config/ConfigCenter.java
@@ -24,7 +24,6 @@ import com.google.common.base.Strings;
 import com.google.common.eventbus.Subscribe;
 import org.apache.shardingsphere.encrypt.algorithm.config.AlgorithmProvidedEncryptRuleConfiguration;
 import org.apache.shardingsphere.encrypt.api.config.EncryptRuleConfiguration;
-import org.apache.shardingsphere.infra.eventbus.ShardingSphereEventBus;
 import org.apache.shardingsphere.governance.core.event.model.datasource.DataSourcePersistEvent;
 import org.apache.shardingsphere.governance.core.event.model.rule.RuleConfigurationsPersistEvent;
 import org.apache.shardingsphere.governance.core.event.model.schema.SchemaNamePersistEvent;
@@ -36,12 +35,15 @@ import org.apache.shardingsphere.governance.core.yaml.swapper.DataSourceConfigur
 import org.apache.shardingsphere.governance.core.yaml.swapper.SchemaYamlSwapper;
 import org.apache.shardingsphere.governance.repository.api.ConfigurationRepository;
 import org.apache.shardingsphere.ha.api.config.HARuleConfiguration;
+import org.apache.shardingsphere.ha.api.config.rule.HADataSourceRuleConfiguration;
 import org.apache.shardingsphere.infra.auth.Authentication;
 import org.apache.shardingsphere.infra.auth.yaml.config.YamlAuthenticationConfiguration;
 import org.apache.shardingsphere.infra.auth.yaml.swapper.AuthenticationYamlSwapper;
 import org.apache.shardingsphere.infra.config.RuleConfiguration;
 import org.apache.shardingsphere.infra.config.datasource.DataSourceConfiguration;
+import org.apache.shardingsphere.infra.eventbus.ShardingSphereEventBus;
 import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
+import org.apache.shardingsphere.infra.rule.event.impl.PrimaryDataSourceUpdateEvent;
 import org.apache.shardingsphere.infra.yaml.config.YamlRootRuleConfigurations;
 import org.apache.shardingsphere.infra.yaml.engine.YamlEngine;
 import org.apache.shardingsphere.infra.yaml.swapper.YamlRuleConfigurationSwapperEngine;
@@ -154,6 +156,36 @@ public final class ConfigCenter {
         persistSchema(event.getSchemaName(), event.getSchema());
     }
     
+    /**
+     * Persist new HA rule configurations.
+     *
+     * @param event Data source name update event.
+     */
+    @Subscribe
+    public synchronized void renew(final PrimaryDataSourceUpdateEvent event) {
+        Map<String, DataSourceConfiguration> dataSourceConfigurations = loadDataSourceConfigurations(event.getSchemaName());
+        dataSourceConfigurations.remove(event.getOldPrimaryDataSource());
+        Collection<RuleConfiguration> ruleConfigurations = loadRuleConfigurations(event.getSchemaName());
+        for (RuleConfiguration each : ruleConfigurations) {
+            if (each instanceof HARuleConfiguration) {
+                updateHaDataSourceRuleConfigurations(event, (HARuleConfiguration) each);
+            }
+        }
+        persistDataSourceConfigurations(event.getSchemaName(), dataSourceConfigurations);
+        persistRuleConfigurations(event.getSchemaName(), ruleConfigurations);
+    }
+    
+    private void updateHaDataSourceRuleConfigurations(final PrimaryDataSourceUpdateEvent event, final HARuleConfiguration haRuleConfiguration) {
+        Collection<HADataSourceRuleConfiguration> haDataSourceRuleConfigurations = haRuleConfiguration.getDataSources();
+        for (HADataSourceRuleConfiguration each : haDataSourceRuleConfigurations) {
+            if (each.getPrimaryDataSourceName().equals(event.getNewPrimaryDataSource())) {
+                break;
+            }
+            each.setPrimaryDataSourceName(event.getNewPrimaryDataSource());
+            each.getReplicaDataSourceNames().remove(event.getNewPrimaryDataSource());
+        }
+    }
+    
     private void persistDataSourceConfigurations(final String schemaName, final Map<String, DataSourceConfiguration> dataSourceConfigurations, final boolean isOverwrite) {
         if (!dataSourceConfigurations.isEmpty() && (isOverwrite || !hasDataSourceConfiguration(schemaName))) {
             persistDataSourceConfigurations(schemaName, dataSourceConfigurations);
diff --git a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/rule/builder/ShardingSphereRulesBuilder.java b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/rule/builder/ShardingSphereRulesBuilder.java
index f00ff58..c279095 100644
--- a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/rule/builder/ShardingSphereRulesBuilder.java
+++ b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/rule/builder/ShardingSphereRulesBuilder.java
@@ -47,21 +47,24 @@ public final class ShardingSphereRulesBuilder {
      * @param ruleConfigurations rule configurations
      * @param databaseType database type
      * @param dataSourceMap data source map
+     * @param schemaName schema name
      * @return rules
      */
     @SuppressWarnings({"unchecked", "rawtypes"})
-    public static Collection<ShardingSphereRule> build(final Collection<RuleConfiguration> ruleConfigurations, final DatabaseType databaseType, final Map<String, DataSource> dataSourceMap) {
+    public static Collection<ShardingSphereRule> build(final Collection<RuleConfiguration> ruleConfigurations, final DatabaseType databaseType,
+                                                       final Map<String, DataSource> dataSourceMap, final String schemaName) {
         Map<RuleConfiguration, ShardingSphereRuleBuilder> builders = OrderedSPIRegistry.getRegisteredServices(ruleConfigurations, ShardingSphereRuleBuilder.class);
-        setResources(builders.values(), databaseType, dataSourceMap);
+        setResources(builders.values(), databaseType, dataSourceMap, schemaName);
         return builders.entrySet().stream().map(entry -> entry.getValue().build(entry.getKey())).collect(Collectors.toList());
     }
     
     @SuppressWarnings("rawtypes")
-    private static void setResources(final Collection<ShardingSphereRuleBuilder> builders, final DatabaseType databaseType, final Map<String, DataSource> dataSourceMap) {
+    private static void setResources(final Collection<ShardingSphereRuleBuilder> builders, final DatabaseType databaseType, final Map<String, DataSource> dataSourceMap, final String schemaName) {
         for (ShardingSphereRuleBuilder each : builders) {
             if (each instanceof ResourceAware) {
                 ((ResourceAware) each).setDatabaseType(databaseType);
                 ((ResourceAware) each).setDataSourceMap(dataSourceMap);
+                ((ResourceAware) each).setSchemaName(schemaName);
             }
         }
     }
diff --git a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/rule/builder/aware/ResourceAware.java b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/rule/builder/aware/ResourceAware.java
index 2d6a8c8..897ca39 100644
--- a/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/rule/builder/aware/ResourceAware.java
+++ b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/rule/builder/aware/ResourceAware.java
@@ -40,4 +40,12 @@ public interface ResourceAware {
      * @param dataSourceMap data source map
      */
     void setDataSourceMap(Map<String, DataSource> dataSourceMap);
+    
+    /**
+     * Set schema name.
+     *
+     * @param schemaName schema name
+     */
+    default void setSchemaName(String schemaName) {
+    }
 }
diff --git a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-api/src/main/java/org/apache/shardingsphere/ha/api/config/rule/HADataSourceRuleConfiguration.java b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/rule/event/impl/PrimaryDataSourceUpdateEvent.java
similarity index 70%
copy from shardingsphere-features/shardingsphere-ha/shardingsphere-ha-api/src/main/java/org/apache/shardingsphere/ha/api/config/rule/HADataSourceRuleConfiguration.java
copy to shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/rule/event/impl/PrimaryDataSourceUpdateEvent.java
index b858652..fe0475e 100644
--- a/shardingsphere-features/shardingsphere-ha/shardingsphere-ha-api/src/main/java/org/apache/shardingsphere/ha/api/config/rule/HADataSourceRuleConfiguration.java
+++ b/shardingsphere-infra/shardingsphere-infra-common/src/main/java/org/apache/shardingsphere/infra/rule/event/impl/PrimaryDataSourceUpdateEvent.java
@@ -15,27 +15,22 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.ha.api.config.rule;
+package org.apache.shardingsphere.infra.rule.event.impl;
 
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
-
-import java.util.List;
+import org.apache.shardingsphere.infra.rule.event.RuleChangedEvent;
 
 /**
- * HA data source rule configuration.
+ * Primary data source update event.
  */
 @RequiredArgsConstructor
 @Getter
-public final class HADataSourceRuleConfiguration {
-    
-    private final String name;
-    
-    private final String primaryDataSourceName;
+public final class PrimaryDataSourceUpdateEvent implements RuleChangedEvent {
     
-    private final List<String> replicaDataSourceNames;
+    private final String schemaName;
     
-    private final String loadBalancerName;
+    private final String newPrimaryDataSource;
     
-    private final Boolean readWriteSplit;
+    private final String oldPrimaryDataSource;
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/rule/ShardingSphereRulesBuilderTest.java b/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/rule/ShardingSphereRulesBuilderTest.java
index 4b83cf3..12a5723 100644
--- a/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/rule/ShardingSphereRulesBuilderTest.java
+++ b/shardingsphere-infra/shardingsphere-infra-common/src/test/java/org/apache/shardingsphere/infra/rule/ShardingSphereRulesBuilderTest.java
@@ -36,7 +36,7 @@ public final class ShardingSphereRulesBuilderTest {
     @Test
     public void assertBuild() {
         RuleConfiguration ruleConfig = new TestRuleConfiguration();
-        Collection<ShardingSphereRule> shardingSphereRules = ShardingSphereRulesBuilder.build(Collections.singletonList(ruleConfig), mock(DatabaseType.class), Collections.emptyMap());
+        Collection<ShardingSphereRule> shardingSphereRules = ShardingSphereRulesBuilder.build(Collections.singletonList(ruleConfig), mock(DatabaseType.class), Collections.emptyMap(), "schema_name");
         assertThat(shardingSphereRules, is(Collections.singletonList(TestShardingSphereRuleBuilder.getRule())));
     }
 }
diff --git a/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/metadata/MetaDataContextsBuilder.java b/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/metadata/MetaDataContextsBuilder.java
index 1e380ba..f2fb9ab 100644
--- a/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/metadata/MetaDataContextsBuilder.java
+++ b/shardingsphere-infra/shardingsphere-infra-context/src/main/java/org/apache/shardingsphere/infra/context/metadata/MetaDataContextsBuilder.java
@@ -98,7 +98,7 @@ public final class MetaDataContextsBuilder {
     private ShardingSphereMetaData buildMetaData(final String schemaName) throws SQLException {
         Map<String, DataSource> dataSourceMap = dataSources.get(schemaName);
         Collection<RuleConfiguration> ruleConfigs = this.ruleConfigs.get(schemaName);
-        Collection<ShardingSphereRule> rules = ShardingSphereRulesBuilder.build(ruleConfigs, databaseType, dataSourceMap);
+        Collection<ShardingSphereRule> rules = ShardingSphereRulesBuilder.build(ruleConfigs, databaseType, dataSourceMap, schemaName);
         ShardingSphereRuleMetaData ruleMetaData = new ShardingSphereRuleMetaData(ruleConfigs, rules);
         return new ShardingSphereMetaData(schemaName, buildResource(dataSourceMap), ruleMetaData, buildSchema(schemaName, dataSourceMap, rules));
     }
diff --git a/shardingsphere-proxy/shardingsphere-proxy-bootstrap/src/main/resources/conf/config-ha.yaml b/shardingsphere-proxy/shardingsphere-proxy-bootstrap/src/main/resources/conf/config-ha.yaml
index df4ad3e..267302e 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-bootstrap/src/main/resources/conf/config-ha.yaml
+++ b/shardingsphere-proxy/shardingsphere-proxy-bootstrap/src/main/resources/conf/config-ha.yaml
@@ -16,10 +16,10 @@
 #
 
 ######################################################################################################
-# 
+#
 # Here you can configure the rules for the proxy.
 # This example is configuration of HA rule.
-# 
+#
 ######################################################################################################
 #
 #schemaName: ha_db