You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2018/11/22 07:09:59 UTC

[incubator-skywalking] 01/01: Support create table in mysql. Add column name override mechanism.

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

wusheng pushed a commit to branch mysql-style
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git

commit 76eb00a288e49d191e3bfdaa3c7e2783cb55e6eb
Author: Wu Sheng <wu...@foxmail.com>
AuthorDate: Thu Nov 22 15:09:44 2018 +0800

    Support create table in mysql. Add column name override mechanism.
---
 .../skywalking/oap/server/core/CoreModule.java     |   2 +
 .../oap/server/core/CoreModuleProvider.java        |   2 +
 .../annotation/StorageAnnotationListener.java      |  16 ++-
 .../oap/server/core/storage/model/ColumnName.java  |  12 +-
 .../model/{ColumnName.java => IModelOverride.java} |  25 +---
 .../server/core/storage/model/ModelInstaller.java  |  17 ++-
 .../client/jdbc/hikaricp/JDBCHikariCPClient.java   |  32 +++--
 .../main/assembly/datasource-settings.properties}  |  14 +-
 .../src/main/resources/application.yml             |  19 +--
 .../main/resources/datasource-settings.properties} |  14 +-
 .../storage-jdbc-hikaricp-plugin/pom.xml           |   5 +
 .../plugin/jdbc/h2/dao/H2AggregationQueryDAO.java  |   8 +-
 .../plugin/jdbc/h2/dao/H2MetadataQueryDAO.java     |  48 ++-----
 .../plugin/jdbc/h2/dao/H2MetricQueryDAO.java       |  18 +--
 .../storage/plugin/jdbc/h2/dao/H2RegisterDAO.java  |   6 +-
 .../storage/plugin/jdbc/h2/dao/H2SQLExecutor.java  |  18 +--
 .../jdbc/h2/dao/H2ServiceInventoryCacheDAO.java    |   6 +-
 .../plugin/jdbc/h2/dao/H2TableInstaller.java       |  12 +-
 .../plugin/jdbc/h2/dao/H2TopologyQueryDAO.java     |  12 +-
 .../plugin/jdbc/h2/dao/H2TraceQueryDAO.java        |  12 +-
 .../plugin/jdbc/mysql/MySQLStorageProvider.java    | 149 +++++++++++++++++++++
 .../plugin/jdbc/mysql/MySQLTableInstaller.java     |  58 ++++++++
 ...alking.oap.server.library.module.ModuleProvider |   3 +-
 .../mysql/PreventRedistributionMySQLDriver.java}   |  37 ++---
 24 files changed, 362 insertions(+), 183 deletions(-)

diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModule.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModule.java
index dade6d0..1baa250 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModule.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModule.java
@@ -29,6 +29,7 @@ import org.apache.skywalking.oap.server.core.remote.client.RemoteClientManager;
 import org.apache.skywalking.oap.server.core.server.*;
 import org.apache.skywalking.oap.server.core.source.SourceReceiver;
 import org.apache.skywalking.oap.server.core.storage.model.IModelGetter;
+import org.apache.skywalking.oap.server.core.storage.model.IModelOverride;
 import org.apache.skywalking.oap.server.library.module.*;
 
 /**
@@ -73,6 +74,7 @@ public class CoreModule extends ModuleDefine {
 
     private void addInsideService(List<Class> classes) {
         classes.add(IModelGetter.class);
+        classes.add(IModelOverride.class);
         classes.add(StreamDataClassGetter.class);
         classes.add(RemoteClientManager.class);
         classes.add(RemoteSenderService.class);
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java
index b1181da..0a2a04d 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/CoreModuleProvider.java
@@ -63,6 +63,7 @@ import org.apache.skywalking.oap.server.core.source.SourceReceiverImpl;
 import org.apache.skywalking.oap.server.core.storage.PersistenceTimer;
 import org.apache.skywalking.oap.server.core.storage.annotation.StorageAnnotationListener;
 import org.apache.skywalking.oap.server.core.storage.model.IModelGetter;
+import org.apache.skywalking.oap.server.core.storage.model.IModelOverride;
 import org.apache.skywalking.oap.server.core.storage.ttl.DataTTLKeeperTimer;
 import org.apache.skywalking.oap.server.library.module.*;
 import org.apache.skywalking.oap.server.library.module.ModuleDefine;
@@ -135,6 +136,7 @@ public class CoreModuleProvider extends ModuleProvider {
 
         this.registerServiceImplementation(RemoteSenderService.class, new RemoteSenderService(getManager()));
         this.registerServiceImplementation(IModelGetter.class, storageAnnotationListener);
+        this.registerServiceImplementation(IModelOverride.class, storageAnnotationListener);
 
         this.registerServiceImplementation(ServiceInventoryCache.class, new ServiceInventoryCache(getManager()));
         this.registerServiceImplementation(IServiceInventoryRegister.class, new ServiceInventoryRegister(getManager()));
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/StorageAnnotationListener.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/StorageAnnotationListener.java
index e9e09e9..7d9da52 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/StorageAnnotationListener.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/annotation/StorageAnnotationListener.java
@@ -29,6 +29,7 @@ import org.apache.skywalking.oap.server.core.annotation.AnnotationListener;
 import org.apache.skywalking.oap.server.core.source.Scope;
 import org.apache.skywalking.oap.server.core.storage.model.ColumnName;
 import org.apache.skywalking.oap.server.core.storage.model.IModelGetter;
+import org.apache.skywalking.oap.server.core.storage.model.IModelOverride;
 import org.apache.skywalking.oap.server.core.storage.model.Model;
 import org.apache.skywalking.oap.server.core.storage.model.ModelColumn;
 import org.slf4j.Logger;
@@ -37,7 +38,7 @@ import org.slf4j.LoggerFactory;
 /**
  * @author peng-yongsheng
  */
