diff --git a/client/conf/db.properties.in b/client/conf/db.properties.in index 2f1dcf0d6b84..8830fa1cc8e2 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 6483f4f9b037..4ecac996a956 100644 --- a/framework/db/pom.xml +++ b/framework/db/pom.xml @@ -19,6 +19,11 @@ ../pom.xml + + com.zaxxer + HikariCP + 2.7.8 + net.sf.ehcache ehcache-core 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 442d3cc181da..d292357e1ff3 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 List searchIncludingRemoved(SearchCriteria sc, final Filter filter, 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 List searchIncludingRemoved(SearchCriteria sc, final Filter filter, PreparedStatement pstmt = null; final List result = new ArrayList(); 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 6a422d30fc36..999b175f3cfd 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 e81ab1ebbf78..cd52201c7e54 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]"