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 <rohit.yadav@shapeblue.com>
Signed-off-by: Abhishek Kumar <abhishek.mrt22@gmail.com>
Co-authored-by: Rohit Yadav <rohityadav89@gmail.com>
This commit is contained in:
Abhishek Kumar 2024-09-05 09:36:58 +05:30 committed by GitHub
parent 31b0ed0a18
commit 7e085d5e1d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 229 additions and 43 deletions

View File

@ -34,10 +34,14 @@ db.cloud.uri=
# CloudStack database tuning parameters # CloudStack database tuning parameters
db.cloud.connectionPoolLib=hikaricp
db.cloud.maxActive=250 db.cloud.maxActive=250
db.cloud.maxIdle=30 db.cloud.maxIdle=30
db.cloud.maxWait=10000 db.cloud.maxWait=600000
db.cloud.validationQuery=SELECT 1 db.cloud.minIdleConnections=5
db.cloud.connectionTimeout=30000
db.cloud.keepAliveTime=600000
db.cloud.validationQuery=/* ping */ SELECT 1
db.cloud.testOnBorrow=true db.cloud.testOnBorrow=true
db.cloud.testWhileIdle=true db.cloud.testWhileIdle=true
db.cloud.timeBetweenEvictionRunsMillis=40000 db.cloud.timeBetweenEvictionRunsMillis=40000
@ -70,9 +74,13 @@ db.usage.uri=
# usage database tuning parameters # usage database tuning parameters
db.usage.connectionPoolLib=hikaricp
db.usage.maxActive=100 db.usage.maxActive=100
db.usage.maxIdle=30 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 db.usage.url.params=serverTimezone=UTC
# Simulator database settings # Simulator database settings
@ -82,9 +90,13 @@ db.simulator.host=@DBHOST@
db.simulator.driver=@DBDRIVER@ db.simulator.driver=@DBDRIVER@
db.simulator.port=3306 db.simulator.port=3306
db.simulator.name=simulator db.simulator.name=simulator
db.simulator.connectionPoolLib=hikaricp
db.simulator.maxActive=250 db.simulator.maxActive=250
db.simulator.maxIdle=30 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 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. # 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.

View File

@ -42,6 +42,10 @@
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.jasypt</groupId> <groupId>org.jasypt</groupId>
<artifactId>jasypt</artifactId> <artifactId>jasypt</artifactId>

View File