-public class StorageAnnotationListener implements AnnotationListener, IModelGetter {
+public class StorageAnnotationListener implements AnnotationListener, IModelGetter, IModelOverride {
 
     private static final Logger logger = LoggerFactory.getLogger(StorageAnnotationListener.class);
 
@@ -84,4 +85,17 @@ public class StorageAnnotationListener implements AnnotationListener, IModelGett
             retrieval(clazz.getSuperclass(), modelName, modelColumns);
         }
     }
+
+    @Override public void overrideColumnName(String columnName, String newName) {
+        models.forEach(model -> {
+            model.getColumns().forEach(column -> {
+                ColumnName existColumnName = column.getColumnName();
+                String name = existColumnName.getName();
+                if (name.equals(columnName)) {
+                    existColumnName.setName(newName);
+                    logger.debug("Model {} column {} has been override. The new column name is {}.", model.getName(), name, newName);
+                }
+            });
+        });
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ColumnName.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ColumnName.java
index be7e775..d504867 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ColumnName.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ColumnName.java
@@ -22,8 +22,8 @@ package org.apache.skywalking.oap.server.core.storage.model;
  * @author peng-yongsheng
  */
 public class ColumnName {
-    private final String fullName;
-    private final String shortName;
+    private String fullName;
+    private String shortName;
     private boolean useShortName = false;
 
     public ColumnName(String fullName, String shortName) {
@@ -38,4 +38,12 @@ public class ColumnName {
     public void useShortName() {
         this.useShortName = true;
     }
+
+    public void setName(String name) {
+        if (useShortName) {
+            shortName = name;
+        } else {
+            fullName = name;
+        }
+    }
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ColumnName.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/IModelOverride.java
similarity index 65%
copy from oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ColumnName.java
copy to oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/IModelOverride.java
index be7e775..3344fb8 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ColumnName.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/IModelOverride.java
@@ -18,24 +18,13 @@
 
 package org.apache.skywalking.oap.server.core.storage.model;
 
+import org.apache.skywalking.oap.server.library.module.Service;
+
 /**
- * @author peng-yongsheng
+ * Override service provides ways to rename the existing column or table name.
+ *
+ * @author wusheng
  */
-public class ColumnName {
-    private final String fullName;
-    private final String shortName;
-    private boolean useShortName = false;
-
-    public ColumnName(String fullName, String shortName) {
-        this.fullName = fullName;
-        this.shortName = shortName;
-    }
-
-    public String getName() {
-        return useShortName ? shortName : fullName;
-    }
-
-    public void useShortName() {
-        this.useShortName = true;
-    }
+public interface IModelOverride extends Service {
+    void overrideColumnName(String columnName, String newName);
 }
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ModelInstaller.java b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ModelInstaller.java
index 1c3b463..4eef358 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ModelInstaller.java
+++ b/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ModelInstaller.java
@@ -18,13 +18,17 @@
 
 package org.apache.skywalking.oap.server.core.storage.model;
 
-import java.util.*;
-import org.apache.skywalking.oap.server.core.*;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.skywalking.oap.server.core.Const;
+import org.apache.skywalking.oap.server.core.CoreModule;
 import org.apache.skywalking.oap.server.core.config.DownsamplingConfigService;
-import org.apache.skywalking.oap.server.core.storage.*;
+import org.apache.skywalking.oap.server.core.storage.Downsampling;
+import org.apache.skywalking.oap.server.core.storage.StorageException;
 import org.apache.skywalking.oap.server.library.client.Client;
 import org.apache.skywalking.oap.server.library.module.ModuleManager;
-import org.slf4j.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * @author peng-yongsheng
@@ -75,6 +79,11 @@ public abstract class ModelInstaller {
         }
     }
 
+    public final void overrideColumnName(String columnName, String newName) {
+        IModelOverride modelOverride = moduleManager.find(CoreModule.NAME).provider().getService(IModelOverride.class);
+        modelOverride.overrideColumnName(columnName, newName);
+    }
+
     protected abstract boolean isExists(Client client, Model model) throws StorageException;
 
     protected abstract void columnCheck(Client client, Model model) throws StorageException;
diff --git a/oap-server/server-library/library-client/src/main/java/org/apache/skywalking/oap/server/library/client/jdbc/hikaricp/JDBCHikariCPClient.java b/oap-server/server-library/library-client/src/main/java/org/apache/skywalking/oap/server/library/client/jdbc/hikaricp/JDBCHikariCPClient.java
index b09bbbf..38aecde 100644
--- a/oap-server/server-library/library-client/src/main/java/org/apache/skywalking/oap/server/library/client/jdbc/hikaricp/JDBCHikariCPClient.java
+++ b/oap-server/server-library/library-client/src/main/java/org/apache/skywalking/oap/server/library/client/jdbc/hikaricp/JDBCHikariCPClient.java
@@ -54,36 +54,34 @@ public class JDBCHikariCPClient implements Client {
     @Override public void shutdown() {
     }
 
+    /**
+     * Default getConnection is not set in auto-commit.
+     *
+     * @return
+     * @throws JDBCClientException
+     */
     public Connection getConnection() throws JDBCClientException {
+        return getConnection(true);
+    }
+
+    public Connection getTransactionConnection() throws JDBCClientException {
+        return getConnection(false);
+    }
+
+    public Connection getConnection(boolean autoCommit) throws JDBCClientException {
         try {
             Connection connection = dataSource.getConnection();
-            connection.setAutoCommit(true);
+            connection.setAutoCommit(autoCommit);
             return connection;
         } catch (SQLException e) {
             throw new JDBCClientException(e.getMessage(), e);
         }
     }
 
-    public void close(Connection connection) {
-        if (connection != null) {
-            try {
-                connection.commit();
-                connection.close();
-            } catch (SQLException e) {
-            }
-        }
-    }
-
     public void execute(Connection connection, String sql) throws JDBCClientException {
-        try {
-            connection.setReadOnly(true);
-        } catch (SQLException e) {
-
-        }
         logger.debug("execute aql: {}", sql);
         try (Statement statement = connection.createStatement()) {
             statement.execute(sql);
-            statement.closeOnCompletion();
         } catch (SQLException e) {
             throw new JDBCClientException(e.getMessage(), e);
         }
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider b/oap-server/server-starter/src/main/assembly/datasource-settings.properties
similarity index 64%
copy from oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider
copy to oap-server/server-starter/src/main/assembly/datasource-settings.properties
index 86c2c56..169c04e 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider
+++ b/oap-server/server-starter/src/main/assembly/datasource-settings.properties
@@ -16,4 +16,16 @@
 #
 #
 
-org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.H2StorageProvider
\ No newline at end of file
+jdbcUrl=jdbc:mysql://localhost:3306
+user=root
+password=root@1234
+dataSource.cachePrepStmts=true
+dataSource.prepStmtCacheSize=250
+dataSource.prepStmtCacheSqlLimit=2048
+dataSource.useServerPrepStmts=true
+dataSource.useLocalSessionState=true
+dataSource.rewriteBatchedStatements=true
+dataSource.cacheResultSetMetadata=true
+dataSource.cacheServerConfiguration=true
+dataSource.elideSetAutoCommits=true
+dataSource.maintainTimeStats=false
\ No newline at end of file
diff --git a/oap-server/server-starter/src/main/resources/application.yml b/oap-server/server-starter/src/main/resources/application.yml
index 16219bb..7365fe2 100644
--- a/oap-server/server-starter/src/main/resources/application.yml
+++ b/oap-server/server-starter/src/main/resources/application.yml
@@ -46,19 +46,20 @@ core:
     dayMetricsDataTTL: 45 # Unit is day
     monthMetricsDataTTL: 18 # Unit is month
 storage:
-  elasticsearch:
-    clusterNodes: localhost:9200
-    indexShardsNumber: 2
-    indexReplicasNumber: 0
-    # Batch process setting, refer to https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.5/java-docs-bulk-processor.html
-    bulkActions: 2000 # Execute the bulk every 2000 requests
-    bulkSize: 20 # flush the bulk every 20mb
-    flushInterval: 10 # flush the bulk every 10 seconds whatever the number of requests
-    concurrentRequests: 2 # the number of concurrent requests
+#  elasticsearch:
+#    clusterNodes: localhost:9200
+#    indexShardsNumber: 2
+#    indexReplicasNumber: 0
+#    # Batch process setting, refer to https://www.elastic.co/guide/en/elasticsearch/client/java-api/5.5/java-docs-bulk-processor.html
+#    bulkActions: 2000 # Execute the bulk every 2000 requests
+#    bulkSize: 20 # flush the bulk every 20mb
+#    flushInterval: 10 # flush the bulk every 10 seconds whatever the number of requests
+#    concurrentRequests: 2 # the number of concurrent requests
 #  h2:
 #    driver: org.h2.jdbcx.JdbcDataSource
 #    url: jdbc:h2:mem:skywalking-oap-db
 #    user: sa
+  mysql:
 receiver-register:
   default:
 receiver-trace:
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider b/oap-server/server-starter/src/main/resources/datasource-settings.properties
similarity index 63%
copy from oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider
copy to oap-server/server-starter/src/main/resources/datasource-settings.properties
index 86c2c56..70b0099 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider
+++ b/oap-server/server-starter/src/main/resources/datasource-settings.properties
@@ -16,4 +16,16 @@
 #
 #
 
-org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.H2StorageProvider
\ No newline at end of file
+jdbcUrl=jdbc:mysql://localhost:3306/swtest
+dataSource.user=root
+dataSource.password=root@1234
+dataSource.cachePrepStmts=true
+dataSource.prepStmtCacheSize=250
+dataSource.prepStmtCacheSqlLimit=2048
+dataSource.useServerPrepStmts=true
+dataSource.useLocalSessionState=true
+dataSource.rewriteBatchedStatements=true
+dataSource.cacheResultSetMetadata=true
+dataSource.cacheServerConfiguration=true
+dataSource.elideSetAutoCommits=true
+dataSource.maintainTimeStats=false
\ No newline at end of file
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/pom.xml b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/pom.xml
index 6a7e571..65f7eb0 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/pom.xml
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/pom.xml
@@ -43,6 +43,11 @@
             <groupId>com.h2database</groupId>
             <artifactId>h2</artifactId>
         </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <version>8.0.13</version>
+        </dependency>
     </dependencies>
 
 </project>
\ No newline at end of file
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2AggregationQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2AggregationQueryDAO.java
index 7137643..6fbdee8 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2AggregationQueryDAO.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2AggregationQueryDAO.java
@@ -92,10 +92,8 @@ public class H2AggregationQueryDAO implements IAggregationQueryDAO {
         sql.append(" group by ").append(Indicator.ENTITY_ID);
         sql.append(") order by value ").append(order.equals(Order.ASC) ? "asc" : "desc").append(" limit ").append(topN);
 
-        Connection connection = null;
         List<TopNEntity> topNEntities = new ArrayList<>();
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             ResultSet resultSet = h2Client.executeQuery(connection, sql.toString(), conditions.toArray(new Object[0]));
 
             try {
@@ -108,8 +106,8 @@ public class H2AggregationQueryDAO implements IAggregationQueryDAO {
             } catch (SQLException e) {
                 throw new IOException(e);
             }
-        } finally {
-            h2Client.close(connection);
+        } catch (SQLException e) {
+            throw new IOException(e);
         }
         return topNEntities;
     }
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetadataQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetadataQueryDAO.java
index 4f82a82..769738d 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetadataQueryDAO.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetadataQueryDAO.java
@@ -57,17 +57,13 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
         setTimeRangeCondition(sql, condition, startTimestamp, endTimestamp);
         sql.append(" and ").append(ServiceInventory.IS_ADDRESS).append("=0");
 
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             ResultSet resultSet = h2Client.executeQuery(connection, sql.toString(), condition.toArray(new Object[0]));
             while (resultSet.next()) {
                 return resultSet.getInt("num");
             }
         } catch (SQLException e) {
             throw new IOException(e);
-        } finally {
-            h2Client.close(connection);
         }
         return 0;
     }
@@ -79,9 +75,7 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
         setTimeRangeCondition(sql, condition, startTimestamp, endTimestamp);
         sql.append(" and ").append(EndpointInventory.DETECT_POINT).append("=").append(DetectPoint.SERVER.ordinal());
 
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             ResultSet resultSet = h2Client.executeQuery(connection, sql.toString(), condition.toArray(new Object[0]));
 
             while (resultSet.next()) {
@@ -89,8 +83,6 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
             }
         } catch (SQLException e) {
             throw new IOException(e);
-        } finally {
-            h2Client.close(connection);
         }
         return 0;
     }
@@ -104,17 +96,13 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
         sql.append(" and ").append(NetworkAddressInventory.SRC_LAYER).append("=?");
         condition.add(srcLayer);
 
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             ResultSet resultSet = h2Client.executeQuery(connection, sql.toString(), condition.toArray(new Object[0]));
             while (resultSet.next()) {
                 return resultSet.getInt("num");
             }
         } catch (SQLException e) {
             throw new IOException(e);
-        } finally {
-            h2Client.close(connection);
         }
         return 0;
     }
