This is an automated email from the ASF dual-hosted git repository.
rohit pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
The following commit(s) were added to refs/heads/main by this push:
new 7e085d5e1df framework/db: use HikariCP as default and improvements
(#9518)
7e085d5e1df is described below
commit 7e085d5e1df9fd58305f0a9504c27b35e077e4f0
Author: Abhishek Kumar <[email protected]>
AuthorDate: Thu Sep 5 09:36:58 2024 +0530
framework/db: use HikariCP as default and improvements (#9518)
Per docs, if the mysql connector is JDBC2 compliant then it should use
the Connection.isValid API to test a connection.
(https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#isValid-int-)
This would significantly reduce query lags and API throughput, as for
every SQL query one or two SELECT 1 are performed everytime a Connection
is given to application logic.
This should only be accepted when the driver is JDBC4 complaint.
As per the docs, the connector-j can use /* ping */ before calling
SELECT 1 to have light weight application pings to the server:
https://dev.mysql.com/doc/connector-j/en/connector-j-usagenotes-j2ee-concepts-connection-pooling.html
Replaces dbcp2 connection pool library with more performant HikariCP.
With this unit tests are failing but build is passing.
Signed-off-by: Rohit Yadav <[email protected]>
Signed-off-by: Abhishek Kumar <[email protected]>
Co-authored-by: Rohit Yadav <[email protected]>
---
client/conf/db.properties.in | 20 ++-
developer/pom.xml | 4 +
.../java/com/cloud/upgrade/DatabaseCreator.java | 10 +-
engine/storage/snapshot/pom.xml | 5 +
framework/db/pom.xml | 8 +
.../com/cloud/utils/db/ConnectionConcierge.java | 2 +-
.../java/com/cloud/utils/db/TransactionLegacy.java | 191 +++++++++++++++++----
plugins/network-elements/globodns/pom.xml | 5 +
plugins/network-elements/tungsten/pom.xml | 5 +
pom.xml | 13 ++
server/pom.xml | 5 +
usage/conf/db.properties.in | 4 +
12 files changed, 229 insertions(+), 43 deletions(-)
diff --git a/client/conf/db.properties.in b/client/conf/db.properties.in
index 8f31aff17e6..0f7d2706a42 100644
--- a/client/conf/db.properties.in
+++ b/client/conf/db.properties.in
@@ -34,10 +34,14 @@ db.cloud.uri=
# CloudStack database tuning parameters
+db.cloud.connectionPoolLib=hikaricp
db.cloud.maxActive=250
db.cloud.maxIdle=30
-db.cloud.maxWait=10000
-db.cloud.validationQuery=SELECT 1
+db.cloud.maxWait=600000
+db.cloud.minIdleConnections=5
+db.cloud.connectionTimeout=30000
+db.cloud.keepAliveTime=600000
+db.cloud.validationQuery=/* ping */ SELECT 1
db.cloud.testOnBorrow=true
db.cloud.testWhileIdle=true
db.cloud.timeBetweenEvictionRunsMillis=40000
@@ -70,9 +74,13 @@ db.usage.uri=
# usage database tuning parameters
+db.usage.connectionPoolLib=hikaricp
db.usage.maxActive=100
db.usage.maxIdle=30
-db.usage.maxWait=10000
+db.usage.maxWait=600000
+db.usage.minIdleConnections=5
+db.usage.connectionTimeout=30000
+db.usage.keepAliveTime=600000
db.usage.url.params=serverTimezone=UTC
# Simulator database settings
@@ -82,9 +90,13 @@ db.simulator.host=@DBHOST@
db.simulator.driver=@DBDRIVER@
db.simulator.port=3306
db.simulator.name=simulator
+db.simulator.connectionPoolLib=hikaricp
db.simulator.maxActive=250
db.simulator.maxIdle=30
-db.simulator.maxWait=10000
+db.simulator.maxWait=600000
+db.simulator.minIdleConnections=5
+db.simulator.connectionTimeout=30000
+db.simulator.keepAliveTime=600000
db.simulator.autoReconnect=true
# Connection URI to the database "simulator". When this property is set, only
the following properties will be used along with it: db.simulator.host,
db.simulator.port, db.simulator.name, db.simulator.autoReconnect. Other
properties will be ignored.
diff --git a/developer/pom.xml b/developer/pom.xml
index 6cbf483faac..b44446ec0a5 100644
--- a/developer/pom.xml
+++ b/developer/pom.xml
@@ -42,6 +42,10 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.zaxxer</groupId>
+ <artifactId>HikariCP</artifactId>
+ </dependency>
<dependency>
<groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId>
diff --git a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseCreator.java
b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseCreator.java
index 154a8d11887..384826227af 100644
--- a/engine/schema/src/main/java/com/cloud/upgrade/DatabaseCreator.java
+++ b/engine/schema/src/main/java/com/cloud/upgrade/DatabaseCreator.java
@@ -116,10 +116,6 @@ public class DatabaseCreator {
}
public static void main(String[] args) {
-
- ClassPathXmlApplicationContext appContext = new
ClassPathXmlApplicationContext(new String[]
{"/com/cloud/upgrade/databaseCreatorContext.xml"});
- appContext.getBean(ComponentContext.class);
-
String dbPropsFile = "";
List<String> sqlFiles = new ArrayList<String>();
List<String> upgradeClasses = new ArrayList<String>();
@@ -166,13 +162,17 @@ public class DatabaseCreator {
System.exit(1);
}
+ initDB(dbPropsFile, rootPassword, databases, dryRun);
+
+ ClassPathXmlApplicationContext appContext = new
ClassPathXmlApplicationContext(new String[]
{"/com/cloud/upgrade/databaseCreatorContext.xml"});
+ appContext.getBean(ComponentContext.class);
+
try {
TransactionLegacy.initDataSource(dbPropsFile);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
- initDB(dbPropsFile, rootPassword, databases, dryRun);
// Process sql files
for (String sqlFile : sqlFiles) {
diff --git a/engine/storage/snapshot/pom.xml b/engine/storage/snapshot/pom.xml
index ac0daeabf76..f29b43d8de0 100644
--- a/engine/storage/snapshot/pom.xml
+++ b/engine/storage/snapshot/pom.xml
@@ -56,6 +56,11 @@
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
<plugins>
diff --git a/framework/db/pom.xml b/framework/db/pom.xml
index d4d3b6b8772..586d72f34f3 100644
--- a/framework/db/pom.xml
+++ b/framework/db/pom.xml
@@ -40,6 +40,10 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.zaxxer</groupId>
+ <artifactId>HikariCP</artifactId>
+ </dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
@@ -48,6 +52,10 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-utils</artifactId>
diff --git
a/framework/db/src/main/java/com/cloud/utils/db/ConnectionConcierge.java
b/framework/db/src/main/java/com/cloud/utils/db/ConnectionConcierge.java
index 7cf34e6955c..c7c869ba920 100644
--- a/framework/db/src/main/java/com/cloud/utils/db/ConnectionConcierge.java
+++ b/framework/db/src/main/java/com/cloud/utils/db/ConnectionConcierge.java
@@ -145,7 +145,7 @@ public class ConnectionConcierge {
protected String testValidity(String name, Connection conn) {
if (conn != null) {
synchronized (conn) {
- try (PreparedStatement pstmt =
conn.prepareStatement("SELECT 1");) {
+ try (PreparedStatement pstmt = conn.prepareStatement("/*
ping */ SELECT 1");) {
pstmt.executeQuery();
} catch (Throwable th) {
logger.error("Unable to keep the db connection for " +
name, th);
diff --git
a/framework/db/src/main/java/com/cloud/utils/db/TransactionLegacy.java
b/framework/db/src/main/java/com/cloud/utils/db/TransactionLegacy.java
index 00fa8e4c0d5..88af397c06a 100644
--- a/framework/db/src/main/java/com/cloud/utils/db/TransactionLegacy.java
+++ b/framework/db/src/main/java/com/cloud/utils/db/TransactionLegacy.java
@@ -38,17 +38,20 @@ import
org.apache.commons.dbcp2.DriverManagerConnectionFactory;
import org.apache.commons.dbcp2.PoolableConnection;
import org.apache.commons.dbcp2.PoolableConnectionFactory;
import org.apache.commons.dbcp2.PoolingDataSource;
+import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool2.ObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
-import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
import com.cloud.utils.Pair;
import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.mgmt.JmxUtil;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
/**
* Transaction abstracts away the Connection object in JDBC. It allows the
@@ -95,6 +98,8 @@ public class TransactionLegacy implements Closeable {
}
}
+ private static final String CONNECTION_POOL_LIB_DBCP = "dbcp";
+
private final LinkedList<StackElement> _stack;
private long _id;
@@ -1020,6 +1025,21 @@ public class TransactionLegacy implements Closeable {
}
}
+ private static <T extends Number> T parseNumber(String value, Class<T>
type) {
+ if (value == null) {
+ return null;
+ }
+ try {
+ if (type.equals(Long.class)) {
+ return type.cast(Long.parseLong(value));
+ } else {
+ return type.cast(Integer.parseInt(value));
+ }
+ } catch (NumberFormatException ignored) {
+ return null;
+ }
+ }
+
@SuppressWarnings({"rawtypes", "unchecked"})
public static void initDataSource(Properties dbProps) {
try {
@@ -1030,9 +1050,12 @@ public class TransactionLegacy implements Closeable {
LOGGER.info("Is Data Base High Availiability enabled? Ans : " +
s_dbHAEnabled);
String loadBalanceStrategy =
dbProps.getProperty("db.ha.loadBalanceStrategy");
// FIXME: If params are missing...default them????
- final int cloudMaxActive =
Integer.parseInt(dbProps.getProperty("db.cloud.maxActive"));
- final int cloudMaxIdle =
Integer.parseInt(dbProps.getProperty("db.cloud.maxIdle"));
- final long cloudMaxWait =
Long.parseLong(dbProps.getProperty("db.cloud.maxWait"));
+ final Integer cloudMaxActive =
parseNumber(dbProps.getProperty("db.cloud.maxActive"), Integer.class);
+ final Integer cloudMaxIdle =
parseNumber(dbProps.getProperty("db.cloud.maxIdle"), Integer.class);
+ final Long cloudMaxWait =
parseNumber(dbProps.getProperty("db.cloud.maxWait"), Long.class);
+ final Integer cloudMinIdleConnections =
parseNumber(dbProps.getProperty("db.cloud.minIdleConnections"), Integer.class);
+ final Long cloudConnectionTimeout =
parseNumber(dbProps.getProperty("db.cloud.connectionTimeout"), Long.class);
+ final Long cloudKeepAliveTimeout =
parseNumber(dbProps.getProperty("db.cloud.keepAliveTime"), Long.class);
final String cloudUsername =
dbProps.getProperty("db.cloud.username");
final String cloudPassword =
dbProps.getProperty("db.cloud.password");
final String cloudValidationQuery =
dbProps.getProperty("db.cloud.validationQuery");
@@ -1071,14 +1094,19 @@ public class TransactionLegacy implements Closeable {
DriverLoader.loadDriver(cloudUriAndDriver.second());
// Default Data Source for CloudStack
- s_ds = createDataSource(cloudUriAndDriver.first(), cloudUsername,
cloudPassword, cloudMaxActive, cloudMaxIdle, cloudMaxWait,
- cloudTimeBtwEvictionRunsMillis,
cloudMinEvcitableIdleTimeMillis, cloudTestWhileIdle, cloudTestOnBorrow,
- cloudValidationQuery, isolationLevel);
+ s_ds =
createDataSource(dbProps.getProperty("db.cloud.connectionPoolLib"),
cloudUriAndDriver.first(),
+ cloudUsername, cloudPassword, cloudMaxActive,
cloudMaxIdle, cloudMaxWait,
+ cloudTimeBtwEvictionRunsMillis,
cloudMinEvcitableIdleTimeMillis, cloudTestWhileIdle,
+ cloudTestOnBorrow, cloudValidationQuery,
cloudMinIdleConnections, cloudConnectionTimeout,
+ cloudKeepAliveTimeout, isolationLevel, "cloud");
// Configure the usage db
- final int usageMaxActive =
Integer.parseInt(dbProps.getProperty("db.usage.maxActive"));
- final int usageMaxIdle =
Integer.parseInt(dbProps.getProperty("db.usage.maxIdle"));
- final long usageMaxWait =
Long.parseLong(dbProps.getProperty("db.usage.maxWait"));
+ final Integer usageMaxActive =
parseNumber(dbProps.getProperty("db.usage.maxActive"), Integer.class);
+ final Integer usageMaxIdle =
parseNumber(dbProps.getProperty("db.usage.maxIdle"), Integer.class);
+ final Long usageMaxWait =
parseNumber(dbProps.getProperty("db.usage.maxWait"), Long.class);
+ final Integer usageMinIdleConnections =
parseNumber(dbProps.getProperty("db.usage.minIdleConnections"), Integer.class);
+ final Long usageConnectionTimeout =
parseNumber(dbProps.getProperty("db.usage.connectionTimeout"), Long.class);
+ final Long usageKeepAliveTimeout =
parseNumber(dbProps.getProperty("db.usage.keepAliveTime"), Long.class);
final String usageUsername =
dbProps.getProperty("db.usage.username");
final String usagePassword =
dbProps.getProperty("db.usage.password");
@@ -1087,15 +1115,19 @@ public class TransactionLegacy implements Closeable {
DriverLoader.loadDriver(usageUriAndDriver.second());
// Data Source for usage server
- s_usageDS = createDataSource(usageUriAndDriver.first(),
usageUsername, usagePassword,
- usageMaxActive, usageMaxIdle, usageMaxWait, null, null,
null, null,
- null, isolationLevel);
+ s_usageDS =
createDataSource(dbProps.getProperty("db.usage.connectionPoolLib"),
usageUriAndDriver.first(),
+ usageUsername, usagePassword, usageMaxActive,
usageMaxIdle, usageMaxWait, null,
+ null, null, null, null,
+ usageMinIdleConnections, usageConnectionTimeout,
usageKeepAliveTimeout, isolationLevel, "usage");
try {
// Configure the simulator db
- final int simulatorMaxActive =
Integer.parseInt(dbProps.getProperty("db.simulator.maxActive"));
- final int simulatorMaxIdle =
Integer.parseInt(dbProps.getProperty("db.simulator.maxIdle"));
- final long simulatorMaxWait =
Long.parseLong(dbProps.getProperty("db.simulator.maxWait"));
+ final Integer simulatorMaxActive =
parseNumber(dbProps.getProperty("db.simulator.maxActive"), Integer.class);
+ final Integer simulatorMaxIdle =
parseNumber(dbProps.getProperty("db.simulator.maxIdle"), Integer.class);
+ final Long simulatorMaxWait =
parseNumber(dbProps.getProperty("db.simulator.maxWait"), Long.class);
+ final Integer simulatorMinIdleConnections =
parseNumber(dbProps.getProperty("db.simulator.minIdleConnections"),
Integer.class);
+ final Long simulatorConnectionTimeout =
parseNumber(dbProps.getProperty("db.simulator.connectionTimeout"), Long.class);
+ final Long simulatorKeepAliveTimeout =
parseNumber(dbProps.getProperty("db.simulator.keepAliveTime"), Long.class);
final String simulatorUsername =
dbProps.getProperty("db.simulator.username");
final String simulatorPassword =
dbProps.getProperty("db.simulator.password");
@@ -1122,15 +1154,18 @@ public class TransactionLegacy implements Closeable {
DriverLoader.loadDriver(simulatorDriver);
- s_simulatorDS = createDataSource(simulatorConnectionUri,
simulatorUsername, simulatorPassword,
- simulatorMaxActive, simulatorMaxIdle,
simulatorMaxWait, null, null, null, null, cloudValidationQuery, isolationLevel);
+ s_simulatorDS =
createDataSource(dbProps.getProperty("db.simulator.connectionPoolLib"),
+ simulatorConnectionUri, simulatorUsername,
simulatorPassword, simulatorMaxActive,
+ simulatorMaxIdle, simulatorMaxWait, null, null, null,
null,
+ cloudValidationQuery, simulatorMinIdleConnections,
simulatorConnectionTimeout,
+ simulatorKeepAliveTimeout, isolationLevel,
"simulator");
} catch (Exception e) {
LOGGER.debug("Simulator DB properties are not available. Not
initializing simulator DS");
}
} catch (final Exception e) {
- s_ds = getDefaultDataSource("cloud");
- s_usageDS = getDefaultDataSource("cloud_usage");
- s_simulatorDS = getDefaultDataSource("cloud_simulator");
+ s_ds =
getDefaultDataSource(dbProps.getProperty("db.cloud.connectionPoolLib"),
"cloud");
+ s_usageDS =
getDefaultDataSource(dbProps.getProperty("db.usage.connectionPoolLib"),
"cloud_usage");
+ s_simulatorDS =
getDefaultDataSource(dbProps.getProperty("db.simulator.connectionPoolLib"),
"simulator");
LOGGER.warn(
"Unable to load db configuration, using defaults with 5
connections. Falling back on assumed datasource on localhost:3306 using
username:password=cloud:cloud. Please check your configuration",
e);
@@ -1222,11 +1257,71 @@ public class TransactionLegacy implements Closeable {
/**
* Creates a data source
*/
- private static DataSource createDataSource(String uri, String username,
String password,
+ private static DataSource createDataSource(String connectionPoolLib,
String uri, String username, String password,
+ Integer maxActive, Integer maxIdle, Long maxWait, Long
timeBtwnEvictionRuns, Long minEvictableIdleTime,
+ Boolean testWhileIdle, Boolean testOnBorrow, String
validationQuery, Integer minIdleConnections,
+ Long connectionTimeout, Long keepAliveTime, Integer
isolationLevel, String dsName) {
+ LOGGER.debug("Creating datasource for database: {} with connection
pool lib: {}", dsName,
+ connectionPoolLib);
+ if (CONNECTION_POOL_LIB_DBCP.equals(connectionPoolLib)) {
+ return createDbcpDataSource(uri, username, password, maxActive,
maxIdle, maxWait, timeBtwnEvictionRuns,
+ minEvictableIdleTime, testWhileIdle, testOnBorrow,
validationQuery, isolationLevel);
+ }
+ return createHikaricpDataSource(uri, username, password, maxActive,
maxIdle, maxWait, minIdleConnections,
+ connectionTimeout, keepAliveTime, isolationLevel, dsName);
+ }
+
+ private static DataSource createHikaricpDataSource(String uri, String
username, String password,
Integer maxActive, Integer
maxIdle, Long maxWait,
- Long timeBtwnEvictionRuns, Long
minEvictableIdleTime,
- Boolean testWhileIdle, Boolean
testOnBorrow,
- String validationQuery, Integer
isolationLevel) {
+ Integer minIdleConnections,
Long connectionTimeout, Long keepAliveTime,
+ Integer isolationLevel, String
dsName) {
+ HikariConfig config = new HikariConfig();
+ config.setJdbcUrl(uri);
+ config.setUsername(username);
+ config.setPassword(password);
+
+ config.setPoolName(dsName);
+
+ // Connection pool properties
+ config.setMaximumPoolSize(ObjectUtils.defaultIfNull(maxActive, 250));
+ config.setIdleTimeout(ObjectUtils.defaultIfNull(maxIdle, 30) * 1000);
+ config.setMaxLifetime(ObjectUtils.defaultIfNull(maxWait, 600000L));
+ config.setMinimumIdle(ObjectUtils.defaultIfNull(minIdleConnections,
5));
+
config.setConnectionTimeout(ObjectUtils.defaultIfNull(connectionTimeout,
30000L));
+ config.setKeepaliveTime(ObjectUtils.defaultIfNull(keepAliveTime,
600000L));
+
+ String isolationLevelString = "TRANSACTION_READ_COMMITTED";
+ if (isolationLevel == Connection.TRANSACTION_SERIALIZABLE) {
+ isolationLevelString = "TRANSACTION_SERIALIZABLE";
+ } else if (isolationLevel == Connection.TRANSACTION_READ_UNCOMMITTED) {
+ isolationLevelString = "TRANSACTION_READ_UNCOMMITTED";
+ } else if (isolationLevel == Connection.TRANSACTION_REPEATABLE_READ) {
+ isolationLevelString = "TRANSACTION_REPEATABLE_READ";
+ }
+ config.setTransactionIsolation(isolationLevelString);
+
+ // Standard datasource config for MySQL
+ config.addDataSourceProperty("cachePrepStmts", "true");
+ config.addDataSourceProperty("prepStmtCacheSize", "250");
+ config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
+ // Additional config for MySQL
+ config.addDataSourceProperty("useServerPrepStmts", "true");
+ config.addDataSourceProperty("useLocalSessionState", "true");
+ config.addDataSourceProperty("rewriteBatchedStatements", "true");
+ config.addDataSourceProperty("cacheResultSetMetadata", "true");
+ config.addDataSourceProperty("cacheServerConfiguration", "true");
+ config.addDataSourceProperty("elideSetAutoCommits", "true");
+ config.addDataSourceProperty("maintainTimeStats", "false");
+
+ HikariDataSource dataSource = new HikariDataSource(config);
+ return dataSource;
+ }
+
+ private static DataSource createDbcpDataSource(String uri, String
username, String password,
+ Integer maxActive, Integer
maxIdle, Long maxWait,
+ Long timeBtwnEvictionRuns,
Long minEvictableIdleTime,
+ Boolean testWhileIdle, Boolean
testOnBorrow,
+ String validationQuery,
Integer isolationLevel) {
ConnectionFactory connectionFactory = new
DriverManagerConnectionFactory(uri, username, password);
PoolableConnectionFactory poolableConnectionFactory = new
PoolableConnectionFactory(connectionFactory, null);
GenericObjectPoolConfig config = createPoolConfig(maxActive, maxIdle,
maxWait, timeBtwnEvictionRuns, minEvictableIdleTime, testWhileIdle,
testOnBorrow);
@@ -1267,6 +1362,44 @@ public class TransactionLegacy implements Closeable {
return config;
}
+ private static DataSource getDefaultDataSource(final String
connectionPoolLib, final String database) {
+ LOGGER.debug("Creating default datasource for database: {} with
connection pool lib: {}",
+ database, connectionPoolLib);
+ if (CONNECTION_POOL_LIB_DBCP.equalsIgnoreCase(connectionPoolLib)) {
+ return getDefaultDbcpDataSource(database);
+ }
+ return getDefaultHikaricpDataSource(database);
+ }
+
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ private static DataSource getDefaultHikaricpDataSource(final String
database) {
+ HikariConfig config = new HikariConfig();
+ config.setJdbcUrl("jdbc:mysql://localhost:3306/" + database + "?" +
CONNECTION_PARAMS);
+ config.setUsername("cloud");
+ config.setPassword("cloud");
+ config.setPoolName(database);
+ config.setDriverClassName("com.mysql.cj.jdbc.Driver");
+ config.setMaximumPoolSize(250);
+ config.setConnectionTimeout(1000);
+ config.setIdleTimeout(1000);
+ config.setKeepaliveTime(1000);
+ config.setMaxLifetime(1000);
+ config.setTransactionIsolation("TRANSACTION_READ_COMMITTED");
+ config.setInitializationFailTimeout(-1L);
+ config.addDataSourceProperty("cachePrepStmts", "true");
+ config.addDataSourceProperty("prepStmtCacheSize", "250");
+ config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
+ return new HikariDataSource(config);
+ }
+
+ @SuppressWarnings({"unchecked", "rawtypes"})
+ private static DataSource getDefaultDbcpDataSource(final String database) {
+ final ConnectionFactory connectionFactory = new
DriverManagerConnectionFactory("jdbc:mysql://localhost:3306/" + database + "?"
+ CONNECTION_PARAMS, "cloud", "cloud");
+ final PoolableConnectionFactory poolableConnectionFactory = new
PoolableConnectionFactory(connectionFactory, null);
+ final GenericObjectPool connectionPool = new
GenericObjectPool(poolableConnectionFactory);
+ return new PoolingDataSource(connectionPool);
+ }
+
private static String getDBHAParams(String dbName, Properties dbProps) {
StringBuilder sb = new StringBuilder();
sb.append("failOverReadOnly=" + dbProps.getProperty("db." + dbName +
".failOverReadOnly"));
@@ -1278,14 +1411,6 @@ public class TransactionLegacy implements Closeable {
return sb.toString();
}
- @SuppressWarnings({"unchecked", "rawtypes"})
- private static DataSource getDefaultDataSource(final String database) {
- final ConnectionFactory connectionFactory = new
DriverManagerConnectionFactory("jdbc:mysql://localhost:3306/" + database + "?"
+ CONNECTION_PARAMS, "cloud", "cloud");
- final PoolableConnectionFactory poolableConnectionFactory = new
PoolableConnectionFactory(connectionFactory, null);
- final GenericObjectPool connectionPool = new
GenericObjectPool(poolableConnectionFactory);
- return new PoolingDataSource(connectionPool);
- }
-
/**
* Used for unit testing primarily
*
diff --git a/plugins/network-elements/globodns/pom.xml
b/plugins/network-elements/globodns/pom.xml
index e27a4a54d16..c0200921f20 100644
--- a/plugins/network-elements/globodns/pom.xml
+++ b/plugins/network-elements/globodns/pom.xml
@@ -32,5 +32,10 @@
<groupId>com.globo.globodns</groupId>
<artifactId>globodns-client</artifactId>
</dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/plugins/network-elements/tungsten/pom.xml
b/plugins/network-elements/tungsten/pom.xml
index b0a46b1331a..1345268d313 100644
--- a/plugins/network-elements/tungsten/pom.xml
+++ b/plugins/network-elements/tungsten/pom.xml
@@ -47,5 +47,10 @@
<groupId>ch.qos.reload4j</groupId>
<artifactId>reload4j</artifactId>
</dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/pom.xml b/pom.xml
index 2ed3f8301cc..1acea98096f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -102,6 +102,7 @@
<cs.configuration.version>1.10</cs.configuration.version>
<cs.daemon.version>1.3.3</cs.daemon.version>
<cs.dbcp.version>2.9.0</cs.dbcp.version>
+ <cs.hikaricp.version>5.1.0</cs.hikaricp.version>
<cs.discovery.version>0.5</cs.discovery.version>
<cs.lang.version>2.6</cs.lang.version>
<cs.pool.version>2.9.0</cs.pool.version>
@@ -364,6 +365,7 @@
<artifactId>commons-daemon</artifactId>
<version>${cs.daemon.version}</version>
</dependency>
+
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
@@ -375,6 +377,11 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>com.zaxxer</groupId>
+ <artifactId>HikariCP</artifactId>
+ <version>${cs.hikaricp.version}</version>
+ </dependency>
<dependency>
<groupId>commons-discovery</groupId>
<artifactId>commons-discovery</artifactId>
@@ -455,6 +462,12 @@
<artifactId>reload4j</artifactId>
<version>${cs.reload4j.version}</version>
</dependency>
+ <dependency>
+ <groupId>mysql</groupId>
+ <artifactId>mysql-connector-java</artifactId>
+ <version>${cs.mysql.version}</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>apache-log4j-extras</artifactId>
diff --git a/server/pom.xml b/server/pom.xml
index 269583c381a..ec157b00e30 100644
--- a/server/pom.xml
+++ b/server/pom.xml
@@ -164,6 +164,11 @@
<artifactId>cloud-framework-agent-lb</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.cloudstack</groupId>
+ <artifactId>cloud-framework-db</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine-storage-configdrive</artifactId>
diff --git a/usage/conf/db.properties.in b/usage/conf/db.properties.in
index 35a40def7b1..c597bb9fad3 100644
--- a/usage/conf/db.properties.in
+++ b/usage/conf/db.properties.in
@@ -24,7 +24,11 @@ db.usage.port=3306
db.usage.name=cloud_usage
# usage database tuning parameters
+db.usage.connectionPoolLib=hikaricp
db.usage.maxActive=100
db.usage.maxIdle=30
db.usage.maxWait=10000
+db.usage.minIdleConnections=5
+db.usage.connectionTimeout=30000
+db.usage.keepAliveTime=600000
db.usage.autoReconnect=true