DaanHoogland closed pull request #2603: WIP: Connection pool replacement -
HikariCP attempt
URL: https://github.com/apache/cloudstack/pull/2603
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/client/conf/db.properties.in b/client/conf/db.properties.in
index 2f1dcf0d6b8..8830fa1cc8e 100644
--- a/client/conf/db.properties.in
+++ b/client/conf/db.properties.in
@@ -101,3 +101,6 @@ db.usage.autoReconnectForPools=true
db.usage.secondsBeforeRetryMaster=3600
db.usage.queriesBeforeRetryMaster=5000
db.usage.initialTimeout=3600
+
+# Connection Pool - Valid options: dbcp, hikari
+db.cloud.connPool=hikari
diff --git a/framework/db/pom.xml b/framework/db/pom.xml
index 6483f4f9b03..4ecac996a95 100644
--- a/framework/db/pom.xml
+++ b/framework/db/pom.xml
@@ -19,6 +19,11 @@
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
+ <dependency>
+ <groupId>com.zaxxer</groupId>
+ <artifactId>HikariCP</artifactId>
+ <version>2.7.8</version>
+ </dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
diff --git a/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java
b/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java
index 442d3cc181d..d292357e1ff 100644
--- a/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java
+++ b/framework/db/src/main/java/com/cloud/utils/db/GenericDaoBase.java
@@ -31,6 +31,7 @@
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
+import java.sql.Connection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
@@ -388,6 +389,7 @@ public T lockOneRandomRow(final SearchCriteria<T> sc, final
boolean exclusive) {
addFilter(str, filter);
final TransactionLegacy txn = TransactionLegacy.currentTxn();
+
if (lock != null) {
assert (txn.dbTxnStarted() == true) : "As nice as I can here
now....how do you lock when there's no DB transaction? Review your db 101
course from college.";
str.append(lock ? FOR_UPDATE_CLAUSE : SHARE_MODE_CLAUSE);
@@ -398,6 +400,8 @@ public T lockOneRandomRow(final SearchCriteria<T> sc, final
boolean exclusive) {
PreparedStatement pstmt = null;
final List<T> result = new ArrayList<T>();
try {
+ Connection currentConnection = txn.getCurrentConnection();
+ s_logger.info("Connection: " + (currentConnection.isClosed() ?
"closed" : "open"));
pstmt = txn.prepareAutoCloseStatement(sql);
int i = 1;
if (clause != null) {
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 6a422d30fc3..999b175f3cf 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
@@ -33,6 +33,8 @@
import javax.sql.DataSource;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
@@ -426,9 +428,6 @@ public void start() {
protected void closePreviousStatement() {
if (_stmt != null) {
try {
- if (s_stmtLogger.isTraceEnabled()) {
- s_stmtLogger.trace("Closing: " + _stmt.toString());
- }
try {
ResultSet rs = _stmt.getResultSet();
if (rs != null && _stmt.getResultSetHoldability() !=
ResultSet.HOLD_CURSORS_OVER_COMMIT) {
@@ -1062,6 +1061,7 @@ public static void initDataSource(Properties dbProps) {
final long cloudMinEvcitableIdleTimeMillis =
Long.parseLong(dbProps.getProperty("db.cloud.minEvictableIdleTimeMillis"));
final boolean cloudPoolPreparedStatements =
Boolean.parseBoolean(dbProps.getProperty("db.cloud.poolPreparedStatements"));
final String url = dbProps.getProperty("db.cloud.url.params");
+ final String connPool = dbProps.getProperty("db.cloud.connPool");
String cloudDbHAParams = null;
String cloudSlaves = null;
@@ -1088,6 +1088,55 @@ public static void initDataSource(Properties dbProps) {
(s_dbHAEnabled ? "&" + cloudDbHAParams : "") +
(s_dbHAEnabled ? "&loadBalanceStrategy=" + loadBalanceStrategy : "");
DriverLoader.loadDriver(cloudDriver);
+ if (connPool.equalsIgnoreCase("hikari")) {
+ HikariConfig hikariConfig = new HikariConfig();
+ hikariConfig.setJdbcUrl(cloudConnectionUri);
+ hikariConfig.setUsername(cloudUsername);
+ hikariConfig.setPassword(cloudPassword);
+ hikariConfig.addDataSourceProperty("cachePrepStmts", "true");
+ hikariConfig.addDataSourceProperty("prepStmtCacheSize", "250");
+ hikariConfig.addDataSourceProperty("prepStmtCacheSqlLimit",
"2048");
+ hikariConfig.setMinimumIdle(100);
+ hikariConfig.setMaximumPoolSize(200);
+ hikariConfig.setAutoCommit(false);
+
+ s_ds = new HikariDataSource(hikariConfig);
+
+ // 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 String usageUsername =
dbProps.getProperty("db.usage.username");
+ final String usagePassword =
dbProps.getProperty("db.usage.password");
+ final String usageHost = dbProps.getProperty("db.usage.host");
+ final String usageDriver =
dbProps.getProperty("db.usage.driver");
+ final int usagePort =
Integer.parseInt(dbProps.getProperty("db.usage.port"));
+ final String usageDbName =
dbProps.getProperty("db.usage.name");
+ final boolean usageAutoReconnect =
Boolean.parseBoolean(dbProps.getProperty("db.usage.autoReconnect"));
+ final String usageUrl =
dbProps.getProperty("db.usage.url.params");
+
+ final GenericObjectPool usageConnectionPool =
+ new GenericObjectPool(null, usageMaxActive,
GenericObjectPool.DEFAULT_WHEN_EXHAUSTED_ACTION, usageMaxWait, usageMaxIdle);
+
+ final String usageConnectionUri = usageDriver + "://" +
usageHost + (s_dbHAEnabled ? "," + dbProps.getProperty("db.cloud.slaves") : "")
+ ":" + usagePort +
+ "/" + usageDbName + "?autoReconnect=" +
usageAutoReconnect + (usageUrl != null ? "&" + usageUrl : "") +
+ (s_dbHAEnabled ? "&" + getDBHAParams("usage", dbProps)
: "") + (s_dbHAEnabled ? "&loadBalanceStrategy=" + loadBalanceStrategy : "");
+ DriverLoader.loadDriver(usageDriver);
+
+ HikariConfig hikariConfigUsage = new HikariConfig();
+ hikariConfigUsage.setJdbcUrl(usageConnectionUri);
+ hikariConfigUsage.setUsername(usageUsername);
+ hikariConfigUsage.setPassword(usagePassword);
+ hikariConfigUsage.addDataSourceProperty("cachePrepStmts",
"true");
+ hikariConfigUsage.addDataSourceProperty("prepStmtCacheSize",
"250");
+
hikariConfigUsage.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
+ hikariConfigUsage.setIdleTimeout(600000l);
+ hikariConfigUsage.setMinimumIdle(5);
+ s_usageDS = new HikariDataSource(hikariConfigUsage);
+ return;
+
+ }
+
final ConnectionFactory cloudConnectionFactory = new
DriverManagerConnectionFactory(cloudConnectionUri, cloudUsername,
cloudPassword);
final KeyedObjectPoolFactory poolableObjFactory =
(cloudPoolPreparedStatements ? new StackKeyedObjectPoolFactory() : null);
diff --git
a/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java
b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java
index e81ab1ebbf7..cd52201c7e5 100644
---
a/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java
+++
b/framework/jobs/src/main/java/org/apache/cloudstack/framework/jobs/dao/VmWorkJobDaoImpl.java
@@ -16,6 +16,7 @@
// under the License.
package org.apache.cloudstack.framework.jobs.dao;
+import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Date;
@@ -161,19 +162,19 @@ public void expungeLeftoverWorkJobs(final long msid) {
sc.setParameters("msid", msid);
expunge(sc);
- */
+*/
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status)
{
TransactionLegacy txn = TransactionLegacy.currentTxn();
- try (
- PreparedStatement pstmt = txn
- .prepareAutoCloseStatement(
- "DELETE FROM vm_work_job WHERE id IN (SELECT id
FROM async_job WHERE (job_dispatcher='VmWorkJobPlaceHolder' OR
job_dispatcher='VmWorkJobDispatcher') AND job_init_msid=?)");
- ) {
+ try {
+ PreparedStatement pstmt = txn
+ .prepareAutoCloseStatement(
+ "DELETE FROM vm_work_job WHERE id IN
(SELECT id FROM async_job WHERE (job_dispatcher='VmWorkJobPlaceHolder' OR
job_dispatcher='VmWorkJobDispatcher') AND job_init_msid=?)");
+ Connection currentConnection = txn.getCurrentConnection();
+ s_logger.info("Connection: " +
(currentConnection.isClosed() ? "closed" : "open"));
pstmt.setLong(1, msid);
-
pstmt.execute();
} catch (SQLException e) {
s_logger.info("[ignored]"
@@ -183,12 +184,12 @@ public void
doInTransactionWithoutResult(TransactionStatus status) {
+ "caught an error during delete vm work job: " +
e.getLocalizedMessage());
}
- try (
- PreparedStatement pstmt =
txn.prepareAutoCloseStatement(
+ try {
+ PreparedStatement pstmt = txn.prepareAutoCloseStatement(
"DELETE FROM async_job WHERE
(job_dispatcher='VmWorkJobPlaceHolder' OR job_dispatcher='VmWorkJobDispatcher')
AND job_init_msid=?");
- ) {
+ Connection currentConnection = txn.getCurrentConnection();
+ s_logger.info("Connection: " +
(currentConnection.isClosed() ? "closed" : "open"));
pstmt.setLong(1, msid);
-
pstmt.execute();
} catch (SQLException e) {
s_logger.info("[ignored]"
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
[email protected]
With regards,
Apache Git Services