@@ -128,15 +116,11 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
         sql.append(" and ").append(ServiceInventory.IS_ADDRESS).append("=? limit 100");
         condition.add(BooleanUtils.FALSE);
 
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             ResultSet resultSet = h2Client.executeQuery(connection, sql.toString(), condition.toArray(new Object[0]));
             return buildServices(resultSet);
         } catch (SQLException e) {
             throw new IOException(e);
-        } finally {
-            h2Client.close(connection);
         }
     }
 
@@ -153,15 +137,11 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
         }
         sql.append(" limit 100");
 
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             ResultSet resultSet = h2Client.executeQuery(connection, sql.toString(), condition.toArray(new Object[0]));
             return buildServices(resultSet);
         } catch (SQLException e) {
             throw new IOException(e);
-        } finally {
-            h2Client.close(connection);
         }
     }
 
@@ -174,9 +154,7 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
         sql.append(" and ").append(ServiceInventory.NAME).append(" = ?");
         condition.add(serviceCode);
 
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             ResultSet resultSet = h2Client.executeQuery(connection, sql.toString(), condition.toArray(new Object[0]));
 
             while (resultSet.next()) {
@@ -187,8 +165,6 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
             }
         } catch (SQLException e) {
             throw new IOException(e);
-        } finally {
-            h2Client.close(connection);
         }
 
         return null;
