Skip to content

Commit

Permalink
Fix loss storage unit when register storage unit (#29281)
Browse files Browse the repository at this point in the history
* Refactor register storage unit loss storage unit problem

* Fix checkstyle
  • Loading branch information
zhaojinchao95 authored Dec 6, 2023
1 parent 6b127cb commit c99d91e
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public synchronized void unregisterStorageUnit(final String databaseName, final
Collection<ResourceHeldRule> staleResourceHeldRules = getStaleResourceHeldRules(databaseName);
staleResourceHeldRules.forEach(ResourceHeldRule::closeStaleResource);
SwitchingResource switchingResource = new NewResourceSwitchManager().unregisterStorageUnit(metaDataContexts.get().getMetaData().getDatabase(databaseName).getResourceMetaData(),
storageUnitName);
Collections.singletonList(storageUnitName));
buildNewMetaDataContext(databaseName, switchingResource);
} catch (final SQLException ex) {
log.error("Alter database: {} register storage unit failed", databaseName, ex);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,23 +105,35 @@ private Map<StorageNode, DataSource> getStaleDataSources(final ResourceMetaData
* Unregister storage unit.
*
* @param resourceMetaData resource meta data
* @param storageUnitName storage unit name
* @param storageUnitNames storage unit names
* @return created switching resource
*/
public SwitchingResource unregisterStorageUnit(final ResourceMetaData resourceMetaData, final String storageUnitName) {
public SwitchingResource unregisterStorageUnit(final ResourceMetaData resourceMetaData, final Collection<String> storageUnitNames) {
Map<String, DataSourcePoolProperties> mergedDataSourcePoolPropertiesMap = new LinkedHashMap<>(resourceMetaData.getStorageUnits().entrySet().stream()
.collect(Collectors.toMap(Entry::getKey, entry -> entry.getValue().getDataSourcePoolProperties(), (oldValue, currentValue) -> oldValue, LinkedHashMap::new)));
mergedDataSourcePoolPropertiesMap.keySet().removeIf(each -> each.equals(storageUnitName));
resourceMetaData.getStorageUnits().remove(storageUnitName);
return new SwitchingResource(Collections.emptyMap(),
getToBeRemovedStaleDataSource(resourceMetaData, storageUnitName), Collections.singleton(storageUnitName), mergedDataSourcePoolPropertiesMap);
SwitchingResource result = new SwitchingResource(Collections.emptyMap(),
getToBeRemovedStaleDataSource(resourceMetaData, storageUnitNames), storageUnitNames, mergedDataSourcePoolPropertiesMap);
removeToBeRemovedStorageUnitNames(resourceMetaData, mergedDataSourcePoolPropertiesMap, storageUnitNames);
return result;
}

private Map<StorageNode, DataSource> getToBeRemovedStaleDataSource(final ResourceMetaData resourceMetaData, final Collection<String> storageUnitNames) {
Map<StorageNode, DataSource> result = new LinkedHashMap<>();
for (String each : storageUnitNames) {
if (!resourceMetaData.getStorageUnits().containsKey(each)) {
return Collections.emptyMap();
}
StorageNode storageNode = resourceMetaData.getStorageUnits().get(each).getStorageNode();
result.put(storageNode, resourceMetaData.getDataSources().get(storageNode));
}
return result;
}

private Map<StorageNode, DataSource> getToBeRemovedStaleDataSource(final ResourceMetaData resourceMetaData, final String storageUnitName) {
if (!resourceMetaData.getStorageUnits().containsKey(storageUnitName)) {
return Collections.emptyMap();
private void removeToBeRemovedStorageUnitNames(final ResourceMetaData resourceMetaData, final Map<String, DataSourcePoolProperties> dataSourcePoolPropsMap,
final Collection<String> storageUnitNames) {
for (String each : storageUnitNames) {
dataSourcePoolPropsMap.remove(each);
resourceMetaData.getStorageUnits().remove(each);
}
StorageNode storageNode = resourceMetaData.getStorageUnits().get(storageUnitName).getStorageNode();
return Collections.singletonMap(storageNode, resourceMetaData.getDataSources().get(storageNode));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
import org.apache.shardingsphere.metadata.persist.service.database.DatabaseMetaDataBasedPersistService;
import org.apache.shardingsphere.mode.manager.ContextManager;
import org.apache.shardingsphere.mode.manager.ContextManagerAware;
import org.apache.shardingsphere.mode.manager.switcher.ResourceSwitchManager;
import org.apache.shardingsphere.mode.manager.switcher.NewResourceSwitchManager;
import org.apache.shardingsphere.mode.manager.switcher.SwitchingResource;
import org.apache.shardingsphere.mode.metadata.MetaDataContexts;

Expand Down Expand Up @@ -209,7 +209,7 @@ private void refreshMetaDataHeldRule(final ShardingSphereDatabase database) {
@Override
public void registerStorageUnits(final String databaseName, final Map<String, DataSourcePoolProperties> toBeRegisteredProps) throws SQLException {
SwitchingResource switchingResource =
new ResourceSwitchManager().create(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getResourceMetaData(), toBeRegisteredProps);
new NewResourceSwitchManager().registerStorageUnit(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getResourceMetaData(), toBeRegisteredProps);
contextManager.getMetaDataContexts().getMetaData().getDatabases().putAll(contextManager.getConfigurationContextManager().createChangedDatabases(databaseName, false, switchingResource, null));
contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().findRules(ResourceHeldRule.class)
.forEach(each -> each.addResource(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName)));
Expand All @@ -224,7 +224,7 @@ public void registerStorageUnits(final String databaseName, final Map<String, Da
@Override
public void alterStorageUnits(final String databaseName, final Map<String, DataSourcePoolProperties> toBeUpdatedProps) throws SQLException {
SwitchingResource switchingResource =
new ResourceSwitchManager().create(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getResourceMetaData(), toBeUpdatedProps);
new NewResourceSwitchManager().alterStorageUnit(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getResourceMetaData(), toBeUpdatedProps);
contextManager.getMetaDataContexts().getMetaData().getDatabases().putAll(contextManager.getConfigurationContextManager().createChangedDatabases(databaseName, true, switchingResource, null));
contextManager.getMetaDataContexts().getMetaData().getGlobalRuleMetaData().findRules(ResourceHeldRule.class)
.forEach(each -> each.addResource(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName)));
Expand All @@ -236,33 +236,19 @@ public void alterStorageUnits(final String databaseName, final Map<String, DataS

@Override
public void unregisterStorageUnits(final String databaseName, final Collection<String> toBeDroppedStorageUnitNames) throws SQLException {
Map<String, DataSourcePoolProperties> propsMap = contextManager.getMetaDataContexts().getPersistService().getDataSourceUnitService()
.load(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getName());
Map<String, DataSourcePoolProperties> toBeDeletedPropsMap = getToBeDeletedPropertiesMap(propsMap, toBeDroppedStorageUnitNames);
SwitchingResource switchingResource =
new ResourceSwitchManager().createByDropResource(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getResourceMetaData(), toBeDeletedPropsMap);
new NewResourceSwitchManager().unregisterStorageUnit(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getResourceMetaData(), toBeDroppedStorageUnitNames);
contextManager.getMetaDataContexts().getMetaData().getDatabases()
.putAll(contextManager.getConfigurationContextManager().renewDatabase(contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName), switchingResource));
MetaDataContexts reloadMetaDataContexts = contextManager.getConfigurationContextManager().createMetaDataContexts(databaseName, false, switchingResource, null);
contextManager.getConfigurationContextManager().alterSchemaMetaData(databaseName, reloadMetaDataContexts.getMetaData().getDatabase(databaseName),
contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName));
contextManager.deletedSchemaNames(databaseName, reloadMetaDataContexts.getMetaData().getDatabase(databaseName), contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName));
contextManager.renewMetaDataContexts(reloadMetaDataContexts);
Map<String, DataSourcePoolProperties> toBeReversedPropsMap = getToBeReversedDataSourcePoolPropertiesMap(propsMap, toBeDroppedStorageUnitNames);
contextManager.getMetaDataContexts().getPersistService().getDataSourceUnitService().persist(
contextManager.getMetaDataContexts().getMetaData().getDatabase(databaseName).getName(), toBeReversedPropsMap);
switchingResource.closeStaleDataSources();
clearServiceCache();
}

private Map<String, DataSourcePoolProperties> getToBeDeletedPropertiesMap(final Map<String, DataSourcePoolProperties> propsMap, final Collection<String> toBeDroppedResourceNames) {
return propsMap.entrySet().stream().filter(entry -> toBeDroppedResourceNames.contains(entry.getKey())).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
}

private Map<String, DataSourcePoolProperties> getToBeReversedDataSourcePoolPropertiesMap(final Map<String, DataSourcePoolProperties> propsMap, final Collection<String> toBeDroppedResourceNames) {
return propsMap.entrySet().stream().filter(entry -> !toBeDroppedResourceNames.contains(entry.getKey())).collect(Collectors.toMap(Entry::getKey, Entry::getValue));
}

@Override
public void alterRuleConfiguration(final String databaseName, final Collection<RuleConfiguration> ruleConfigs) {
contextManager.getConfigurationContextManager().alterRuleConfiguration(databaseName, ruleConfigs);
Expand Down

0 comments on commit c99d91e

Please sign in to comment.