@ -116,10 +116,6 @@ public class DatabaseCreator {
} }
public static void main(String[] args) { public static void main(String[] args) {
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] {"/com/cloud/upgrade/databaseCreatorContext.xml"});
appContext.getBean(ComponentContext.class);
String dbPropsFile = ""; String dbPropsFile = "";
List<String> sqlFiles = new ArrayList<String>(); List<String> sqlFiles = new ArrayList<String>();
List<String> upgradeClasses = new ArrayList<String>(); List<String> upgradeClasses = new ArrayList<String>();
@ -166,13 +162,17 @@ public class DatabaseCreator {
System.exit(1); System.exit(1);
} }
initDB(dbPropsFile, rootPassword, databases, dryRun);
ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(new String[] {"/com/cloud/upgrade/databaseCreatorContext.xml"});
appContext.getBean(ComponentContext.class);
try { try {
TransactionLegacy.initDataSource(dbPropsFile); TransactionLegacy.initDataSource(dbPropsFile);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
System.exit(1); System.exit(1);
} }
initDB(dbPropsFile, rootPassword, databases, dryRun);
// Process sql files // Process sql files
for (String sqlFile : sqlFiles) { for (String sqlFile : sqlFiles) {

View File

@ -56,6 +56,11 @@
<version>${project.version}</version> <version>${project.version}</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>

View File

@ -40,6 +40,10 @@
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId> <artifactId>commons-dbcp2</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
<dependency> <dependency>
<groupId>commons-io</groupId> <groupId>commons-io</groupId>
<artifactId>commons-io</artifactId> <artifactId>commons-io</artifactId>
@ -48,6 +52,10 @@
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId> <artifactId>commons-pool2</artifactId>
</dependency> </dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency> <dependency>
<groupId>org.apache.cloudstack</groupId> <groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-utils</artifactId> <artifactId>cloud-utils</artifactId>

View File

@ -145,7 +145,7 @@ public class ConnectionConcierge {
protected String testValidity(String name, Connection conn) { protected String testValidity(String name, Connection conn) {
if (conn != null) { if (conn != null) {
synchronized (conn) { synchronized (conn) {
try (PreparedStatement pstmt = conn.prepareStatement("SELECT 1");) { try (PreparedStatement pstmt = conn.prepareStatement("/* ping */ SELECT 1");) {
pstmt.executeQuery(); pstmt.executeQuery();
} catch (Throwable th) { } catch (Throwable th) {
logger.error("Unable to keep the db connection for " + name, th); logger.error("Unable to keep the db connection for " + name, th);

View File

@ -38,17 +38,20 @@ import org.apache.commons.dbcp2.DriverManagerConnectionFactory;
import org.apache.commons.dbcp2.PoolableConnection; import org.apache.commons.dbcp2.PoolableConnection;
import org.apache.commons.dbcp2.PoolableConnectionFactory; import org.apache.commons.dbcp2.PoolableConnectionFactory;
import org.apache.commons.dbcp2.PoolingDataSource; import org.apache.commons.dbcp2.PoolingDataSource;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool2.ObjectPool; import org.apache.commons.pool2.ObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPool; import org.apache.commons.pool2.impl.GenericObjectPool;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.cloud.utils.Pair; import com.cloud.utils.Pair;
import com.cloud.utils.PropertiesUtil; import com.cloud.utils.PropertiesUtil;
import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.mgmt.JmxUtil; 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 * 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 final LinkedList<StackElement> _stack;
private long _id; 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"}) @SuppressWarnings({"rawtypes", "unchecked"})
public static void initDataSource(Properties dbProps) { public static void initDataSource(Properties dbProps) {
try { try {
@ -1030,9 +1050,12 @@ public class TransactionLegacy implements Closeable {
LOGGER.info("Is Data Base High Availiability enabled? Ans : " + s_dbHAEnabled); LOGGER.info("Is Data Base High Availiability enabled? Ans : " + s_dbHAEnabled);
String loadBalanceStrategy = dbProps.getProperty("db.ha.loadBalanceStrategy"); String loadBalanceStrategy = dbProps.getProperty("db.ha.loadBalanceStrategy");
// FIXME: If params are missing...default them???? // FIXME: If params are missing...default them????
final int cloudMaxActive = Integer.parseInt(dbProps.getProperty("db.cloud.maxActive")); final Integer cloudMaxActive = parseNumber(dbProps.getProperty("db.cloud.maxActive"), Integer.class);
final int cloudMaxIdle = Integer.parseInt(dbProps.getProperty("db.cloud.maxIdle")); final Integer cloudMaxIdle = parseNumber(dbProps.getProperty("db.cloud.maxIdle"), Integer.class);
final long cloudMaxWait = Long.parseLong(dbProps.getProperty("db.cloud.maxWait")); 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 cloudUsername = dbProps.getProperty("db.cloud.username");
final String cloudPassword = dbProps.getProperty("db.cloud.password"); final String cloudPassword = dbProps.getProperty("db.cloud.password");
final String cloudValidationQuery = dbProps.getProperty("db.cloud.validationQuery"); final String cloudValidationQuery = dbProps.getProperty("db.cloud.validationQuery");
@ -1071,14 +1094,19 @@ public class TransactionLegacy implements Closeable {
DriverLoader.loadDriver(cloudUriAndDriver.second()); DriverLoader.loadDriver(cloudUriAndDriver.second());
// Default Data Source for CloudStack // Default Data Source for CloudStack
s_ds = createDataSource(cloudUriAndDriver.first(), cloudUsername, cloudPassword, cloudMaxActive, cloudMaxIdle, cloudMaxWait, s_ds = createDataSource(dbProps.getProperty("db.cloud.connectionPoolLib"), cloudUriAndDriver.first(),
cloudTimeBtwEvictionRunsMillis, cloudMinEvcitableIdleTimeMillis, cloudTestWhileIdle, cloudTestOnBorrow, cloudUsername, cloudPassword, cloudMaxActive, cloudMaxIdle, cloudMaxWait,
cloudValidationQuery, isolationLevel); cloudTimeBtwEvictionRunsMillis, cloudMinEvcitableIdleTimeMillis, cloudTestWhileIdle,
cloudTestOnBorrow, cloudValidationQuery, cloudMinIdleConnections, cloudConnectionTimeout,
cloudKeepAliveTimeout, isolationLevel, "cloud");
// Configure the usage db // Configure the usage db
final int usageMaxActive = Integer.parseInt(dbProps.getProperty("db.usage.maxActive")); final Integer usageMaxActive = parseNumber(dbProps.getProperty("db.usage.maxActive"), Integer.class);
final int usageMaxIdle = Integer.parseInt(dbProps.getProperty("db.usage.maxIdle")); final Integer usageMaxIdle = parseNumber(dbProps.getProperty("db.usage.maxIdle"), Integer.class);
final long usageMaxWait = Long.parseLong(dbProps.getProperty("db.usage.maxWait")); 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 usageUsername = dbProps.getProperty("db.usage.username");
final String usagePassword = dbProps.getProperty("db.usage.password"); final String usagePassword = dbProps.getProperty("db.usage.password");
@ -1087,15 +1115,19 @@ public class TransactionLegacy implements Closeable {
DriverLoader.loadDriver(usageUriAndDriver.second()); DriverLoader.loadDriver(usageUriAndDriver.second());
// Data Source for usage server // Data Source for usage server
s_usageDS = createDataSource(usageUriAndDriver.first(), usageUsername, usagePassword, s_usageDS = createDataSource(dbProps.getProperty("db.usage.connectionPoolLib"), usageUriAndDriver.first(),
usageMaxActive, usageMaxIdle, usageMaxWait, null, null, null, null, usageUsername, usagePassword, usageMaxActive, usageMaxIdle, usageMaxWait, null,
null, isolationLevel); null, null, null, null,
usageMinIdleConnections, usageConnectionTimeout, usageKeepAliveTimeout, isolationLevel, "usage");
try { try {
// Configure the simulator db // Configure the simulator db
final int simulatorMaxActive = Integer.parseInt(dbProps.getProperty("db.simulator.maxActive")); final Integer simulatorMaxActive = parseNumber(dbProps.getProperty("db.simulator.maxActive"), Integer.class);
final int simulatorMaxIdle = Integer.parseInt(dbProps.getProperty("db.simulator.maxIdle")); final Integer simulatorMaxIdle = parseNumber(dbProps.getProperty("db.simulator.maxIdle"), Integer.class);
final long simulatorMaxWait = Long.parseLong(dbProps.getProperty("db.simulator.maxWait")); 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 simulatorUsername = dbProps.getProperty("db.simulator.username");
final String simulatorPassword = dbProps.getProperty("db.simulator.password"); final String simulatorPassword = dbProps.getProperty("db.simulator.password");
@ -1122,15 +1154,18 @@ public class TransactionLegacy implements Closeable {
DriverLoader.loadDriver(simulatorDriver); DriverLoader.loadDriver(simulatorDriver);
s_simulatorDS = createDataSource(simulatorConnectionUri, simulatorUsername, simulatorPassword, s_simulatorDS = createDataSource(dbProps.getProperty("db.simulator.connectionPoolLib"),
simulatorMaxActive, simulatorMaxIdle, simulatorMaxWait, null, null, null, null, cloudValidationQuery, isolationLevel); simulatorConnectionUri, simulatorUsername, simulatorPassword, simulatorMaxActive,
simulatorMaxIdle, simulatorMaxWait, null, null, null, null,
cloudValidationQuery, simulatorMinIdleConnections, simulatorConnectionTimeout,
simulatorKeepAliveTimeout, isolationLevel, "simulator");
} catch (Exception e) { } catch (Exception e) {
LOGGER.debug("Simulator DB properties are not available. Not initializing simulator DS"); LOGGER.debug("Simulator DB properties are not available. Not initializing simulator DS");
} }
} catch (final Exception e) { } catch (final Exception e) {
s_ds = getDefaultDataSource("cloud"); s_ds = getDefaultDataSource(dbProps.getProperty("db.cloud.connectionPoolLib"), "cloud");
s_usageDS = getDefaultDataSource("cloud_usage"); s_usageDS = getDefaultDataSource(dbProps.getProperty("db.usage.connectionPoolLib"), "cloud_usage");
s_simulatorDS = getDefaultDataSource("cloud_simulator"); s_simulatorDS = getDefaultDataSource(dbProps.getProperty("db.simulator.connectionPoolLib"), "simulator");
LOGGER.warn( 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", "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); e);
@ -1222,11 +1257,71 @@ public class TransactionLegacy implements Closeable {
/** /**
* Creates a data source * 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, Integer maxActive, Integer maxIdle, Long maxWait,
Long timeBtwnEvictionRuns, Long minEvictableIdleTime, Integer minIdleConnections, Long connectionTimeout, Long keepAliveTime,
Boolean testWhileIdle, Boolean testOnBorrow, Integer isolationLevel, String dsName) {
String validationQuery, Integer isolationLevel) { 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); ConnectionFactory connectionFactory = new DriverManagerConnectionFactory(uri, username, password);
PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, null); PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory, null);
GenericObjectPoolConfig config = createPoolConfig(maxActive, maxIdle, maxWait, timeBtwnEvictionRuns, minEvictableIdleTime, testWhileIdle, testOnBorrow); GenericObjectPoolConfig config = createPoolConfig(maxActive, maxIdle, maxWait, timeBtwnEvictionRuns, minEvictableIdleTime, testWhileIdle, testOnBorrow);
@ -1267,6 +1362,44 @@ public class TransactionLegacy implements Closeable {
return config; 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) { private static String getDBHAParams(String dbName, Properties dbProps) {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
sb.append("failOverReadOnly=" + dbProps.getProperty("db." + dbName + ".failOverReadOnly")); sb.append("failOverReadOnly=" + dbProps.getProperty("db." + dbName + ".failOverReadOnly"));
@ -1278,14 +1411,6 @@ public class TransactionLegacy implements Closeable {
return sb.toString(); 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 * Used for unit testing primarily
* *

View File

@ -32,5 +32,10 @@
<groupId>com.globo.globodns</groupId> <groupId>com.globo.globodns</groupId>
<artifactId>globodns-client</artifactId> <artifactId>globodns-client</artifactId>
</dependency> </dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -47,5 +47,10 @@
<groupId>ch.qos.reload4j</groupId> <groupId>ch.qos.reload4j</groupId>
<artifactId>reload4j</artifactId> <artifactId>reload4j</artifactId>
</dependency> </dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
</project> </project>

13
pom.xml
View File

@ -102,6 +102,7 @@
<cs.configuration.version>1.10</cs.configuration.version> <cs.configuration.version>1.10</cs.configuration.version>
<cs.daemon.version>1.3.3</cs.daemon.version> <cs.daemon.version>1.3.3</cs.daemon.version>
<cs.dbcp.version>2.9.0</cs.dbcp.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.discovery.version>0.5</cs.discovery.version>
<cs.lang.version>2.6</cs.lang.version> <cs.lang.version>2.6</cs.lang.version>
<cs.pool.version>2.9.0</cs.pool.version> <cs.pool.version>2.9.0</cs.pool.version>
@ -364,6 +365,7 @@
<artifactId>commons-daemon</artifactId> <artifactId>commons-daemon</artifactId>
<version>${cs.daemon.version}</version> <version>${cs.daemon.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId> <artifactId>commons-dbcp2</artifactId>
@ -375,6 +377,11 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>${cs.hikaricp.version}</version>
</dependency>
<dependency> <dependency>
<groupId>commons-discovery</groupId> <groupId>commons-discovery</groupId>
<artifactId>commons-discovery</artifactId> <artifactId>commons-discovery</artifactId>
@ -455,6 +462,12 @@
<artifactId>reload4j</artifactId> <artifactId>reload4j</artifactId>
<version>${cs.reload4j.version}</version> <version>${cs.reload4j.version}</version>
</dependency> </dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${cs.mysql.version}</version>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>log4j</groupId> <groupId>log4j</groupId>
<artifactId>apache-log4j-extras</artifactId> <artifactId>apache-log4j-extras</artifactId>

View File

@ -164,6 +164,11 @@
<artifactId>cloud-framework-agent-lb</artifactId> <artifactId>cloud-framework-agent-lb</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-framework-db</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.apache.cloudstack</groupId> <groupId>org.apache.cloudstack</groupId>
<artifactId>cloud-engine-storage-configdrive</artifactId> <artifactId>cloud-engine-storage-configdrive</artifactId>

View File

@ -24,7 +24,11 @@ db.usage.port=3306
db.usage.name=cloud_usage db.usage.name=cloud_usage
# usage database tuning parameters # usage database tuning parameters
db.usage.connectionPoolLib=hikaricp
db.usage.maxActive=100 db.usage.maxActive=100
db.usage.maxIdle=30 db.usage.maxIdle=30
db.usage.maxWait=10000 db.usage.maxWait=10000
db.usage.minIdleConnections=5
db.usage.connectionTimeout=30000
db.usage.keepAliveTime=600000
db.usage.autoReconnect=true db.usage.autoReconnect=true