@@ -209,9 +185,7 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
         sql.append(" limit ").append(limit);
 
         List<Endpoint> endpoints = new ArrayList<>();
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             ResultSet resultSet = h2Client.executeQuery(connection, sql.toString(), condition.toArray(new Object[0]));
 
             while (resultSet.next()) {
@@ -222,8 +196,6 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
             }
         } catch (SQLException e) {
             throw new IOException(e);
-        } finally {
-            h2Client.close(connection);
         }
         return endpoints;
     }
@@ -237,10 +209,8 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
         sql.append(" and ").append(ServiceInstanceInventory.SERVICE_ID).append("=?");
         condition.add(serviceId);
 
-        Connection connection = null;
         List<ServiceInstance> serviceInstances = new ArrayList<>();
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             ResultSet resultSet = h2Client.executeQuery(connection, sql.toString(), condition.toArray(new Object[0]));
 
             while (resultSet.next()) {
@@ -269,8 +239,6 @@ public class H2MetadataQueryDAO implements IMetadataQueryDAO {
             }
         } catch (SQLException e) {
             throw new IOException(e);
-        } finally {
-            h2Client.close(connection);
         }
         return serviceInstances;
     }
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetricQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetricQueryDAO.java
index a8093a6..a61c6db 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetricQueryDAO.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2MetricQueryDAO.java
@@ -91,9 +91,7 @@ public class H2MetricQueryDAO extends H2SQLExecutor implements IMetricQueryDAO {
         }
 
         IntValues intValues = new IntValues();
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             try (ResultSet resultSet = h2Client.executeQuery(connection, "select " + Indicator.ENTITY_ID + " id, " + op + "(" + valueCName + ") value from " + tableName
                     + " where " + whereSql
                     + Indicator.TIME_BUCKET + ">= ? and " + Indicator.TIME_BUCKET + "<=?"
@@ -109,8 +107,6 @@ public class H2MetricQueryDAO extends H2SQLExecutor implements IMetricQueryDAO {
             }
         } catch (SQLException e) {
             throw new IOException(e);
-        } finally {
-            h2Client.close(connection);
         }
         return orderWithDefault0(intValues, ids);
     }
