You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2021/09/29 09:22:11 UTC

[shardingsphere] branch master updated: Refresh memory meta data for create and drop database (#12820)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 9d6a02c  Refresh memory meta data for create and drop database (#12820)
9d6a02c is described below

commit 9d6a02cdd06e983b714a87cf60317a97c9e656c2
Author: Haoran Meng <me...@gmail.com>
AuthorDate: Wed Sep 29 17:21:41 2021 +0800

    Refresh memory meta data for create and drop database (#12820)
---
 .../mode/manager/ContextManager.java               | 84 ++++++++++++++++++++++
 .../ClusterContextManagerCoordinator.java          | 37 +---------
 .../database/CreateDatabaseBackendHandler.java     |  6 +-
 .../text/database/DropDatabaseBackendHandler.java  |  2 +-
 .../database/CreateDatabaseBackendHandlerTest.java |  3 +
 5 files changed, 94 insertions(+), 38 deletions(-)

diff --git a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
index 8cd7d21..c410653 100644
--- a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
+++ b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/ContextManager.java
@@ -18,13 +18,29 @@
 package org.apache.shardingsphere.mode.manager;
 
 import lombok.Getter;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shardingsphere.infra.config.RuleConfiguration;
+import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
+import org.apache.shardingsphere.infra.metadata.resource.ShardingSphereResource;
+import org.apache.shardingsphere.infra.metadata.schema.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.state.StateContext;
 import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
+import org.apache.shardingsphere.mode.metadata.MetaDataContextsBuilder;
+import org.apache.shardingsphere.transaction.ShardingSphereTransactionManagerEngine;
 import org.apache.shardingsphere.transaction.context.TransactionContexts;
 
+import javax.sql.DataSource;
+import java.sql.SQLException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
 /**
  * Context manager.
  */
+@Slf4j
 @Getter
 public final class ContextManager implements AutoCloseable {
     
@@ -63,6 +79,74 @@ public final class ContextManager implements AutoCloseable {
         this.transactionContexts = transactionContexts;
     }
     
+    /**
+     * Add schema.
+     * 
+     * @param schemaName schema name
+     * @throws SQLException SQL exception                  
+     */
+    public void addSchema(final String schemaName) throws SQLException {
+        if (metaDataContexts.getMetaDataMap().containsKey(schemaName)) {
+            return;
+        }
+        MetaDataContexts newMetaDataContexts = buildNewMetaDataContext(schemaName);
+        metaDataContexts.getOptimizerContext().getMetaData().getSchemas().put(schemaName,
+                newMetaDataContexts.getOptimizerContext().getMetaData().getSchemas().get(schemaName));
+        metaDataContexts.getMetaDataMap().put(schemaName, newMetaDataContexts.getMetaData(schemaName));
+    }
+    
+    /**
+     * Delete schema.
+     * 
+     * @param schemaName schema name
+     */
+    public void deleteSchema(final String schemaName) {
+        if (metaDataContexts.getMetaDataMap().containsKey(schemaName)) {
+            metaDataContexts.getOptimizerContext().getMetaData().getSchemas().remove(schemaName);
+            metaDataContexts.getOptimizerContext().getParserContexts().remove(schemaName);
+            metaDataContexts.getOptimizerContext().getPlannerContexts().remove(schemaName);
+            ShardingSphereMetaData removeMetaData = metaDataContexts.getMetaDataMap().remove(schemaName);
+            closeDataSources(removeMetaData);
+            closeTransactionEngine(schemaName);
+        }
+    }
+    
+    private MetaDataContexts buildNewMetaDataContext(final String schemaName) throws SQLException {
+        Map<String, Map<String, DataSource>> dataSourcesMap = Collections.singletonMap(schemaName, new HashMap<>());
+        Map<String, Collection<RuleConfiguration>> schemaRuleConfigs = Collections.singletonMap(schemaName, Collections.emptyList());
+        Properties props = metaDataContexts.getProps().getProps();
+        Map<String, ShardingSphereSchema> schemas = Collections.singletonMap(schemaName, new ShardingSphereSchema());
+        return new MetaDataContextsBuilder(dataSourcesMap, schemaRuleConfigs, metaDataContexts.getGlobalRuleMetaData().getConfigurations(), schemas, props)
+                .build(metaDataContexts.getMetaDataPersistService().orElse(null));
+    }
+    
+    private void closeDataSources(final ShardingSphereMetaData removeMetaData) {
+        if (null != removeMetaData.getResource()) {
+            removeMetaData.getResource().getDataSources().values().forEach(each -> closeDataSource(removeMetaData.getResource(), each));
+        }
+    }
+    
+    private void closeDataSource(final ShardingSphereResource resource, final DataSource dataSource) {
+        try {
+            resource.close(dataSource);
+        } catch (final SQLException ex) {
+            log.error("Close data source failed", ex);
+        }
+    }
+    
+    private void closeTransactionEngine(final String schemaName) {
+        ShardingSphereTransactionManagerEngine staleEngine = transactionContexts.getEngines().remove(schemaName);
+        if (null != staleEngine) {
+            try {
+                staleEngine.close();
+                // CHECKSTYLE:OFF
+            } catch (final Exception ex) {
+                // CHECKSTYLE:ON
+                log.error("Close transaction engine failed", ex);
+            }
+        }
+    }
+    
     @Override
     public void close() throws Exception {
         metaDataContexts.close();
diff --git a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/ClusterContextManagerCoordinator.java b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/ClusterContextManagerCoordinator.java
index ad72e60..27a833e 100644
--- a/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/ClusterContextManagerCoordinator.java
+++ b/shardingsphere-mode/shardingsphere-mode-type/shardingsphere-cluster-mode/shardingsphere-cluster-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/ClusterContextManagerCoordinator.java
@@ -99,10 +99,7 @@ public final class ClusterContextManagerCoordinator {
     @Subscribe
     public synchronized void renew(final SchemaAddedEvent event) throws SQLException {
         persistSchema(event.getSchemaName());
-        MetaDataContexts metaDataContexts = buildNewMetaDataContext(event.getSchemaName());
-        contextManager.getMetaDataContexts().getOptimizerContext().getMetaData().getSchemas().put(event.getSchemaName(), 
-                metaDataContexts.getOptimizerContext().getMetaData().getSchemas().get(event.getSchemaName()));
-        contextManager.getMetaDataContexts().getMetaDataMap().put(event.getSchemaName(), metaDataContexts.getMetaData(event.getSchemaName()));
+        contextManager.addSchema(event.getSchemaName());
     }
     
     /**
@@ -112,13 +109,7 @@ public final class ClusterContextManagerCoordinator {
      */
     @Subscribe
     public synchronized void renew(final SchemaDeletedEvent event) {
-        String schemaName = event.getSchemaName();
-        closeDataSources(schemaName);
-        Map<String, ShardingSphereMetaData> schemaMetaData = new HashMap<>(contextManager.getMetaDataContexts().getMetaDataMap());
-        schemaMetaData.remove(schemaName);
-        contextManager.getMetaDataContexts().getOptimizerContext().getMetaData().getSchemas().remove(schemaName);
-        contextManager.renewMetaDataContexts(rebuildMetaDataContexts(schemaMetaData));
-        renewTransactionContext(schemaName);
+        contextManager.deleteSchema(event.getSchemaName());
     }
     
     /**
@@ -276,14 +267,6 @@ public final class ClusterContextManagerCoordinator {
         }
     }
     
-    private MetaDataContexts buildNewMetaDataContext(final String schemaName) throws SQLException {
-        Map<String, Map<String, DataSource>> dataSourcesMap = createDataSourcesMap(Collections.singletonMap(schemaName, metaDataPersistService.getDataSourceService().load(schemaName)));
-        Map<String, Collection<RuleConfiguration>> schemaRuleConfigs = Collections.singletonMap(schemaName, metaDataPersistService.getSchemaRuleService().load(schemaName));
-        Properties props = contextManager.getMetaDataContexts().getProps().getProps();
-        Map<String, ShardingSphereSchema> schemas = new SchemaLoader(dataSourcesMap, schemaRuleConfigs, props).load();
-        return new MetaDataContextsBuilder(dataSourcesMap, schemaRuleConfigs, metaDataPersistService.getGlobalRuleService().load(), schemas, props).build(metaDataPersistService);
-    }
-    
     private MetaDataContexts buildChangedMetaDataContext(final ShardingSphereMetaData originalMetaData, final Collection<RuleConfiguration> ruleConfigs) throws SQLException {
         Map<String, Map<String, DataSource>> dataSourcesMap = Collections.singletonMap(originalMetaData.getName(), originalMetaData.getResource().getDataSources());
         Map<String, Collection<RuleConfiguration>> schemaRuleConfigs = Collections.singletonMap(originalMetaData.getName(), ruleConfigs);
@@ -345,10 +328,6 @@ public final class ClusterContextManagerCoordinator {
         return null != dataSourceConfig && !dataSourceConfiguration.equals(dataSourceConfig);
     }
     
-    private Map<String, Map<String, DataSource>> createDataSourcesMap(final Map<String, Map<String, DataSourceConfiguration>> dataSourcesConfigs) {
-        return dataSourcesConfigs.entrySet().stream().collect(Collectors.toMap(Entry::getKey, entry -> DataSourceConverter.getDataSourceMap(entry.getValue())));
-    }
-    
     private Collection<DataSource> getPendingClosedDataSources(final String schemaName, final Map<String, DataSourceConfiguration> dataSourceConfigurations) {
         Collection<DataSource> result = new LinkedList<>();
         result.addAll(getDeletedDataSources(contextManager.getMetaDataContexts().getMetaData(schemaName), dataSourceConfigurations).values());
@@ -356,13 +335,6 @@ public final class ClusterContextManagerCoordinator {
         return result;
     }
     
-    private void closeDataSources(final String schemaName) {
-        if (null != contextManager.getMetaDataContexts().getMetaData(schemaName) 
-                && null != contextManager.getMetaDataContexts().getMetaData(schemaName).getResource()) {
-            closeDataSources(schemaName, contextManager.getMetaDataContexts().getMetaData(schemaName).getResource().getDataSources().values());
-        }
-    }
-    
     private void closeDataSources(final String schemaName, final Collection<DataSource> dataSources) {
         ShardingSphereResource resource = contextManager.getMetaDataContexts().getMetaData(schemaName).getResource();
         dataSources.forEach(each -> closeDataSource(resource, each));
@@ -383,11 +355,6 @@ public final class ClusterContextManagerCoordinator {
         renewContexts(existedEngines);
     }
     
-    private void renewTransactionContext(final String schemaName) {
-        closeStaleEngine(schemaName);
-        renewContexts(contextManager.getTransactionContexts().getEngines());
-    }
-    
     private void closeStaleEngine(final String schemaName) {
         ShardingSphereTransactionManagerEngine staleEngine = contextManager.getTransactionContexts().getEngines().remove(schemaName);
         if (null != staleEngine) {
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/database/CreateDatabaseBackendHandler.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/database/CreateDatabaseBackendHandler.java
index ca1f4ab..81d9c26 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/database/CreateDatabaseBackendHandler.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/database/CreateDatabaseBackendHandler.java
@@ -25,6 +25,8 @@ import org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResp
 import org.apache.shardingsphere.proxy.backend.text.TextProtocolBackendHandler;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.CreateDatabaseStatement;
 
+import java.sql.SQLException;
+
 /**
  * Create database backend handler.
  */
@@ -34,9 +36,9 @@ public final class CreateDatabaseBackendHandler implements TextProtocolBackendHa
     private final CreateDatabaseStatement sqlStatement;
     
     @Override
-    public ResponseHeader execute() {
+    public ResponseHeader execute() throws SQLException {
         check(sqlStatement);
-        // TODO update meta data context in memory
+        ProxyContext.getInstance().getContextManager().addSchema(sqlStatement.getDatabaseName());
         ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaDataPersistService().ifPresent(
             optional -> optional.getSchemaMetaDataService().persist(sqlStatement.getDatabaseName()));
         return new UpdateResponseHeader(sqlStatement);
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/database/DropDatabaseBackendHandler.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/database/DropDatabaseBackendHandler.java
index e6b429a..108302b 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/database/DropDatabaseBackendHandler.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/database/DropDatabaseBackendHandler.java
@@ -43,7 +43,7 @@ public final class DropDatabaseBackendHandler implements TextProtocolBackendHand
         if (isDropCurrentDatabase(sqlStatement.getDatabaseName())) {
             backendConnection.setCurrentSchema(null);
         }
-        // TODO update meta data context in memory
+        ProxyContext.getInstance().getContextManager().deleteSchema(sqlStatement.getDatabaseName());
         ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaDataPersistService().ifPresent(
             optional -> optional.getSchemaMetaDataService().delete(sqlStatement.getDatabaseName()));
         return new UpdateResponseHeader(sqlStatement);
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/database/CreateDatabaseBackendHandlerTest.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/database/CreateDatabaseBackendHandlerTest.java
index 8edbc3a..aae8b8d 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/database/CreateDatabaseBackendHandlerTest.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/database/CreateDatabaseBackendHandlerTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.proxy.backend.text.database;
 
+import lombok.SneakyThrows;
 import org.apache.shardingsphere.mode.manager.ContextManager;
 import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
@@ -55,6 +56,7 @@ public final class CreateDatabaseBackendHandlerTest {
         when(metaDataContexts.getAllSchemaNames()).thenReturn(Collections.singleton("test_db"));
     }
 
+    @SneakyThrows
     @Test
     public void assertExecuteCreateNewDatabase() {
         when(statement.getDatabaseName()).thenReturn("other_db");
@@ -62,6 +64,7 @@ public final class CreateDatabaseBackendHandlerTest {
         Assert.assertTrue(responseHeader instanceof UpdateResponseHeader);
     }
 
+    @SneakyThrows
     @Test(expected = DBCreateExistsException.class)
     public void assertExecuteCreateExistDatabase() {
         when(statement.getDatabaseName()).thenReturn("test_db");