This is an automated email from the ASF dual-hosted git repository.
menghaoran 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 2c095d190c4 Refactor ContextManager.reloadDatabaseMetaData (#18876)
2c095d190c4 is described below
commit 2c095d190c46963a743b306781b0e34c8a49c6d4
Author: Liang Zhang <[email protected]>
AuthorDate: Wed Jul 6 06:01:15 2022 +0800
Refactor ContextManager.reloadDatabaseMetaData (#18876)
---
.../optimizer/context/OptimizerContext.java | 13 +++
.../mode/manager/ContextManager.java | 115 ++++++++++-----------
.../mode/manager/ContextManagerTest.java | 17 ++-
.../updatable/RefreshTableMetadataHandler.java | 6 +-
4 files changed, 82 insertions(+), 69 deletions(-)
diff --git
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/context/OptimizerContext.java
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/context/OptimizerContext.java
index cd2ad256466..e0c59d1ef23 100644
---
a/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/context/OptimizerContext.java
+++
b/shardingsphere-infra/shardingsphere-infra-federation/shardingsphere-infra-federation-optimizer/src/main/java/org/apache/shardingsphere/infra/federation/optimizer/context/OptimizerContext.java
@@ -26,6 +26,7 @@ import
org.apache.shardingsphere.infra.federation.optimizer.context.planner.Opti
import
org.apache.shardingsphere.infra.federation.optimizer.context.planner.OptimizerPlannerContextFactory;
import
org.apache.shardingsphere.infra.federation.optimizer.metadata.FederationDatabaseMetaData;
import
org.apache.shardingsphere.infra.federation.optimizer.metadata.FederationMetaData;
+import
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereSchema;
import
org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereTable;
import org.apache.shardingsphere.parser.rule.SQLParserRule;
@@ -60,6 +61,18 @@ public final class OptimizerContext {
plannerContexts.put(databaseName,
OptimizerPlannerContextFactory.create(federationDatabaseMetaData));
}
+ /**
+ * Alter database.
+ *
+ * @param databaseName database name
+ * @param schemas schemas
+ */
+ public void alterDatabase(final String databaseName, final Map<String,
ShardingSphereSchema> schemas) {
+ FederationDatabaseMetaData federationDatabaseMetaData = new
FederationDatabaseMetaData(databaseName, schemas);
+ federationMetaData.getDatabases().put(databaseName,
federationDatabaseMetaData);
+ plannerContexts.put(databaseName,
OptimizerPlannerContextFactory.create(federationDatabaseMetaData));
+ }
+
/**
* Drop database.
*
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 a6c2ba16968..4a22b09cf51 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
@@ -32,8 +32,6 @@ import
org.apache.shardingsphere.infra.datasource.props.DataSourcePropertiesCrea
import org.apache.shardingsphere.infra.executor.kernel.ExecutorEngine;
import
org.apache.shardingsphere.infra.federation.optimizer.context.OptimizerContext;
import
org.apache.shardingsphere.infra.federation.optimizer.context.OptimizerContextFactory;
-import
org.apache.shardingsphere.infra.federation.optimizer.context.planner.OptimizerPlannerContextFactory;
-import
org.apache.shardingsphere.infra.federation.optimizer.metadata.FederationDatabaseMetaData;
import org.apache.shardingsphere.infra.instance.InstanceContext;
import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
import
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
@@ -364,13 +362,13 @@ public final class ContextManager implements
AutoCloseable {
}
/**
- * Reload meta data.
+ * Reload database meta data.
*
- * @param databaseName database name to be reloaded
+ * @param databaseName to be reloaded database name
*/
- public synchronized void reloadMetaData(final String databaseName) {
+ public synchronized void reloadDatabaseMetaData(final String databaseName)
{
try {
- Map<String, ShardingSphereSchema> schemas =
loadActualSchema(databaseName);
+ Map<String, ShardingSphereSchema> schemas =
loadSchemas(databaseName);
deleteSchemas(databaseName, schemas);
alterSchemas(databaseName, schemas);
persistMetaData(metaDataContexts);
@@ -379,86 +377,94 @@ public final class ContextManager implements
AutoCloseable {
}
}
+ private Map<String, ShardingSphereSchema> loadSchemas(final String
databaseName) throws SQLException {
+ ShardingSphereDatabase database =
metaDataContexts.getMetaData().getDatabases().get(databaseName);
+ Map<String, DataSource> dataSourceMap =
database.getResource().getDataSources();
+ database.reloadRules(instanceContext);
+ DatabaseType storageType =
DatabaseTypeEngine.getDatabaseType(dataSourceMap.values());
+ Map<String, ShardingSphereSchema> result = new ConcurrentHashMap<>();
+ GenericSchemaBuilderMaterials materials = new
GenericSchemaBuilderMaterials(database.getProtocolType(),
+ storageType, dataSourceMap,
database.getRuleMetaData().getRules(),
metaDataContexts.getMetaData().getProps(), databaseName);
+ result.putAll(GenericSchemaBuilder.build(materials));
+ result.putAll(SystemSchemaBuilder.build(databaseName,
database.getProtocolType()));
+ return result;
+ }
+
+ private void deleteSchemas(final String databaseName, final Map<String,
ShardingSphereSchema> schemas) {
+ Map<String, ShardingSphereSchema> originalSchemas =
metaDataContexts.getMetaData().getDatabases().get(databaseName).getSchemas();
+ originalSchemas.forEach((key, value) -> {
+ if (!schemas.containsKey(key)) {
+ metaDataContexts.getPersistService().ifPresent(optional ->
optional.getDatabaseMetaDataService().deleteSchema(databaseName, key));
+ }
+ });
+ }
+
+ private synchronized void alterSchemas(final String databaseName, final
Map<String, ShardingSphereSchema> schemas) {
+ ShardingSphereDatabase alteredMetaData = new
ShardingSphereDatabase(databaseName,
metaDataContexts.getMetaData().getDatabases().get(databaseName).getProtocolType(),
+
metaDataContexts.getMetaData().getDatabases().get(databaseName).getResource(),
metaDataContexts.getMetaData().getDatabases().get(databaseName).getRuleMetaData(),
schemas);
+ Map<String, ShardingSphereDatabase> alteredDatabases = new
HashMap<>(metaDataContexts.getMetaData().getDatabases());
+ alteredDatabases.put(databaseName, alteredMetaData);
+ metaDataContexts.getOptimizerContext().alterDatabase(databaseName,
schemas);
+ metaDataContexts = newMetaDataContexts(new
ShardingSphereMetaData(alteredDatabases,
metaDataContexts.getMetaData().getGlobalRuleMetaData(),
metaDataContexts.getMetaData().getProps()),
+ metaDataContexts.getOptimizerContext());
+ }
+
/**
* Reload table meta data.
*
* @param databaseName database name
* @param schemaName schema name
- * @param tableName logic table name
+ * @param dataSourceName data source name
*/
- public synchronized void reloadMetaData(final String databaseName, final
String schemaName, final String tableName) {
+ public synchronized void reloadSchemaMetaData(final String databaseName,
final String schemaName, final String dataSourceName) {
try {
ShardingSphereDatabase database =
metaDataContexts.getMetaData().getDatabases().get(databaseName);
- GenericSchemaBuilderMaterials materials = new
GenericSchemaBuilderMaterials(database.getProtocolType(),
- database.getResource().getDatabaseType(),
database.getResource().getDataSources(), database.getRuleMetaData().getRules(),
metaDataContexts.getMetaData().getProps(), schemaName);
- loadTableMetaData(databaseName, schemaName, tableName, materials);
+ database.reloadRules(instanceContext);
+ GenericSchemaBuilderMaterials materials = new
GenericSchemaBuilderMaterials(database.getProtocolType(),
database.getResource().getDatabaseType(),
+ Collections.singletonMap(dataSourceName,
database.getResource().getDataSources().get(dataSourceName)),
+ database.getRuleMetaData().getRules(),
metaDataContexts.getMetaData().getProps(), schemaName);
+ loadTableMetaData(databaseName, schemaName, materials);
} catch (final SQLException ex) {
- log.error("Reload table:{} meta data of database:{} schema:{}
failed", tableName, databaseName, schemaName, ex);
+ log.error("Reload meta data of database:{} schema:{} with data
source:{} failed", databaseName, schemaName, dataSourceName, ex);
}
}
/**
- * Reload single data source table meta data.
+ * Reload table meta data.
*
* @param databaseName database name
* @param schemaName schema name
- * @param dataSourceName data source name
* @param tableName logic table name
*/
- public synchronized void reloadMetaData(final String databaseName, final
String schemaName, final String dataSourceName, final String tableName) {
+ public synchronized void reloadTableMetaData(final String databaseName,
final String schemaName, final String tableName) {
try {
ShardingSphereDatabase database =
metaDataContexts.getMetaData().getDatabases().get(databaseName);
- GenericSchemaBuilderMaterials materials = new
GenericSchemaBuilderMaterials(database.getProtocolType(),
database.getResource().getDatabaseType(),
- Collections.singletonMap(dataSourceName,
database.getResource().getDataSources().get(dataSourceName)),
- database.getRuleMetaData().getRules(),
metaDataContexts.getMetaData().getProps(), schemaName);
+ GenericSchemaBuilderMaterials materials = new
GenericSchemaBuilderMaterials(database.getProtocolType(),
+ database.getResource().getDatabaseType(),
database.getResource().getDataSources(), database.getRuleMetaData().getRules(),
metaDataContexts.getMetaData().getProps(), schemaName);
loadTableMetaData(databaseName, schemaName, tableName, materials);
} catch (final SQLException ex) {
- log.error("Reload table:{} meta data of database:{} schema:{} with
data source:{} failed", tableName, databaseName, schemaName, dataSourceName,
ex);
+ log.error("Reload table:{} meta data of database:{} schema:{}
failed", tableName, databaseName, schemaName, ex);
}
}
/**
- * Reload table meta data.
+ * Reload single data source table meta data.
*
* @param databaseName database name
* @param schemaName schema name
* @param dataSourceName data source name
+ * @param tableName logic table name
*/
- public synchronized void reloadSchemaMetaData(final String databaseName,
final String schemaName, final String dataSourceName) {
+ public synchronized void reloadTableMetaData(final String databaseName,
final String schemaName, final String dataSourceName, final String tableName) {
try {
ShardingSphereDatabase database =
metaDataContexts.getMetaData().getDatabases().get(databaseName);
- database.reloadRules(instanceContext);
GenericSchemaBuilderMaterials materials = new
GenericSchemaBuilderMaterials(database.getProtocolType(),
database.getResource().getDatabaseType(),
Collections.singletonMap(dataSourceName,
database.getResource().getDataSources().get(dataSourceName)),
database.getRuleMetaData().getRules(),
metaDataContexts.getMetaData().getProps(), schemaName);
- loadTableMetaData(databaseName, schemaName, materials);
+ loadTableMetaData(databaseName, schemaName, tableName, materials);
} catch (final SQLException ex) {
- log.error("Reload meta data of database:{} schema:{} with data
source:{} failed", databaseName, schemaName, dataSourceName, ex);
- }
- }
-
- private void alterSchemas(final String databaseName, final Map<String,
ShardingSphereSchema> schemas) {
- ShardingSphereDatabase alteredMetaData = new
ShardingSphereDatabase(databaseName,
metaDataContexts.getMetaData().getDatabases().get(databaseName).getProtocolType(),
-
metaDataContexts.getMetaData().getDatabases().get(databaseName).getResource(),
metaDataContexts.getMetaData().getDatabases().get(databaseName).getRuleMetaData(),
schemas);
- Map<String, ShardingSphereDatabase> alteredDatabases = new
HashMap<>(metaDataContexts.getMetaData().getDatabases());
- alteredDatabases.put(databaseName, alteredMetaData);
- FederationDatabaseMetaData alteredDatabaseMetaData = new
FederationDatabaseMetaData(databaseName, schemas);
-
metaDataContexts.getOptimizerContext().getFederationMetaData().getDatabases().put(databaseName,
alteredDatabaseMetaData);
-
metaDataContexts.getOptimizerContext().getPlannerContexts().put(databaseName,
OptimizerPlannerContextFactory.create(alteredDatabaseMetaData));
- renewMetaDataContexts(newMetaDataContexts(new
ShardingSphereMetaData(alteredDatabases,
metaDataContexts.getMetaData().getGlobalRuleMetaData(),
metaDataContexts.getMetaData().getProps()),
- metaDataContexts.getOptimizerContext()));
- }
-
- private void deleteSchemas(final String databaseName, final Map<String,
ShardingSphereSchema> actualSchemas) {
- Map<String, ShardingSphereSchema> originalSchemas =
metaDataContexts.getMetaData().getDatabases().get(databaseName).getSchemas();
- if (originalSchemas.isEmpty()) {
- return;
+ log.error("Reload table:{} meta data of database:{} schema:{} with
data source:{} failed", tableName, databaseName, schemaName, dataSourceName,
ex);
}
- originalSchemas.forEach((key, value) -> {
- if (null == actualSchemas.get(key)) {
- metaDataContexts.getPersistService().ifPresent(optional ->
optional.getDatabaseMetaDataService().deleteSchema(databaseName, key));
- }
- });
}
private void loadTableMetaData(final String databaseName, final String
schemaName, final GenericSchemaBuilderMaterials materials) throws SQLException {
@@ -479,19 +485,6 @@ public final class ContextManager implements AutoCloseable
{
}
}
- private Map<String, ShardingSphereSchema> loadActualSchema(final String
databaseName) throws SQLException {
- ShardingSphereDatabase database =
metaDataContexts.getMetaData().getDatabases().get(databaseName);
- Map<String, DataSource> dataSourceMap =
database.getResource().getDataSources();
- database.reloadRules(instanceContext);
- DatabaseType databaseType =
DatabaseTypeEngine.getDatabaseType(dataSourceMap.values());
- Map<String, ShardingSphereSchema> result = new ConcurrentHashMap<>();
- GenericSchemaBuilderMaterials materials = new
GenericSchemaBuilderMaterials(database.getProtocolType(),
- databaseType, dataSourceMap,
database.getRuleMetaData().getRules(),
metaDataContexts.getMetaData().getProps(), databaseName);
- result.putAll(GenericSchemaBuilder.build(materials));
- result.putAll(SystemSchemaBuilder.build(databaseName,
database.getProtocolType()));
- return result;
- }
-
private Map<String, DataSource> getChangedDataSources(final
ShardingSphereDatabase database, final Map<String, DataSourceProperties>
dataSourcePropsMap) {
Collection<String> changedDataSourceNames =
getChangedDataSourceProperties(database, dataSourcePropsMap).keySet();
return
database.getResource().getDataSources().entrySet().stream().filter(entry ->
changedDataSourceNames.contains(entry.getKey()))
diff --git
a/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
b/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
index bba6a26dfc1..2833c20d8b6 100644
---
a/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
+++
b/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/ContextManagerTest.java
@@ -48,7 +48,6 @@ import java.util.Optional;
import java.util.Properties;
import static org.hamcrest.CoreMatchers.is;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -257,16 +256,24 @@ public final class ContextManagerTest {
}
@Test
- public void assertReloadMetaData() {
+ public void assertReloadDatabaseMetaData() {
when(metaDataContexts.getMetaData().getDatabases().get("foo_db").getResource().getDataSources()).thenReturn(Collections.singletonMap("foo_ds",
new MockedDataSource()));
DatabaseMetaDataPersistService databaseMetaDataPersistService =
mock(DatabaseMetaDataPersistService.class, RETURNS_DEEP_STUBS);
MetaDataPersistService metaDataPersistService =
mock(MetaDataPersistService.class);
when(metaDataPersistService.getDatabaseMetaDataService()).thenReturn(databaseMetaDataPersistService);
when(metaDataContexts.getPersistService()).thenReturn(Optional.of(metaDataPersistService));
- contextManager.reloadMetaData("foo_db");
+ contextManager.reloadDatabaseMetaData("foo_db");
verify(databaseMetaDataPersistService,
times(1)).persistMetaData(eq("foo_db"), eq("foo_db"),
any(ShardingSphereSchema.class));
- contextManager.reloadMetaData("foo_db", "foo_schema", "foo_table");
-
assertNotNull(contextManager.getMetaDataContexts().getMetaData().getDatabases().get("foo_db").getSchemas().get("foo_db"));
+ }
+
+ @Test
+ public void assertReloadTableMetaData() {
+
when(metaDataContexts.getMetaData().getDatabases().get("foo_db").getResource().getDataSources()).thenReturn(Collections.singletonMap("foo_ds",
new MockedDataSource()));
+ DatabaseMetaDataPersistService databaseMetaDataPersistService =
mock(DatabaseMetaDataPersistService.class, RETURNS_DEEP_STUBS);
+ MetaDataPersistService metaDataPersistService =
mock(MetaDataPersistService.class);
+
when(metaDataPersistService.getDatabaseMetaDataService()).thenReturn(databaseMetaDataPersistService);
+
when(metaDataContexts.getPersistService()).thenReturn(Optional.of(metaDataPersistService));
+ contextManager.reloadTableMetaData("foo_db", "foo_schema",
"foo_table");
assertTrue(contextManager.getMetaDataContexts().getMetaData().getDatabases().get("foo_db").getResource().getDataSources().containsKey("foo_ds"));
}
diff --git
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/RefreshTableMetadataHandler.java
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/RefreshTableMetadataHandler.java
index 04ccce7201c..ef3939f1ddd 100644
---
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/RefreshTableMetadataHandler.java
+++
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/common/updatable/RefreshTableMetadataHandler.java
@@ -38,16 +38,16 @@ public final class RefreshTableMetadataHandler extends
UpdatableRALBackendHandle
String schemaName = getSchemaName(databaseName);
if (getSqlStatement().getResourceName().isPresent()) {
if (getSqlStatement().getTableName().isPresent()) {
- contextManager.reloadMetaData(databaseName, schemaName,
getSqlStatement().getResourceName().get(),
getSqlStatement().getTableName().get());
+ contextManager.reloadTableMetaData(databaseName, schemaName,
getSqlStatement().getResourceName().get(),
getSqlStatement().getTableName().get());
} else {
contextManager.reloadSchemaMetaData(databaseName, schemaName,
getSqlStatement().getResourceName().get());
}
return;
}
if (getSqlStatement().getTableName().isPresent()) {
- contextManager.reloadMetaData(databaseName, schemaName,
getSqlStatement().getTableName().get());
+ contextManager.reloadTableMetaData(databaseName, schemaName,
getSqlStatement().getTableName().get());
} else {
- contextManager.reloadMetaData(databaseName);
+ contextManager.reloadDatabaseMetaData(databaseName);
}
}