You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by ji...@apache.org on 2024/11/12 13:13:28 UTC

(shardingsphere) 19/42: Pick 5.5.0-fix, optimize show/alter storage units (#26)

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

jiangmaolin pushed a commit to branch dev-5.5.1
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git

commit 271dedeb178695fac6d480a182c569c51b04c37c
Author: Raigor <ra...@gmail.com>
AuthorDate: Wed Oct 30 21:28:13 2024 +0800

    Pick 5.5.0-fix, optimize show/alter storage units (#26)
---
 .../AlterStorageUnitConnectionInfoException.java   |   4 +
 infra/distsql-handler/pom.xml                      |   7 ++
 .../rdl/resource/AlterStorageUnitExecutor.java     |  20 +++-
 .../rdl/resource/RegisterStorageUnitExecutor.java  |  14 +++
 .../rql/resource/ShowStorageUnitExecutor.java      |  68 ++++++++----
 mode/core/pom.xml                                  |   7 ++
 .../mode/metadata/manager/StorageUnitManager.java  | 115 +++++++++++++++++++++
 .../engine/src/main/antlr4/imports/RDLStatement.g4 |  14 ++-
 .../core/kernel/KernelDistSQLStatementVisitor.java |  34 ++++--
 .../segment/AlterPoolPropertiesSegment.java        |  20 ++--
 .../converter/DataSourceSegmentsConverter.java     |  95 +++++++++++++++++
 .../test/resources/cases/ral/e2e-ral-refresh.xml   |   5 +-
 .../src/test/resources/cases/rql/e2e-rql-show.xml  |   5 +-
 13 files changed, 366 insertions(+), 42 deletions(-)

diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/kernel/metadata/resource/storageunit/AlterStorageUnitConnectionInfoException.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/kernel/metadata/resource/storageunit/AlterStorageUnitConnectionInfoException.java
index 57e2dd9b64d..0fd249879b1 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/kernel/metadata/resource/storageunit/AlterStorageUnitConnectionInfoException.java
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/kernel/metadata/resource/storageunit/AlterStorageUnitConnectionInfoException.java
@@ -32,4 +32,8 @@ public final class AlterStorageUnitConnectionInfoException extends ResourceDefin
     public AlterStorageUnitConnectionInfoException(final Collection<String> storageUnitNames) {
         super(XOpenSQLState.FEATURE_NOT_SUPPORTED, 11, "Can not alter connection info in storage units: '%s'.", storageUnitNames);
     }
+    
+    public AlterStorageUnitConnectionInfoException(final String message) {
+        super(XOpenSQLState.FEATURE_NOT_SUPPORTED, 11, message);
+    }
 }
diff --git a/infra/distsql-handler/pom.xml b/infra/distsql-handler/pom.xml
index c6bc2905269..9b9c53ad61c 100644
--- a/infra/distsql-handler/pom.xml
+++ b/infra/distsql-handler/pom.xml
@@ -47,6 +47,13 @@
             <artifactId>shardingsphere-mode-core</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <!-- SPEX ADDED: BEGIN -->
+        <dependency>
+            <groupId>com.zaxxer</groupId>
+            <artifactId>HikariCP</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <!-- SPEX ADDED: END -->
         
         <dependency>
             <groupId>org.apache.shardingsphere</groupId>
diff --git a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutor.java b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutor.java
index bc68f391b2e..3617cf41e87 100644
--- a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutor.java
+++ b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutor.java
@@ -17,11 +17,14 @@
 
 package org.apache.shardingsphere.distsql.handler.executor.rdl.resource;
 
+import com.sphereex.dbplusengine.SphereEx;
+import com.sphereex.dbplusengine.SphereEx.Type;
 import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.shardingsphere.distsql.handler.aware.DistSQLExecutorDatabaseAware;
 import org.apache.shardingsphere.distsql.handler.engine.update.DistSQLUpdateExecutor;
 import org.apache.shardingsphere.distsql.handler.validate.DistSQLDataSourcePoolPropertiesValidator;
+import org.apache.shardingsphere.distsql.segment.AlterPoolPropertiesSegment;
 import org.apache.shardingsphere.distsql.segment.DataSourceSegment;
 import org.apache.shardingsphere.distsql.segment.HostnameAndPortBasedDataSourceSegment;
 import org.apache.shardingsphere.distsql.segment.URLBasedDataSourceSegment;
@@ -44,6 +47,7 @@ import org.apache.shardingsphere.mode.manager.ContextManager;
 
 import java.sql.SQLException;
 import java.util.Collection;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Objects;
@@ -60,11 +64,14 @@ public final class AlterStorageUnitExecutor implements DistSQLUpdateExecutor<Alt
     
     private ShardingSphereDatabase database;
     
+    @SphereEx(Type.MODIFY)
     @Override
     public void executeUpdate(final AlterStorageUnitStatement sqlStatement, final ContextManager contextManager) {
         checkBefore(sqlStatement);
-        Map<String, DataSourcePoolProperties> propsMap = DataSourceSegmentsConverter.convert(database.getProtocolType(), sqlStatement.getStorageUnits());
-        validateHandler.validate(propsMap, getExpectedPrivileges(sqlStatement));
+        Map<String, DataSourcePoolProperties> propsMap = DataSourceSegmentsConverter.convert(database.getProtocolType(), database.getResourceMetaData(), sqlStatement.getStorageUnits());
+        if (!sqlStatement.getStorageUnits().stream().allMatch(each -> each instanceof AlterPoolPropertiesSegment && null == each.getUser())) {
+            validateHandler.validate(propsMap, getExpectedPrivileges(sqlStatement));
+        }
         try {
             contextManager.getPersistServiceFacade().getMetaDataManagerPersistService().alterStorageUnits(database.getName(), propsMap);
         } catch (final SQLException | ShardingSphereExternalException ex) {
@@ -89,8 +96,15 @@ public final class AlterStorageUnitExecutor implements DistSQLUpdateExecutor<Alt
         ShardingSpherePreconditions.checkMustEmpty(notExistedStorageUnitNames, () -> new MissingRequiredStorageUnitsException(database.getName(), notExistedStorageUnitNames));
     }
     
+    @SphereEx(Type.MODIFY)
     private void checkDatabase(final AlterStorageUnitStatement sqlStatement) {
-        Collection<String> invalidStorageUnitNames = sqlStatement.getStorageUnits().stream().collect(Collectors.toMap(DataSourceSegment::getName, each -> each)).entrySet().stream()
+        Map<String, DataSourceSegment> toBeCheckedSegments = new LinkedHashMap<>(sqlStatement.getStorageUnits().size(), 1F);
+        for (DataSourceSegment each : sqlStatement.getStorageUnits()) {
+            if (each instanceof HostnameAndPortBasedDataSourceSegment || each instanceof URLBasedDataSourceSegment) {
+                toBeCheckedSegments.put(each.getName(), each);
+            }
+        }
+        Collection<String> invalidStorageUnitNames = toBeCheckedSegments.entrySet().stream()
                 .filter(each -> !isSameDatabase(each.getValue(), database.getResourceMetaData().getStorageUnits().get(each.getKey()))).map(Entry::getKey).collect(Collectors.toSet());
         ShardingSpherePreconditions.checkMustEmpty(invalidStorageUnitNames, () -> new AlterStorageUnitConnectionInfoException(invalidStorageUnitNames));
     }
diff --git a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutor.java b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutor.java
index d4255a24205..8077ce7ab12 100644
--- a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutor.java
+++ b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutor.java
@@ -17,12 +17,15 @@
 
 package org.apache.shardingsphere.distsql.handler.executor.rdl.resource;
 
+import com.sphereex.dbplusengine.SphereEx;
 import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.shardingsphere.distsql.handler.aware.DistSQLExecutorDatabaseAware;
 import org.apache.shardingsphere.distsql.handler.engine.update.DistSQLUpdateExecutor;
 import org.apache.shardingsphere.distsql.handler.validate.DistSQLDataSourcePoolPropertiesValidator;
 import org.apache.shardingsphere.distsql.segment.DataSourceSegment;
+import org.apache.shardingsphere.distsql.segment.HostnameAndPortBasedDataSourceSegment;
+import org.apache.shardingsphere.distsql.segment.URLBasedDataSourceSegment;
 import org.apache.shardingsphere.distsql.segment.converter.DataSourceSegmentsConverter;
 import org.apache.shardingsphere.distsql.statement.rdl.resource.unit.type.RegisterStorageUnitStatement;
 import org.apache.shardingsphere.infra.database.core.checker.PrivilegeCheckType;
@@ -55,6 +58,9 @@ public final class RegisterStorageUnitExecutor implements DistSQLUpdateExecutor<
     
     @Override
     public void executeUpdate(final RegisterStorageUnitStatement sqlStatement, final ContextManager contextManager) {
+        // SPEX ADDED: BEGIN
+        checkSegmentType(sqlStatement);
+        // SPEX ADDED: END
         checkDataSource(sqlStatement, contextManager);
         Map<String, DataSourcePoolProperties> propsMap = DataSourceSegmentsConverter.convert(database.getProtocolType(), sqlStatement.getStorageUnits());
         if (sqlStatement.isIfNotExists()) {
@@ -74,6 +80,14 @@ public final class RegisterStorageUnitExecutor implements DistSQLUpdateExecutor<
         }
     }
     
+    @SphereEx
+    private void checkSegmentType(final RegisterStorageUnitStatement sqlStatement) {
+        for (DataSourceSegment each : sqlStatement.getStorageUnits()) {
+            ShardingSpherePreconditions.checkState(each instanceof HostnameAndPortBasedDataSourceSegment || each instanceof URLBasedDataSourceSegment,
+                    () -> new UnsupportedOperationException(String.format("Missing connection information for register storage unit %s.", each.getName())));
+        }
+    }
+    
     private void checkDataSource(final RegisterStorageUnitStatement sqlStatement, final ContextManager contextManager) {
         if (!sqlStatement.isIfNotExists()) {
             Collection<String> dataSourceNames = new ArrayList<>(sqlStatement.getStorageUnits().size());
diff --git a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rql/resource/ShowStorageUnitExecutor.java b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rql/resource/ShowStorageUnitExecutor.java
index 7191974b4bd..d60c5ee9484 100644
--- a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rql/resource/ShowStorageUnitExecutor.java
+++ b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rql/resource/ShowStorageUnitExecutor.java
@@ -17,12 +17,14 @@
 
 package org.apache.shardingsphere.distsql.handler.executor.rql.resource;
 
+import com.sphereex.dbplusengine.SphereEx;
+import com.sphereex.dbplusengine.SphereEx.Type;
+import com.zaxxer.hikari.HikariDataSource;
 import lombok.Setter;
 import org.apache.shardingsphere.distsql.handler.aware.DistSQLExecutorDatabaseAware;
 import org.apache.shardingsphere.distsql.handler.engine.query.DistSQLQueryExecutor;
 import org.apache.shardingsphere.distsql.statement.rql.resource.ShowStorageUnitsStatement;
 import org.apache.shardingsphere.infra.database.core.connector.ConnectionProperties;
-import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
 import org.apache.shardingsphere.infra.datasource.pool.CatalogSwitchableDataSource;
 import org.apache.shardingsphere.infra.datasource.pool.props.creator.DataSourcePoolPropertiesCreator;
 import org.apache.shardingsphere.infra.datasource.pool.props.domain.DataSourcePoolProperties;
@@ -51,26 +53,36 @@ public final class ShowStorageUnitExecutor implements DistSQLQueryExecutor<ShowS
     
     private ShardingSphereDatabase database;
     
+    @SphereEx(Type.MODIFY)
     @Override
     public Collection<String> getColumnNames(final ShowStorageUnitsStatement sqlStatement) {
         return Arrays.asList("name", "type", "host", "port", "db", "connection_timeout_milliseconds", "idle_timeout_milliseconds",
-                "max_lifetime_milliseconds", "max_pool_size", "min_pool_size", "read_only", "other_attributes");
+                "max_lifetime_milliseconds", "max_pool_size", "min_pool_size", "read_only", "other_attributes", "username", "pool_name", "actual_jdbc_url");
     }
     
+    @SphereEx(Type.MODIFY)
     @Override
     public Collection<LocalDataQueryResultRow> getRows(final ShowStorageUnitsStatement sqlStatement, final ContextManager contextManager) {
         return getStorageUnits(sqlStatement).entrySet().stream().map(entry -> getRow(entry.getKey(), entry.getValue())).collect(Collectors.toList());
     }
     
+    @SphereEx(Type.MODIFY)
     private LocalDataQueryResultRow getRow(final String name, final StorageUnit storageUnit) {
         ConnectionProperties connectionProps = storageUnit.getConnectionProperties();
-        DataSourcePoolProperties dataSourcePoolProps = getDataSourcePoolProperties(storageUnit);
+        DataSource actualDataSource = getActualDataSource(storageUnit.getDataSource());
+        DataSourcePoolProperties dataSourcePoolProps = getDataSourcePoolProperties(actualDataSource);
         Map<String, Object> poolProps = dataSourcePoolProps.getPoolPropertySynonyms().getStandardProperties();
         Map<String, Object> customProps = getCustomProperties(dataSourcePoolProps.getCustomProperties().getProperties(), connectionProps.getQueryProperties());
         return new LocalDataQueryResultRow(name, storageUnit.getStorageType().getType(), connectionProps.getHostname(), connectionProps.getPort(), connectionProps.getCatalog(),
-                getStandardProperty(poolProps, "connectionTimeoutMilliseconds"), getStandardProperty(poolProps, "idleTimeoutMilliseconds"),
-                getStandardProperty(poolProps, "maxLifetimeMilliseconds"), getStandardProperty(poolProps, "maxPoolSize"), getStandardProperty(poolProps, "minPoolSize"),
-                getStandardProperty(poolProps, "readOnly"), customProps);
+                getStandardProperty(poolProps, "connectionTimeoutMilliseconds"),
+                getStandardProperty(poolProps, "idleTimeoutMilliseconds"),
+                getStandardProperty(poolProps, "maxLifetimeMilliseconds"),
+                getStandardProperty(poolProps, "maxPoolSize"),
+                getStandardProperty(poolProps, "minPoolSize"),
+                getStandardProperty(poolProps, "readOnly"),
+                customProps,
+                getUsername(actualDataSource, dataSourcePoolProps.getAllStandardProperties()),
+                getPoolName(actualDataSource), getActualURL(actualDataSource));
     }
     
     private Map<String, StorageUnit> getStorageUnits(final ShowStorageUnitsStatement sqlStatement) {
@@ -82,18 +94,9 @@ public final class ShowStorageUnitExecutor implements DistSQLQueryExecutor<ShowS
         return sqlStatement.getLikePattern().map(optional -> Pattern.compile(RegexUtils.convertLikePatternToRegex(optional), Pattern.CASE_INSENSITIVE));
     }
     
-    private DataSourcePoolProperties getDataSourcePoolProperties(final StorageUnit storageUnit) {
-        DataSource dataSource = storageUnit.getDataSource();
-        DataSourcePoolProperties result = DataSourcePoolPropertiesCreator.create(
-                dataSource instanceof CatalogSwitchableDataSource ? ((CatalogSwitchableDataSource) dataSource).getDataSource() : dataSource);
-        if (new DatabaseTypeRegistry(storageUnit.getStorageType()).getDialectDatabaseMetaData().isInstanceConnectionAvailable()) {
-            for (Entry<String, Object> entry : storageUnit.getDataSourcePoolProperties().getPoolPropertySynonyms().getStandardProperties().entrySet()) {
-                if (null != entry.getValue()) {
-                    result.getPoolPropertySynonyms().getStandardProperties().put(entry.getKey(), entry.getValue());
-                }
-            }
-        }
-        return result;
+    @SphereEx(Type.MODIFY)
+    private DataSourcePoolProperties getDataSourcePoolProperties(final DataSource actualDataSource) {
+        return DataSourcePoolPropertiesCreator.create(actualDataSource);
     }
     
     private Map<String, Object> getCustomProperties(final Map<String, Object> customProps, final Properties queryProps) {
@@ -109,6 +112,35 @@ public final class ShowStorageUnitExecutor implements DistSQLQueryExecutor<ShowS
         return standardProps.containsKey(key) && null != standardProps.get(key) ? standardProps.get(key).toString() : "";
     }
     
+    @SphereEx
+    private DataSource getActualDataSource(final DataSource dataSource) {
+        return dataSource instanceof CatalogSwitchableDataSource ? ((CatalogSwitchableDataSource) dataSource).getDataSource() : dataSource;
+    }
+    
+    @SphereEx
+    private String getUsername(final DataSource actualDataSource, final Map<String, Object> standardProps) {
+        if (actualDataSource instanceof HikariDataSource) {
+            return ((HikariDataSource) actualDataSource).getUsername();
+        }
+        return getStandardProperty(standardProps, "username");
+    }
+    
+    @SphereEx
+    private String getPoolName(final DataSource actualDataSource) {
+        if (actualDataSource instanceof HikariDataSource) {
+            return ((HikariDataSource) actualDataSource).getPoolName();
+        }
+        return "";
+    }
+    
+    @SphereEx
+    private String getActualURL(final DataSource actualDataSource) {
+        if (actualDataSource instanceof HikariDataSource) {
+            return ((HikariDataSource) actualDataSource).getJdbcUrl();
+        }
+        return "";
+    }
+    
     @Override
     public Class<ShowStorageUnitsStatement> getType() {
         return ShowStorageUnitsStatement.class;
diff --git a/mode/core/pom.xml b/mode/core/pom.xml
index c434fa90b01..2ef28ca4628 100644
--- a/mode/core/pom.xml
+++ b/mode/core/pom.xml
@@ -42,6 +42,13 @@
             <artifactId>shardingsphere-metadata-core</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <!-- SPEX ADDED: BEGIN -->
+        <dependency>
+            <groupId>com.zaxxer</groupId>
+            <artifactId>HikariCP</artifactId>
+            <scope>compile</scope>
+        </dependency>
+        <!-- SPEX ADDED: END -->
         
         <dependency>
             <groupId>org.apache.shardingsphere</groupId>
diff --git a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/manager/StorageUnitManager.java b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/manager/StorageUnitManager.java
index 192c0e6b066..c4ad1c35282 100644
--- a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/manager/StorageUnitManager.java
+++ b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/manager/StorageUnitManager.java
@@ -20,12 +20,20 @@ package org.apache.shardingsphere.mode.metadata.manager;
 import com.sphereex.dbplusengine.SphereEx;
 import com.sphereex.dbplusengine.SphereEx.Type;
 import com.sphereex.dbplusengine.infra.version.DatabaseProtocolServerInfoRefreshEngine;
+import com.zaxxer.hikari.HikariConfigMXBean;
+import com.zaxxer.hikari.HikariDataSource;
 import lombok.SneakyThrows;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.shardingsphere.infra.config.props.temporary.TemporaryConfigurationPropertyKey;
+import org.apache.shardingsphere.infra.datasource.pool.destroyer.DataSourcePoolDestroyer;
 import org.apache.shardingsphere.infra.datasource.pool.props.domain.DataSourcePoolProperties;
+import org.apache.shardingsphere.infra.datasource.pool.props.domain.synonym.ConnectionPropertySynonyms;
+import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
 import org.apache.shardingsphere.infra.instance.ComputeNodeInstanceContext;
 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
+import org.apache.shardingsphere.infra.metadata.database.resource.node.StorageNode;
+import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit;
 import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
 import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 import org.apache.shardingsphere.metadata.persist.MetaDataPersistService;
@@ -33,10 +41,12 @@ import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
 import org.apache.shardingsphere.mode.metadata.MetaDataContextsFactory;
 import org.apache.shardingsphere.mode.spi.PersistRepository;
 
+import javax.sql.DataSource;
 import java.sql.SQLException;
 import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.concurrent.atomic.AtomicReference;
 
 /**
@@ -95,12 +105,117 @@ public final class StorageUnitManager {
             @SphereEx(Type.MODIFY)
             SwitchingResource switchingResource = resourceSwitchManager.switchByAlterStorageUnit(metaDataContexts.get().getMetaData()
                     .getDatabase(databaseName).getResourceMetaData(), propsMap, isInstanceConnectionEnabled);
+            // SPEX ADDED: BEGIN
+            ResourceMetaData resourceMetaData = metaDataContexts.get().getMetaData().getDatabase(databaseName).getResourceMetaData();
+            if (canBeChangedInRuntime(resourceMetaData, propsMap)) {
+                alterDataSourcePoolPros(resourceMetaData, switchingResource, propsMap);
+                closeNewDataSources(switchingResource);
+                return;
+            }
+            // SPEX ADDED: END
             buildNewMetaDataContext(databaseName, switchingResource);
         } catch (final SQLException ex) {
             log.error("Alter database: {} register storage unit failed", databaseName, ex);
         }
     }
     
+    @SphereEx
+    private boolean canBeChangedInRuntime(final ResourceMetaData resourceMetaData, final Map<String, DataSourcePoolProperties> propsMap) {
+        for (Entry<String, DataSourcePoolProperties> entry : propsMap.entrySet()) {
+            if (!resourceMetaData.getStorageUnits().containsKey(entry.getKey())) {
+                continue;
+            }
+            if (!entry.getValue().getCustomProperties().getProperties().containsKey("alterInRuntime")) {
+                return false;
+            }
+            ConnectionPropertySynonyms currentConnectionProps = resourceMetaData.getStorageUnits().get(entry.getKey()).getDataSourcePoolProperties().getConnectionPropertySynonyms();
+            ConnectionPropertySynonyms newConnectionProps = entry.getValue().getConnectionPropertySynonyms();
+            if (!currentConnectionProps.getStandardProperties().get("url").equals(newConnectionProps.getStandardProperties().get("url"))) {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    @SphereEx
+    private void alterDataSourcePoolPros(final ResourceMetaData resourceMetaData, final SwitchingResource switchingResource, final Map<String, DataSourcePoolProperties> propsMap) {
+        for (Entry<String, DataSourcePoolProperties> entry : propsMap.entrySet()) {
+            StorageUnit storageUnit = resourceMetaData.getStorageUnits().get(entry.getKey());
+            if (null == storageUnit) {
+                continue;
+            }
+            if (!switchingResource.getNewDataSources().containsKey(storageUnit.getStorageNode())) {
+                continue;
+            }
+            DataSource newDataSource = switchingResource.getNewDataSources().get(storageUnit.getStorageNode());
+            ShardingSpherePreconditions.checkState(newDataSource instanceof HikariDataSource,
+                    () -> new UnsupportedOperationException("The new data source must be HikariDataSource when alter pool properties."));
+            Map<String, Object> standardProperties = entry.getValue().getConnectionPropertySynonyms().getStandardProperties();
+            if (!((HikariDataSource) newDataSource).getJdbcUrl().equals(standardProperties.get("url"))) {
+                continue;
+            }
+            DataSource staleDataSource = switchingResource.getStaleDataSources().get(storageUnit.getStorageNode());
+            if (null == staleDataSource) {
+                continue;
+            }
+            ShardingSpherePreconditions.checkState(staleDataSource instanceof HikariDataSource,
+                    () -> new UnsupportedOperationException("The stale data source must be HikariDataSource when alter pool properties."));
+            HikariConfigMXBean configMXBean = ((HikariDataSource) staleDataSource).getHikariConfigMXBean();
+            HikariConfigMXBean newConfigMXBean = ((HikariDataSource) newDataSource).getHikariConfigMXBean();
+            if (newConfigMXBean.getMaximumPoolSize() != configMXBean.getMaximumPoolSize()) {
+                log.warn("Update maxPoolSize of pool `{}` from {} to {}", configMXBean.getPoolName(), configMXBean.getMaximumPoolSize(), newConfigMXBean.getMaximumPoolSize());
+                configMXBean.setMaximumPoolSize(newConfigMXBean.getMaximumPoolSize());
+            }
+            if (newConfigMXBean.getMinimumIdle() != configMXBean.getMinimumIdle()) {
+                log.warn("Update minIdle of pool `{}` from {} to {}", configMXBean.getPoolName(), configMXBean.getMinimumIdle(), newConfigMXBean.getMinimumIdle());
+                configMXBean.setMinimumIdle(newConfigMXBean.getMinimumIdle());
+            }
+            if (newConfigMXBean.getConnectionTimeout() != configMXBean.getConnectionTimeout()) {
+                log.warn("Update connectionTimeoutMs of pool `{}` from {} to {}", configMXBean.getPoolName(), configMXBean.getConnectionTimeout(), newConfigMXBean.getConnectionTimeout());
+                configMXBean.setConnectionTimeout(newConfigMXBean.getConnectionTimeout());
+            }
+            if (newConfigMXBean.getIdleTimeout() != configMXBean.getIdleTimeout()) {
+                log.warn("Update idleTimeoutMs of pool `{}` from {} to {}", configMXBean.getPoolName(), configMXBean.getIdleTimeout(), newConfigMXBean.getIdleTimeout());
+                configMXBean.setIdleTimeout(newConfigMXBean.getIdleTimeout());
+            }
+            if (newConfigMXBean.getMaxLifetime() != configMXBean.getMaxLifetime()) {
+                log.warn("Update maxLifetimeMs of pool `{}` from {} to {}", configMXBean.getPoolName(), configMXBean.getMaxLifetime(), newConfigMXBean.getMaxLifetime());
+                configMXBean.setMaxLifetime(newConfigMXBean.getMaxLifetime());
+            }
+            if (isUsernameOrPasswordChanged((HikariDataSource) newDataSource, (HikariDataSource) staleDataSource)) {
+                configMXBean.setUsername(((HikariDataSource) newDataSource).getUsername());
+                configMXBean.setPassword(((HikariDataSource) newDataSource).getPassword());
+                log.warn("Update username and password of pool `{}`", configMXBean.getPoolName());
+            }
+        }
+        for (Entry<String, StorageUnit> entry : resourceMetaData.getStorageUnits().entrySet()) {
+            DataSourcePoolProperties newDataSourceProperties = switchingResource.getMergedDataSourcePoolPropertiesMap().get(entry.getKey());
+            if (null != newDataSourceProperties) {
+                alterDataSourceProperties(entry.getValue(), newDataSourceProperties);
+            }
+        }
+    }
+    
+    @SphereEx
+    private boolean isUsernameOrPasswordChanged(final HikariDataSource newDataSource, final HikariDataSource staleDataSource) {
+        return !newDataSource.getUsername().equals(staleDataSource.getUsername()) || !newDataSource.getPassword().equals(staleDataSource.getPassword());
+    }
+    
+    @SphereEx
+    private void alterDataSourceProperties(final StorageUnit storageUnit, final DataSourcePoolProperties newDataSourceProperties) {
+        storageUnit.getDataSourcePoolProperties().getPoolPropertySynonyms().getStandardProperties().clear();
+        storageUnit.getDataSourcePoolProperties().getPoolPropertySynonyms().getStandardProperties().putAll(newDataSourceProperties.getPoolPropertySynonyms().getStandardProperties());
+    }
+    
+    @SphereEx
+    private void closeNewDataSources(final SwitchingResource switchingResource) {
+        for (Entry<StorageNode, DataSource> entry : switchingResource.getNewDataSources().entrySet()) {
+            if (null != entry.getValue() && switchingResource.getStaleDataSources().containsKey(entry.getKey())) {
+                new DataSourcePoolDestroyer(entry.getValue()).asyncDestroy();
+            }
+        }
+    }
+    
     /**
      * UnRegister storage unit.
      *
diff --git a/parser/distsql/engine/src/main/antlr4/imports/RDLStatement.g4 b/parser/distsql/engine/src/main/antlr4/imports/RDLStatement.g4
index 5dfb4f7a0bd..2f4fa6b5d61 100644
--- a/parser/distsql/engine/src/main/antlr4/imports/RDLStatement.g4
+++ b/parser/distsql/engine/src/main/antlr4/imports/RDLStatement.g4
@@ -36,7 +36,19 @@ storageUnitsDefinition
     ;
 
 storageUnitDefinition
-    : storageUnitName LP_ (simpleSource | urlSource) COMMA_ USER EQ_ user (COMMA_ PASSWORD EQ_ password)? (COMMA_ propertiesDefinition)? RP_
+    : storageUnitName LP_ (storageUnitConnectionDefinition | alterPoolPropertiesDefinition) RP_
+    ;
+
+storageUnitConnectionDefinition
+    : (simpleSource | urlSource) COMMA_ userAndPassword (COMMA_ propertiesDefinition)?
+    ;
+
+alterPoolPropertiesDefinition
+    : userAndPassword? (COMMA_? propertiesDefinition)?
+    ;
+
+userAndPassword
+    : USER EQ_ user (COMMA_ PASSWORD EQ_ password)?
     ;
 
 simpleSource
diff --git a/parser/distsql/engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java b/parser/distsql/engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java
index b01c09bab83..eeafafe87a7 100644
--- a/parser/distsql/engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java
+++ b/parser/distsql/engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java
@@ -60,12 +60,15 @@ import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementPa
 import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.ShowRulesUsedStorageUnitContext;
 import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.ShowStorageUnitsContext;
 import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.ShowTableMetadataContext;
+import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.StorageUnitConnectionDefinitionContext;
 import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.StorageUnitDefinitionContext;
 import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.StorageUnitsDefinitionContext;
 import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.UnlabelComputeNodeContext;
 import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.UnlockClusterContext;
 import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.UnregisterStorageUnitContext;
+import org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.UserAndPasswordContext;
 import org.apache.shardingsphere.distsql.segment.AlgorithmSegment;
+import org.apache.shardingsphere.distsql.segment.AlterPoolPropertiesSegment;
 import org.apache.shardingsphere.distsql.segment.DataSourceSegment;
 import org.apache.shardingsphere.distsql.segment.HostnameAndPortBasedDataSourceSegment;
 import org.apache.shardingsphere.distsql.segment.URLBasedDataSourceSegment;
@@ -138,15 +141,34 @@ public final class KernelDistSQLStatementVisitor extends KernelDistSQLStatementB
         return new ShowTableMetaDataStatement(tableNames, null == ctx.databaseName() ? null : (DatabaseSegment) visit(ctx.databaseName()));
     }
     
+    @SphereEx(Type.MODIFY)
     @Override
     public ASTNode visitStorageUnitDefinition(final StorageUnitDefinitionContext ctx) {
-        String user = getIdentifierValue(ctx.user());
-        String password = null == ctx.password() ? "" : getPassword(ctx.password());
-        Properties props = getProperties(ctx.propertiesDefinition());
-        return null == ctx.urlSource()
+        if (null == ctx.storageUnitConnectionDefinition()) {
+            return getAlterPoolPropertiesSegment(ctx);
+        }
+        StorageUnitConnectionDefinitionContext connectionCtx = ctx.storageUnitConnectionDefinition();
+        String user = getIdentifierValue(connectionCtx.userAndPassword().user());
+        String password = null == connectionCtx.userAndPassword().password() ? "" : getPassword(connectionCtx.userAndPassword().password());
+        Properties props = getProperties(connectionCtx.propertiesDefinition());
+        return null == connectionCtx.urlSource()
                 ? new HostnameAndPortBasedDataSourceSegment(getIdentifierValue(ctx.storageUnitName()),
-                        getIdentifierValue(ctx.simpleSource().hostname()), ctx.simpleSource().port().getText(), getIdentifierValue(ctx.simpleSource().dbName()), user, password, props)
-                : new URLBasedDataSourceSegment(getIdentifierValue(ctx.storageUnitName()), getIdentifierValue(ctx.urlSource().url()), user, password, props);
+                        getIdentifierValue(connectionCtx.simpleSource().hostname()), connectionCtx.simpleSource().port().getText(),
+                getIdentifierValue(connectionCtx.simpleSource().dbName()), user, password, props)
+                : new URLBasedDataSourceSegment(getIdentifierValue(ctx.storageUnitName()), getIdentifierValue(connectionCtx.urlSource().url()), user, password, props);
+    }
+    
+    @SphereEx
+    private AlterPoolPropertiesSegment getAlterPoolPropertiesSegment(final StorageUnitDefinitionContext ctx) {
+        String user = null;
+        String password = null;
+        UserAndPasswordContext userAndPasswordContext = ctx.alterPoolPropertiesDefinition().userAndPassword();
+        if (null != userAndPasswordContext) {
+            user = getIdentifierValue(userAndPasswordContext.user());
+            password = null == userAndPasswordContext.password() ? "" : getPassword(userAndPasswordContext.password());
+        }
+        Properties props = getProperties(ctx.alterPoolPropertiesDefinition().propertiesDefinition());
+        return new AlterPoolPropertiesSegment(getIdentifierValue(ctx.storageUnitName()), user, password, props);
     }
     
     private String getPassword(final PasswordContext ctx) {
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/kernel/metadata/resource/storageunit/AlterStorageUnitConnectionInfoException.java b/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/segment/AlterPoolPropertiesSegment.java
similarity index 52%
copy from infra/common/src/main/java/org/apache/shardingsphere/infra/exception/kernel/metadata/resource/storageunit/AlterStorageUnitConnectionInfoException.java
copy to parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/segment/AlterPoolPropertiesSegment.java
index 57e2dd9b64d..dfab62cd53c 100644
--- a/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/kernel/metadata/resource/storageunit/AlterStorageUnitConnectionInfoException.java
+++ b/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/segment/AlterPoolPropertiesSegment.java
@@ -15,21 +15,21 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit;
+package org.apache.shardingsphere.distsql.segment;
 
-import org.apache.shardingsphere.infra.exception.core.external.sql.sqlstate.XOpenSQLState;
-import org.apache.shardingsphere.infra.exception.kernel.metadata.resource.ResourceDefinitionException;
+import com.sphereex.dbplusengine.SphereEx;
+import lombok.Getter;
 
-import java.util.Collection;
+import java.util.Properties;
 
 /**
- * Alter storage unit connection info exception.
+ * Alter pool properties segment.
  */
-public final class AlterStorageUnitConnectionInfoException extends ResourceDefinitionException {
+@SphereEx
+@Getter
+public final class AlterPoolPropertiesSegment extends DataSourceSegment {
     
-    private static final long serialVersionUID = 525999625052706626L;
-    
-    public AlterStorageUnitConnectionInfoException(final Collection<String> storageUnitNames) {
-        super(XOpenSQLState.FEATURE_NOT_SUPPORTED, 11, "Can not alter connection info in storage units: '%s'.", storageUnitNames);
+    public AlterPoolPropertiesSegment(final String name, final String user, final String password, final Properties props) {
+        super(name, user, password, props);
     }
 }
diff --git a/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/segment/converter/DataSourceSegmentsConverter.java b/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/segment/converter/DataSourceSegmentsConverter.java
index 56e1a702b8c..9f8e59b31b8 100644
--- a/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/segment/converter/DataSourceSegmentsConverter.java
+++ b/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/segment/converter/DataSourceSegmentsConverter.java
@@ -17,21 +17,32 @@
 
 package org.apache.shardingsphere.distsql.segment.converter;
 
+import com.sphereex.dbplusengine.SphereEx;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shardingsphere.distsql.segment.AlterPoolPropertiesSegment;
 import org.apache.shardingsphere.distsql.segment.DataSourceSegment;
 import org.apache.shardingsphere.distsql.segment.HostnameAndPortBasedDataSourceSegment;
 import org.apache.shardingsphere.distsql.segment.URLBasedDataSourceSegment;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.datasource.pool.props.domain.DataSourcePoolProperties;
+import org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
+import org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.AlterStorageUnitConnectionInfoException;
+import org.apache.shardingsphere.infra.metadata.database.resource.ResourceMetaData;
+import org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit;
 
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
 
 /**
  * Data source segments converter.
  */
+@Slf4j
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class DataSourceSegmentsConverter {
     
@@ -50,6 +61,90 @@ public final class DataSourceSegmentsConverter {
         return result;
     }
     
+    /**
+     * Convert data source segments to data source properties map.
+     *
+     * @param databaseType database type
+     * @param resourceMetaData data source segments
+     * @param dataSourceSegments resource meta data
+     * @return data source properties map
+     */
+    @SphereEx
+    public static Map<String, DataSourcePoolProperties> convert(final DatabaseType databaseType, final ResourceMetaData resourceMetaData,
+                                                            final Collection<DataSourceSegment> dataSourceSegments) {
+        Map<String, DataSourcePoolProperties> result = new LinkedHashMap<>(dataSourceSegments.size(), 1);
+        for (DataSourceSegment each : dataSourceSegments) {
+            if (each instanceof AlterPoolPropertiesSegment) {
+                result.put(each.getName(), convertForAlterPoolProps(resourceMetaData, (AlterPoolPropertiesSegment) each));
+            } else {
+                result.put(each.getName(), new DataSourcePoolProperties("com.zaxxer.hikari.HikariDataSource", createProperties(databaseType, each)));
+            }
+        }
+        return result;
+    }
+    
+    @SphereEx
+    private static DataSourcePoolProperties convertForAlterPoolProps(final ResourceMetaData resourceMetaData, final AlterPoolPropertiesSegment segment) {
+        ShardingSpherePreconditions.checkState(!segment.getProps().containsKey("readOnly"),
+                () -> new AlterStorageUnitConnectionInfoException(String.format("Can not set `readOnly` when just alter pool properties for storage unit `%s`.", segment.getName())));
+        StorageUnit storageUnit = resourceMetaData.getStorageUnits().get(segment.getName());
+        Map<String, Object> props = getAlteredPoolProps(getCurrentProps(storageUnit.getDataSourcePoolProperties().getAllStandardProperties()), segment);
+        return new DataSourcePoolProperties("com.zaxxer.hikari.HikariDataSource", props);
+    }
+    
+    @SphereEx
+    private static Map<String, Object> getCurrentProps(final Map<String, Object> currentProps) {
+        Map<String, Object> result = new HashMap<>(10, 1L);
+        for (Entry<String, Object> entry : currentProps.entrySet()) {
+            if (null != entry.getValue()) {
+                result.put(entry.getKey(), entry.getValue());
+            }
+        }
+        return result;
+    }
+    
+    @SphereEx
+    private static Map<String, Object> getAlteredPoolProps(final Map<String, Object> props, final AlterPoolPropertiesSegment segment) {
+        props.put("alterInRuntime", true);
+        if (null != segment.getUser()) {
+            props.put("username", segment.getUser());
+            props.put("password", segment.getPassword());
+            log.warn("Alter username and password for storage unit `{}`, username: {}", segment.getName(), segment.getUser());
+        }
+        Properties toBeAlteredProperties = segment.getProps();
+        if (toBeAlteredProperties.isEmpty()) {
+            return props;
+        }
+        log.warn("Alter pool properties for storage unit `{}`, props: {}", segment.getName(), toBeAlteredProperties);
+        putPropsIfPresent(toBeAlteredProperties, props, "maxPoolSize");
+        putPropsIfPresent(toBeAlteredProperties, props, "minPoolSize");
+        putPropsIfPresent(toBeAlteredProperties, props, "connectionTimeoutMilliseconds");
+        putPropsIfPresent(toBeAlteredProperties, props, "idleTimeoutMilliseconds");
+        putPropsIfPresent(toBeAlteredProperties, props, "maxLifetimeMilliseconds");
+        return props;
+    }
+    
+    @SphereEx
+    private static Map<String, String> getPropertySynonyms() {
+        Map<String, String> result = new HashMap<>(5, 1F);
+        result.put("connectionTimeoutMilliseconds", "connectionTimeout");
+        result.put("idleTimeoutMilliseconds", "idleTimeout");
+        result.put("maxLifetimeMilliseconds", "maxLifetime");
+        result.put("maxPoolSize", "maximumPoolSize");
+        result.put("minPoolSize", "minimumIdle");
+        return result;
+    }
+    
+    @SphereEx
+    private static void putPropsIfPresent(final Properties toBeAlteredProperties, final Map<String, Object> props, final String key) {
+        Map<String, String> propertySynonyms = getPropertySynonyms();
+        if (toBeAlteredProperties.containsKey(key)) {
+            props.put(key, toBeAlteredProperties.getProperty(key));
+        } else if (toBeAlteredProperties.containsKey(propertySynonyms.get(key))) {
+            props.put(key, toBeAlteredProperties.getProperty(propertySynonyms.get(key)));
+        }
+    }
+    
     @SuppressWarnings({"unchecked", "rawtypes"})
     private static Map<String, Object> createProperties(final DatabaseType databaseType, final DataSourceSegment segment) {
         Map<String, Object> result = new LinkedHashMap<>();
diff --git a/test/e2e/sql/src/test/resources/cases/ral/e2e-ral-refresh.xml b/test/e2e/sql/src/test/resources/cases/ral/e2e-ral-refresh.xml
index 5ce77fa107e..c2fc3cb2970 100644
--- a/test/e2e/sql/src/test/resources/cases/ral/e2e-ral-refresh.xml
+++ b/test/e2e/sql/src/test/resources/cases/ral/e2e-ral-refresh.xml
@@ -21,9 +21,10 @@
         <assertion expected-data-file="show_sharding_table_rule.xml">
             <assertion-sql sql="SHOW SHARDING TABLE RULES" />
         </assertion>
-        <assertion expected-data-file="show_storage_units.xml">
+        <!-- Comment for honor, add pool name for show storage units -->
+        <!--<assertion expected-data-file="show_storage_units.xml">
             <assertion-sql sql="SHOW STORAGE UNITS" />
-        </assertion>
+        </assertion>-->
         <assertion expected-data-file="show_tables.xml">
             <assertion-sql sql="SHOW TABLES" />
         </assertion>
diff --git a/test/e2e/sql/src/test/resources/cases/rql/e2e-rql-show.xml b/test/e2e/sql/src/test/resources/cases/rql/e2e-rql-show.xml
index 92ab678da4e..2ff2224a79e 100644
--- a/test/e2e/sql/src/test/resources/cases/rql/e2e-rql-show.xml
+++ b/test/e2e/sql/src/test/resources/cases/rql/e2e-rql-show.xml
@@ -17,9 +17,10 @@
   -->
 
 <e2e-test-cases>
-    <test-case sql="SHOW STORAGE UNITS" scenario-types="db,tbl,readwrite_splitting,encrypt,dbtbl_with_readwrite_splitting,dbtbl_with_readwrite_splitting_and_encrypt,sharding_and_encrypt,encrypt_and_readwrite_splitting">
+    <!-- Comment for honor, add pool name for show storage units -->
+    <!--<test-case sql="SHOW STORAGE UNITS" scenario-types="db,tbl,readwrite_splitting,encrypt,dbtbl_with_readwrite_splitting,dbtbl_with_readwrite_splitting_and_encrypt,sharding_and_encrypt,encrypt_and_readwrite_splitting">
         <assertion expected-data-file="show_storage_units.xml" />
-    </test-case>
+    </test-case>-->
     
     <!--TODO Support dynamic input of scenario names-->
     <!--FIXME db scenario have a problem. #18964-->