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 0b4e1de3958 Reload table meta data after rule altered for standalone (#34948) 0b4e1de3958 is described below commit 0b4e1de3958efbf2829ff5765c1d6c9fe44b8dfe Author: Haoran Meng <menghaora...@gmail.com> AuthorDate: Mon Mar 10 18:20:38 2025 +0800 Reload table meta data after rule altered for standalone (#34948) --- .../StandaloneMetaDataManagerPersistService.java | 41 +++++++++++++++++++++- ...tandaloneMetaDataManagerPersistServiceTest.java | 21 +++++++++-- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/persist/service/StandaloneMetaDataManagerPersistService.java b/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/persist/service/StandaloneMetaDataManagerPersistService.java index 76f93d32ab5..eabb569247b 100644 --- a/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/persist/service/StandaloneMetaDataManagerPersistService.java +++ b/mode/type/standalone/core/src/main/java/org/apache/shardingsphere/mode/manager/standalone/persist/service/StandaloneMetaDataManagerPersistService.java @@ -17,18 +17,23 @@ package org.apache.shardingsphere.mode.manager.standalone.persist.service; +import lombok.extern.slf4j.Slf4j; import org.apache.shardingsphere.infra.config.rule.RuleConfiguration; +import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry; import org.apache.shardingsphere.infra.datasource.pool.props.domain.DataSourcePoolProperties; import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; +import org.apache.shardingsphere.infra.metadata.database.schema.builder.GenericSchemaBuilder; +import org.apache.shardingsphere.infra.metadata.database.schema.builder.GenericSchemaBuilderMaterial; +import org.apache.shardingsphere.infra.metadata.database.schema.manager.GenericSchemaManager; import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema; import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable; import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereView; -import org.apache.shardingsphere.mode.node.path.version.MetaDataVersion; import org.apache.shardingsphere.infra.rule.scope.GlobalRule; import org.apache.shardingsphere.infra.rule.scope.GlobalRule.GlobalRuleChangedType; import org.apache.shardingsphere.infra.spi.type.ordered.cache.OrderedServicesCache; +import org.apache.shardingsphere.mode.exception.LoadTableMetaDataFailedException; import org.apache.shardingsphere.mode.metadata.MetaDataContexts; import org.apache.shardingsphere.mode.metadata.changed.RuleItemChangedNodePathBuilder; import org.apache.shardingsphere.mode.metadata.manager.ActiveVersionChecker; @@ -37,6 +42,7 @@ import org.apache.shardingsphere.mode.metadata.persist.MetaDataPersistFacade; import org.apache.shardingsphere.mode.metadata.persist.metadata.DatabaseMetaDataPersistFacade; import org.apache.shardingsphere.mode.metadata.refresher.metadata.util.TableRefreshUtils; import org.apache.shardingsphere.mode.node.path.type.database.metadata.rule.DatabaseRuleNodePath; +import org.apache.shardingsphere.mode.node.path.version.MetaDataVersion; import org.apache.shardingsphere.mode.node.path.version.VersionNodePath; import org.apache.shardingsphere.mode.persist.service.MetaDataManagerPersistService; import org.apache.shardingsphere.single.config.SingleRuleConfiguration; @@ -46,6 +52,7 @@ import java.sql.SQLException; import java.util.Collection; import java.util.Collections; import java.util.Map; +import java.util.Map.Entry; import java.util.Optional; import java.util.Properties; import java.util.stream.Collectors; @@ -53,6 +60,7 @@ import java.util.stream.Collectors; /** * Standalone meta data manager persist service. */ +@Slf4j public final class StandaloneMetaDataManagerPersistService implements MetaDataManagerPersistService { private final MetaDataContextManager metaDataContextManager; @@ -217,6 +225,7 @@ public final class StandaloneMetaDataManagerPersistService implements MetaDataMa if (null == toBeAlteredRuleConfig) { return; } + Collection<String> needReloadTables = getNeedReloadTables(database, toBeAlteredRuleConfig); for (MetaDataVersion each : metaDataPersistFacade.getDatabaseRuleService().persist(database.getName(), Collections.singleton(toBeAlteredRuleConfig))) { Optional<DatabaseRuleNodePath> databaseRuleNodePath = ruleItemChangedNodePathBuilder.build(database.getName(), new VersionNodePath(each.getNodePath()).getActiveVersionPath()); if (databaseRuleNodePath.isPresent() @@ -224,6 +233,7 @@ public final class StandaloneMetaDataManagerPersistService implements MetaDataMa metaDataContextManager.getDatabaseRuleItemManager().alter(databaseRuleNodePath.get()); } } + reloadAlteredTables(database.getName(), needReloadTables); clearServiceCache(); } @@ -232,6 +242,7 @@ public final class StandaloneMetaDataManagerPersistService implements MetaDataMa if (null == toBeRemovedRuleConfig) { return; } + Collection<String> needReloadTables = getNeedReloadTables(database, toBeRemovedRuleConfig); Collection<MetaDataVersion> metaDataVersions = metaDataPersistFacade.getDatabaseRuleService().delete(database.getName(), Collections.singleton(toBeRemovedRuleConfig)); for (MetaDataVersion each : metaDataVersions) { Optional<DatabaseRuleNodePath> databaseRuleNodePath = ruleItemChangedNodePathBuilder.build(database.getName(), new VersionNodePath(each.getNodePath()).getActiveVersionPath()); @@ -239,9 +250,37 @@ public final class StandaloneMetaDataManagerPersistService implements MetaDataMa metaDataContextManager.getDatabaseRuleItemManager().drop(databaseRuleNodePath.get()); } } + reloadAlteredTables(database.getName(), needReloadTables); clearServiceCache(); } + private void reloadAlteredTables(final String databaseName, final Collection<String> needReloadTables) { + MetaDataContexts reloadMetaDataContexts = metaDataContextManager.getMetaDataContexts(); + ShardingSphereDatabase database = reloadMetaDataContexts.getMetaData().getDatabase(databaseName); + GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial(database.getResourceMetaData().getStorageUnits(), + database.getRuleMetaData().getRules(), reloadMetaDataContexts.getMetaData().getProps(), + new DatabaseTypeRegistry(database.getProtocolType()).getDefaultSchemaName(databaseName)); + try { + Map<String, ShardingSphereSchema> schemas = GenericSchemaBuilder.build(needReloadTables, database.getProtocolType(), material); + for (Entry<String, ShardingSphereSchema> entry : schemas.entrySet()) { + Collection<ShardingSphereTable> tables = GenericSchemaManager.getToBeAddedTables(entry.getValue(), database.getSchema(entry.getKey())); + metaDataPersistFacade.getDatabaseMetaDataFacade().getTable().persist(databaseName, entry.getKey(), tables); + tables.forEach(each -> metaDataContextManager.getDatabaseMetaDataManager().alterTable(databaseName, entry.getKey(), each)); + } + } catch (final SQLException ex) { + log.error("Load table meta failed, databaseName:{}, needReloadTables:{}", databaseName, needReloadTables, ex); + throw new LoadTableMetaDataFailedException(); + } + } + + private Collection<String> getNeedReloadTables(final ShardingSphereDatabase originalShardingDatabase, final RuleConfiguration toBeAlteredRuleConfig) { + if (toBeAlteredRuleConfig instanceof SingleRuleConfiguration) { + Collection<String> originalSingleTables = originalShardingDatabase.getRuleMetaData().getSingleRule(SingleRule.class).getConfiguration().getLogicTableNames(); + return toBeAlteredRuleConfig.getLogicTableNames().stream().filter(each -> !originalSingleTables.contains(each)).collect(Collectors.toList()); + } + return toBeAlteredRuleConfig.getLogicTableNames(); + } + @Override public void removeRuleConfiguration(final ShardingSphereDatabase database, final String ruleType) { metaDataPersistFacade.getDatabaseRuleService().delete(database.getName(), ruleType); diff --git a/mode/type/standalone/core/src/test/java/org/apache/shardingsphere/mode/manager/standalone/persist/service/StandaloneMetaDataManagerPersistServiceTest.java b/mode/type/standalone/core/src/test/java/org/apache/shardingsphere/mode/manager/standalone/persist/service/StandaloneMetaDataManagerPersistServiceTest.java index ad901f74cba..b4be1f45615 100644 --- a/mode/type/standalone/core/src/test/java/org/apache/shardingsphere/mode/manager/standalone/persist/service/StandaloneMetaDataManagerPersistServiceTest.java +++ b/mode/type/standalone/core/src/test/java/org/apache/shardingsphere/mode/manager/standalone/persist/service/StandaloneMetaDataManagerPersistServiceTest.java @@ -21,11 +21,16 @@ import lombok.SneakyThrows; import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; import org.apache.shardingsphere.infra.config.rule.RuleConfiguration; import org.apache.shardingsphere.infra.database.core.metadata.database.enums.TableType; +import org.apache.shardingsphere.infra.database.core.type.DatabaseType; import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema; import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereTable; +import org.apache.shardingsphere.infra.rule.ShardingSphereRule; +import org.apache.shardingsphere.infra.rule.attribute.RuleAttributes; +import org.apache.shardingsphere.infra.rule.attribute.table.TableMapperRuleAttribute; +import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; import org.apache.shardingsphere.mode.metadata.changed.RuleItemChangedNodePathBuilder; import org.apache.shardingsphere.mode.metadata.manager.MetaDataContextManager; import org.apache.shardingsphere.mode.metadata.persist.MetaDataPersistFacade; @@ -165,8 +170,12 @@ class StandaloneMetaDataManagerPersistServiceTest { @Test void assertAlterRuleConfiguration() throws SQLException { - ShardingSphereDatabase database = mock(ShardingSphereDatabase.class); + ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS); when(database.getName()).thenReturn("foo_db"); + when(database.getProtocolType()).thenReturn(TypedSPILoader.getService(DatabaseType.class, "FIXTURE")); + ShardingSphereRule rule = mock(ShardingSphereRule.class); + when(rule.getAttributes()).thenReturn(new RuleAttributes(mock(TableMapperRuleAttribute.class))); + when(database.getRuleMetaData().getRules()).thenReturn(Collections.singleton(rule)); ShardingSphereMetaData metaData = new ShardingSphereMetaData(Collections.singleton(database), mock(), mock(), new ConfigurationProperties(new Properties())); when(metaDataContextManager.getMetaDataContexts().getMetaData()).thenReturn(metaData); RuleConfiguration ruleConfig = mock(RuleConfiguration.class, RETURNS_DEEP_STUBS); @@ -190,6 +199,14 @@ class StandaloneMetaDataManagerPersistServiceTest { @Test void assertRemoveRuleConfigurationItem() throws SQLException { + ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS); + when(database.getName()).thenReturn("foo_db"); + when(database.getProtocolType()).thenReturn(TypedSPILoader.getService(DatabaseType.class, "FIXTURE")); + ShardingSphereRule rule = mock(ShardingSphereRule.class); + when(rule.getAttributes()).thenReturn(new RuleAttributes(mock(TableMapperRuleAttribute.class))); + when(database.getRuleMetaData().getRules()).thenReturn(Collections.singleton(rule)); + ShardingSphereMetaData metaData = new ShardingSphereMetaData(Collections.singleton(database), mock(), mock(), new ConfigurationProperties(new Properties())); + when(metaDataContextManager.getMetaDataContexts().getMetaData()).thenReturn(metaData); RuleConfiguration ruleConfig = mock(RuleConfiguration.class, RETURNS_DEEP_STUBS); MetaDataVersion metaDataVersion = mock(MetaDataVersion.class); when(metaDataPersistFacade.getDatabaseRuleService().delete("foo_db", Collections.singleton(ruleConfig))).thenReturn(Collections.singleton(metaDataVersion)); @@ -198,7 +215,7 @@ class StandaloneMetaDataManagerPersistServiceTest { when(metaDataVersion.getNodePath()).thenReturn(databaseRuleNodePath); when(ruleItemChangedNodePathBuilder.build(eq("foo_db"), any())).thenReturn(Optional.of(databaseRuleNodePath)); setRuleItemChangedBuildExecutor(ruleItemChangedNodePathBuilder); - metaDataManagerPersistService.removeRuleConfigurationItem(new ShardingSphereDatabase("foo_db", mock(), mock(), mock(), Collections.emptyList()), ruleConfig); + metaDataManagerPersistService.removeRuleConfigurationItem(database, ruleConfig); verify(metaDataContextManager.getDatabaseRuleItemManager()).drop(databaseRuleNodePath); }