@@ -129,9 +125,7 @@ public class H2MetricQueryDAO extends H2SQLExecutor implements IMetricQueryDAO {
 
         IntValues intValues = new IntValues();
 
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             try (ResultSet resultSet = h2Client.executeQuery(connection, "select id, " + valueCName + " from " + tableName + " where id in (" + idValues.toString() + ")")) {
                 while (resultSet.next()) {
                     KVInt kv = new KVInt();
@@ -142,8 +136,6 @@ public class H2MetricQueryDAO extends H2SQLExecutor implements IMetricQueryDAO {
             }
         } catch (SQLException e) {
             throw new IOException(e);
-        } finally {
-            h2Client.close(connection);
         }
         return orderWithDefault0(intValues, ids);
     }
@@ -183,9 +175,7 @@ public class H2MetricQueryDAO extends H2SQLExecutor implements IMetricQueryDAO {
         List<List<Long>> thermodynamicValueCollection = new ArrayList<>();
         Map<String, List<Long>> thermodynamicValueMatrix = new HashMap<>();
 
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             Thermodynamic thermodynamic = new Thermodynamic();
             int numOfSteps = 0;
             int axisYStep = 0;
@@ -232,8 +222,6 @@ public class H2MetricQueryDAO extends H2SQLExecutor implements IMetricQueryDAO {
             return thermodynamic;
         } catch (SQLException e) {
             throw new IOException(e);
-        } finally {
-            h2Client.close(connection);
         }
     }
 
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2RegisterDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2RegisterDAO.java
index 6cdf4ec..0650386 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2RegisterDAO.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2RegisterDAO.java
@@ -40,9 +40,7 @@ public class H2RegisterDAO extends H2SQLExecutor implements IRegisterDAO {
     }
 
     @Override public int max(String modelName) throws IOException {
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             try (ResultSet rs = h2Client.executeQuery(connection, "SELECT max(sequence) max_id FROM " + modelName)) {
                 while (rs.next()) {
                     int maxId = rs.getInt("max_id");
@@ -57,8 +55,6 @@ public class H2RegisterDAO extends H2SQLExecutor implements IRegisterDAO {
             throw new IOException(e.getMessage(), e);
         } catch (JDBCClientException e) {
             throw new IOException(e.getMessage(), e);
-        } finally {
-            h2Client.close(connection);
         }
         return Const.NONE;
     }
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2SQLExecutor.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2SQLExecutor.java
index 53729d6..862c7c7 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2SQLExecutor.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2SQLExecutor.java
@@ -48,9 +48,7 @@ public class H2SQLExecutor {
 
     protected StorageData getByID(JDBCHikariCPClient h2Client, String modelName, String id,
         StorageBuilder storageBuilder) throws IOException {
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             try (ResultSet rs = h2Client.executeQuery(connection, "SELECT * FROM " + modelName + " WHERE id = ?", id)) {
                 return toStorageData(rs, modelName, storageBuilder);
             }
@@ -58,16 +56,12 @@ public class H2SQLExecutor {
             throw new IOException(e.getMessage(), e);
         } catch (JDBCClientException e) {
             throw new IOException(e.getMessage(), e);
-        } finally {
-            h2Client.close(connection);
         }
     }
 
     protected StorageData getByColumn(JDBCHikariCPClient h2Client, String modelName, String columnName, Object value,
         StorageBuilder storageBuilder) throws IOException {
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             try (ResultSet rs = h2Client.executeQuery(connection, "SELECT * FROM " + modelName + " WHERE " + columnName + " = ?", value)) {
                 return toStorageData(rs, modelName, storageBuilder);
             }
@@ -75,8 +69,6 @@ public class H2SQLExecutor {
             throw new IOException(e.getMessage(), e);
         } catch (JDBCClientException e) {
             throw new IOException(e.getMessage(), e);
-        } finally {
-            h2Client.close(connection);
         }
     }
 
@@ -94,9 +86,7 @@ public class H2SQLExecutor {
     }
 
     protected int getEntityIDByID(JDBCHikariCPClient h2Client, String entityColumnName, String modelName, String id) {
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             try (ResultSet rs = h2Client.executeQuery(connection, "SELECT " + entityColumnName + " FROM " + modelName + " WHERE ID=?", id)) {
                 while (rs.next()) {
                     return rs.getInt(ServiceInstanceInventory.SEQUENCE);
@@ -106,8 +96,6 @@ public class H2SQLExecutor {
             logger.error(e.getMessage(), e);
         } catch (JDBCClientException e) {
             logger.error(e.getMessage(), e);
-        } finally {
-            h2Client.close(connection);
         }
         return Const.NONE;
     }
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2ServiceInventoryCacheDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2ServiceInventoryCacheDAO.java
index f28a1c6..2008cd5 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2ServiceInventoryCacheDAO.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2ServiceInventoryCacheDAO.java
@@ -72,9 +72,7 @@ public class H2ServiceInventoryCacheDAO extends H2SQLExecutor implements IServic
 
             sql.append(" LIMIT 50 ");
 
-            Connection connection = null;
-            try {
-                connection = h2Client.getConnection();
+            try (Connection connection = h2Client.getConnection()) {
                 try (ResultSet resultSet = h2Client.executeQuery(connection, sql.toString(), BooleanUtils.TRUE, System.currentTimeMillis() - 10000)) {
                     while (resultSet.next()) {
                         ServiceInventory serviceInventory = (ServiceInventory)toStorageData(resultSet, ServiceInventory.MODEL_NAME, new ServiceInventory.Builder());
@@ -85,8 +83,6 @@ public class H2ServiceInventoryCacheDAO extends H2SQLExecutor implements IServic
                 }
             } catch (SQLException e) {
                 throw new IOException(e);
-            } finally {
-                h2Client.close(connection);
             }
         } catch (Throwable e) {
             logger.error(e.getMessage());
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java
index e7bfbaa..453b94f 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TableInstaller.java
@@ -71,7 +71,7 @@ public class H2TableInstaller extends ModelInstaller {
         TableMetaInfo.addModel(model);
         JDBCHikariCPClient h2Client = (JDBCHikariCPClient)client;
         SQLBuilder tableCreateSQL = new SQLBuilder("CREATE TABLE IF NOT EXISTS " + model.getName() + " (");
-        tableCreateSQL.appendLine("id VARCHAR2(300), ");
+        tableCreateSQL.appendLine("id VARCHAR(300), ");
         for (int i = 0; i < model.getColumns().size(); i++) {
             ModelColumn column = model.getColumns().get(i);
             ColumnName name = column.getColumnName();
@@ -83,19 +83,17 @@ public class H2TableInstaller extends ModelInstaller {
             logger.debug("creating table: " + tableCreateSQL.toStringInNewLine());
         }
 
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             h2Client.execute(connection, tableCreateSQL.toString());
         } catch (JDBCClientException e) {
             throw new StorageException(e.getMessage(), e);
-        } finally {
-            h2Client.close(connection);
+        } catch (SQLException e) {
+            throw new StorageException(e.getMessage(), e);
         }
 
     }
 
-    private String getColumnType(Class<?> type) {
+    protected String getColumnType(Class<?> type) {
         if (Integer.class.equals(type) || int.class.equals(type)) {
             return "INT";
         } else if (Long.class.equals(type) || long.class.equals(type)) {
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TopologyQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TopologyQueryDAO.java
index f24e9b6..c51af73 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TopologyQueryDAO.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TopologyQueryDAO.java
@@ -94,9 +94,7 @@ public class H2TopologyQueryDAO implements ITopologyQueryDAO {
             serviceIdMatchSql.append(")");
         }
         List<Call> calls = new ArrayList<>();
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             ResultSet resultSet = h2Client.executeQuery(connection, "select "
                     + Indicator.ENTITY_ID
                     + " component_id from " + tableName + " where "
@@ -107,8 +105,6 @@ public class H2TopologyQueryDAO implements ITopologyQueryDAO {
             buildCalls(resultSet, calls, isClientSide);
         } catch (SQLException e) {
             throw new IOException(e);
-        } finally {
-            h2Client.close(connection);
         }
         return calls;
     }
@@ -119,10 +115,8 @@ public class H2TopologyQueryDAO implements ITopologyQueryDAO {
         conditions[0] = startTB;
         conditions[1] = endTB;
         conditions[2] = id;
-        Connection connection = null;
         List<Call> calls = new ArrayList<>();
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
             ResultSet resultSet = h2Client.executeQuery(connection, "select "
                     + Indicator.ENTITY_ID
                     + " from " + tableName + " where "
@@ -133,8 +127,6 @@ public class H2TopologyQueryDAO implements ITopologyQueryDAO {
             buildCalls(resultSet, calls, isSourceId);
         } catch (SQLException e) {
             throw new IOException(e);
-        } finally {
-            h2Client.close(connection);
         }
         return calls;
     }
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TraceQueryDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TraceQueryDAO.java
index af7d03d..fe2c764 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TraceQueryDAO.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2TraceQueryDAO.java
@@ -106,9 +106,7 @@ public class H2TraceQueryDAO implements ITraceQueryDAO {
         sql.append(" OFFSET ").append(from);
 
         TraceBrief traceBrief = new TraceBrief();
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
 
             try (ResultSet resultSet = h2Client.executeQuery(connection, "select count(1) total from (select 1 " + sql.toString() + " )", parameters.toArray(new Object[0]))) {
                 while (resultSet.next()) {
@@ -132,8 +130,6 @@ public class H2TraceQueryDAO implements ITraceQueryDAO {
             }
         } catch (SQLException e) {
             throw new IOException(e);
-        } finally {
-            h2Client.close(connection);
         }
 
         return traceBrief;
@@ -141,9 +137,7 @@ public class H2TraceQueryDAO implements ITraceQueryDAO {
 
     @Override public List<SegmentRecord> queryByTraceId(String traceId) throws IOException {
         List<SegmentRecord> segmentRecords = new ArrayList<>();
-        Connection connection = null;
-        try {
-            connection = h2Client.getConnection();
+        try (Connection connection = h2Client.getConnection()) {
 
             try (ResultSet resultSet = h2Client.executeQuery(connection, "select * from " + SegmentRecord.INDEX_NAME + " where " + SegmentRecord.TRACE_ID + " = ?", traceId)) {
                 while (resultSet.next()) {
@@ -166,8 +160,6 @@ public class H2TraceQueryDAO implements ITraceQueryDAO {
             }
         } catch (SQLException e) {
             throw new IOException(e);
-        } finally {
-            h2Client.close(connection);
         }
         return segmentRecords;
     }
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLStorageProvider.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLStorageProvider.java
new file mode 100644
index 0000000..e37cf6c
--- /dev/null
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLStorageProvider.java
@@ -0,0 +1,149 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.oap.server.storage.plugin.jdbc.mysql;
+
+import java.io.IOException;
+import java.util.Properties;
+import org.apache.skywalking.oap.server.core.storage.IBatchDAO;
+import org.apache.skywalking.oap.server.core.storage.IHistoryDeleteDAO;
+import org.apache.skywalking.oap.server.core.storage.IRegisterLockDAO;
+import org.apache.skywalking.oap.server.core.storage.StorageDAO;
+import org.apache.skywalking.oap.server.core.storage.StorageException;
+import org.apache.skywalking.oap.server.core.storage.StorageModule;
+import org.apache.skywalking.oap.server.core.storage.cache.IEndpointInventoryCacheDAO;
+import org.apache.skywalking.oap.server.core.storage.cache.INetworkAddressInventoryCacheDAO;
+import org.apache.skywalking.oap.server.core.storage.cache.IServiceInstanceInventoryCacheDAO;
+import org.apache.skywalking.oap.server.core.storage.cache.IServiceInventoryCacheDAO;
+import org.apache.skywalking.oap.server.core.storage.query.IAggregationQueryDAO;
+import org.apache.skywalking.oap.server.core.storage.query.IAlarmQueryDAO;
+import org.apache.skywalking.oap.server.core.storage.query.IMetadataQueryDAO;
+import org.apache.skywalking.oap.server.core.storage.query.IMetricQueryDAO;
+import org.apache.skywalking.oap.server.core.storage.query.ITopologyQueryDAO;
+import org.apache.skywalking.oap.server.core.storage.query.ITraceQueryDAO;
+import org.apache.skywalking.oap.server.library.client.ClientException;
+import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient;
+import org.apache.skywalking.oap.server.library.module.ModuleConfig;
+import org.apache.skywalking.oap.server.library.module.ModuleDefine;
+import org.apache.skywalking.oap.server.library.module.ModuleProvider;
+import org.apache.skywalking.oap.server.library.module.ModuleStartException;
+import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException;
+import org.apache.skywalking.oap.server.library.util.ResourceUtils;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.H2RegisterLockInstaller;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.H2StorageConfig;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.H2StorageProvider;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2AggregationQueryDAO;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2AlarmQueryDAO;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2BatchDAO;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2EndpointInventoryCacheDAO;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2HistoryDeleteDAO;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2MetadataQueryDAO;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2MetricQueryDAO;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2NetworkAddressInventoryCacheDAO;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2RegisterLockDAO;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2ServiceInstanceInventoryCacheDAO;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2ServiceInventoryCacheDAO;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2StorageDAO;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2TopologyQueryDAO;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2TraceQueryDAO;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * MySQL storage provider should be secondary choice for production usage as SkyWalking storage solution. It enhanced
+ * and came from H2StorageProvider, but consider more in using in production.
+ *
+ * Because this module is not really related to MySQL, instead, it is based on MySQL SQL style with JDBC, so, by having
+ * this storage implementation, we could also use this in MySQL-compatible projects, such as, Apache ShardingSphere,
+ * TiDB
+ *
+ * @author wusheng
+ */
+public class MySQLStorageProvider extends ModuleProvider {
+    private static final Logger logger = LoggerFactory.getLogger(H2StorageProvider.class);
+
+    private H2StorageConfig config;
+    private JDBCHikariCPClient h2Client;
+
+    public MySQLStorageProvider() {
+        config = new H2StorageConfig();
+    }
+
+    @Override public String name() {
+        return "mysql";
+    }
+
+    @Override public Class<? extends ModuleDefine> module() {
+        return StorageModule.class;
+    }
+
+    @Override public ModuleConfig createConfigBeanIfAbsent() {
+        return config;
+    }
+
+    @Override public void prepare() throws ServiceNotProvidedException, ModuleStartException {
+        Properties settings = new Properties();
+        try {
+            settings.load(ResourceUtils.read("datasource-settings.properties"));
+        } catch (IOException e) {
+            throw new ModuleStartException("load datasource setting file failure.", e);
+        }
+
+        h2Client = new JDBCHikariCPClient(settings);
+
+        this.registerServiceImplementation(IBatchDAO.class, new H2BatchDAO(h2Client));
+        this.registerServiceImplementation(StorageDAO.class, new H2StorageDAO(h2Client));
+        this.registerServiceImplementation(IRegisterLockDAO.class, new H2RegisterLockDAO());
+
+        this.registerServiceImplementation(IServiceInventoryCacheDAO.class, new H2ServiceInventoryCacheDAO(h2Client));
+        this.registerServiceImplementation(IServiceInstanceInventoryCacheDAO.class, new H2ServiceInstanceInventoryCacheDAO(h2Client));
+        this.registerServiceImplementation(IEndpointInventoryCacheDAO.class, new H2EndpointInventoryCacheDAO(h2Client));
+        this.registerServiceImplementation(INetworkAddressInventoryCacheDAO.class, new H2NetworkAddressInventoryCacheDAO(h2Client));
+
+        this.registerServiceImplementation(ITopologyQueryDAO.class, new H2TopologyQueryDAO(h2Client));
+        this.registerServiceImplementation(IMetricQueryDAO.class, new H2MetricQueryDAO(h2Client));
+        this.registerServiceImplementation(ITraceQueryDAO.class, new H2TraceQueryDAO(h2Client));
+        this.registerServiceImplementation(IMetadataQueryDAO.class, new H2MetadataQueryDAO(h2Client));
+        this.registerServiceImplementation(IAggregationQueryDAO.class, new H2AggregationQueryDAO(h2Client));
+        this.registerServiceImplementation(IAlarmQueryDAO.class, new H2AlarmQueryDAO());
+        this.registerServiceImplementation(IHistoryDeleteDAO.class, new H2HistoryDeleteDAO());
+    }
+
+    @Override public void start() throws ServiceNotProvidedException, ModuleStartException {
+        try {
+            h2Client.initialize();
+
+            MySQLTableInstaller installer = new MySQLTableInstaller(getManager());
+            installer.install(h2Client);
+
+            new H2RegisterLockInstaller().install(h2Client);
+        } catch (StorageException e) {
+            throw new ModuleStartException(e.getMessage(), e);
+        } catch (ClientException e) {
+            throw new ModuleStartException(e.getMessage(), e);
+        }
+    }
+
+    @Override public void notifyAfterCompleted() throws ServiceNotProvidedException, ModuleStartException {
+
+    }
+
+    @Override public String[] requiredModules() {
+        return new String[0];
+    }
+}
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLTableInstaller.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLTableInstaller.java
new file mode 100644
index 0000000..0e861cd
--- /dev/null
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/MySQLTableInstaller.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.oap.server.storage.plugin.jdbc.mysql;
+
+import org.apache.skywalking.oap.server.core.analysis.indicator.IntKeyLongValueArray;
+import org.apache.skywalking.oap.server.library.module.ModuleManager;
+import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2TableInstaller;
+
+/**
+ * Extend H2TableInstaller but match MySQL SQL syntax.
+ *
+ * @author wusheng
+ */
+public class MySQLTableInstaller extends H2TableInstaller {
+    public MySQLTableInstaller(ModuleManager moduleManager) {
+        super(moduleManager);
+        /**
+         * Override column because the default column names in core have syntax conflict with MySQL.
+         */
+        this.overrideColumnName("precision", "cal_precision");
+        this.overrideColumnName("match", "match_num");
+    }
+
+    @Override
+    protected String getColumnType(Class<?> type) {
+        if (Integer.class.equals(type) || int.class.equals(type)) {
+            return "INT";
+        } else if (Long.class.equals(type) || long.class.equals(type)) {
+            return "BIGINT";
+        } else if (Double.class.equals(type) || double.class.equals(type)) {
+            return "DOUBLE";
+        } else if (String.class.equals(type)) {
+            return "VARCHAR(2000)";
+        } else if (IntKeyLongValueArray.class.equals(type)) {
+            return "MEDIUMTEXT";
+        } else if (byte[].class.equals(type)) {
+            return "MEDIUMTEXT";
+        } else {
+            throw new IllegalArgumentException("Unsupported data type: " + type.getName());
+        }
+    }
+}
diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider
index 86c2c56..c8fa0b9 100644
--- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider
@@ -16,4 +16,5 @@
 #
 #
 
-org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.H2StorageProvider
\ No newline at end of file
+org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.H2StorageProvider
+org.apache.skywalking.oap.server.storage.plugin.jdbc.mysql.MySQLStorageProvider
\ No newline at end of file
diff --git a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ColumnName.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/test/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/PreventRedistributionMySQLDriver.java
similarity index 52%
copy from oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ColumnName.java
copy to oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/test/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/PreventRedistributionMySQLDriver.java
index be7e775..d4f81ca 100644
--- a/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/storage/model/ColumnName.java
+++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/test/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/PreventRedistributionMySQLDriver.java
@@ -16,26 +16,29 @@
  *
  */
 
-package org.apache.skywalking.oap.server.core.storage.model;
+package org.apache.skywalking.oap.server.storage.plugin.jdbc.mysql;
+
+import org.junit.Assert;
+import org.junit.Test;
 
 /**
- * @author peng-yongsheng
+ * This is a very special test case. It isn't for feature testing.
+ *
+ * In Apache, we can't redistribute MySQL Driver, because of GPL license, but we deliver MySQL solution source codes and
+ * distribution by using JDBC.
+ *
+ * @author wusheng
  */
-public class ColumnName {
-    private final String fullName;
-    private final String shortName;
-    private boolean useShortName = false;
-
-    public ColumnName(String fullName, String shortName) {
-        this.fullName = fullName;
-        this.shortName = shortName;
-    }
-
-    public String getName() {
-        return useShortName ? shortName : fullName;
-    }
+public class PreventRedistributionMySQLDriver {
+    @Test
+    public void TestMySQLDriverNotExist() {
+        boolean existDriverClassInClasspath = true;
+        try {
+            Class.forName("com.mysql.cj.jdbc.Driver");
+        } catch (ClassNotFoundException e) {
+            existDriverClassInClasspath = false;
+        }
 
-    public void useShortName() {
-        this.useShortName = true;
+        Assert.assertFalse(existDriverClassInClasspath);
     }
 }