mirror of
https://github.com/alibaba/druid.git
synced 2023-03-04 19:17:16 +00:00
bug fixed sql runningCount & add statLog support
This commit is contained in:
@@ -119,6 +119,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
// threads
|
||||
private CreateConnectionThread createConnectionThread;
|
||||
private DestroyConnectionThread destoryConnectionThread;
|
||||
private LogStatsThread logStatsThread;
|
||||
|
||||
private final CountDownLatch initedLatch = new CountDownLatch(2);
|
||||
|
||||
@@ -131,7 +132,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
private volatile boolean closed = false;
|
||||
private long closeTimeMillis = -1L;
|
||||
|
||||
private JdbcDataSourceStat dataSourceStat;
|
||||
protected JdbcDataSourceStat dataSourceStat;
|
||||
|
||||
private boolean useGloalDataSourceStat = false;
|
||||
|
||||
@@ -436,6 +437,10 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
+ maxActive);
|
||||
}
|
||||
|
||||
if (timeBetweenLogStatsMillis > 0 && useGloalDataSourceStat) {
|
||||
throw new IllegalArgumentException("timeBetweenLogStatsMillis not support useGloalDataSourceStat=true");
|
||||
}
|
||||
|
||||
if (this.driverClass != null) {
|
||||
this.driverClass = driverClass.trim();
|
||||
}
|
||||
@@ -492,7 +497,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
SQLException connectError = null;
|
||||
|
||||
try {
|
||||
// 初始化连接
|
||||
// init connections
|
||||
for (int i = 0, size = getInitialSize(); i < size; ++i) {
|
||||
Connection conn = createPhysicalConnection();
|
||||
DruidConnectionHolder holder = new DruidConnectionHolder(this, conn);
|
||||
@@ -508,6 +513,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
connectError = ex;
|
||||
}
|
||||
|
||||
createAndLogThread();
|
||||
createAndStartCreatorThread();
|
||||
createAndStartDestroyThread();
|
||||
|
||||
@@ -535,6 +541,16 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
}
|
||||
}
|
||||
|
||||
private void createAndLogThread() {
|
||||
if (this.timeBetweenLogStatsMillis <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
String threadName = "Druid-ConnectionPool-Log-" + System.identityHashCode(this);
|
||||
logStatsThread = new LogStatsThread(threadName);
|
||||
logStatsThread.start();
|
||||
}
|
||||
|
||||
private void createAndStartDestroyThread() {
|
||||
String threadName = "Druid-ConnectionPool-Destory-" + System.identityHashCode(this);
|
||||
destoryConnectionThread = new DestroyConnectionThread(threadName);
|
||||
@@ -1047,7 +1063,7 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
recycleErrorCount.incrementAndGet();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public long getRecycleErrorCount() {
|
||||
return recycleErrorCount.get();
|
||||
}
|
||||
@@ -1078,6 +1094,10 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
return;
|
||||
}
|
||||
|
||||
if (logStatsThread != null) {
|
||||
logStatsThread.interrupt();
|
||||
}
|
||||
|
||||
if (createConnectionThread != null) {
|
||||
createConnectionThread.interrupt();
|
||||
}
|
||||
@@ -1236,13 +1256,13 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
@Override
|
||||
public Connection getConnection(String username, String password) throws SQLException {
|
||||
if (!StringUtils.equals(username, this.username)) {
|
||||
throw new UnsupportedOperationException("Not supported by DruidDataSource");
|
||||
throw new UnsupportedOperationException("Not supported by DruidDataSource");
|
||||
}
|
||||
|
||||
|
||||
if (!StringUtils.equals(password, this.password)) {
|
||||
throw new UnsupportedOperationException("Not supported by DruidDataSource");
|
||||
throw new UnsupportedOperationException("Not supported by DruidDataSource");
|
||||
}
|
||||
|
||||
|
||||
return getConnection();
|
||||
}
|
||||
|
||||
@@ -1311,6 +1331,103 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
}
|
||||
}
|
||||
|
||||
public void logStats() {
|
||||
final DruidDataSourceStatLogger statLogger = this.statLogger;
|
||||
if (statLogger == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
DruidDataSourceStatValue statValue = getStatValueAndReset();
|
||||
|
||||
statLogger.log(statValue);
|
||||
}
|
||||
|
||||
public DruidDataSourceStatValue getStatValueAndReset() {
|
||||
DruidDataSourceStatValue value = new DruidDataSourceStatValue();
|
||||
|
||||
lock.lock();
|
||||
try {
|
||||
value.poolingCount = this.poolingCount;
|
||||
value.poolingPeak = this.poolingPeak;
|
||||
value.poolingPeakTime = this.poolingPeakTime;
|
||||
|
||||
value.activeCount = this.activeCount;
|
||||
value.activePeak = this.activePeak;
|
||||
value.activePeakTime = this.activePeakTime;
|
||||
|
||||
value.connectCount = this.connectCount;
|
||||
value.closeCount = this.closeCount;
|
||||
value.waitThreadCount = lock.getWaitQueueLength(notEmpty);
|
||||
value.notEmptyWaitCount = this.notEmptyWaitCount;
|
||||
value.notEmptyWaitNanos = this.notEmptyWaitNanos;
|
||||
|
||||
// reset
|
||||
this.poolingPeak = 0;
|
||||
this.poolingPeakTime = 0;
|
||||
this.activePeak = 0;
|
||||
this.activePeakTime = 0;
|
||||
this.connectCount = 0;
|
||||
this.closeCount = 0;
|
||||
|
||||
this.notEmptyWaitCount = 0;
|
||||
this.notEmptyWaitNanos = 0;
|
||||
} finally {
|
||||
lock.unlock();
|
||||
}
|
||||
|
||||
value.name = this.getName();
|
||||
value.dbType = this.getDbType();
|
||||
value.driverClassName = this.getDriverClassName();
|
||||
|
||||
value.url = this.getUrl();
|
||||
value.userName = this.getUsername();
|
||||
value.filterClassNames = this.getFilterClassNames();
|
||||
|
||||
value.initialSize = this.getInitialSize();
|
||||
value.minIdle = this.getMinIdle();
|
||||
value.maxActive = this.getMaxActive();
|
||||
|
||||
value.queryTimeout = this.getQueryTimeout();
|
||||
value.transactionQueryTimeout = this.getTransactionQueryTimeout();
|
||||
value.loginTimeout = this.getLoginTimeout();
|
||||
value.validConnectionCheckerClassName = this.getValidConnectionCheckerClassName();
|
||||
value.exceptionSorterClassName = this.getExceptionSorterClassName();
|
||||
|
||||
value.testOnBorrow = this.isTestOnBorrow();
|
||||
value.testOnReturn = this.isTestOnReturn();
|
||||
value.testWhileIdle = this.isTestWhileIdle();
|
||||
|
||||
value.defaultAutoCommit = this.isDefaultAutoCommit();
|
||||
value.defaultReadOnly = this.isDefaultAutoCommit();
|
||||
value.defaultTransactionIsolation = this.getDefaultTransactionIsolation();
|
||||
|
||||
value.logicConnectErrorCount = connectErrorCount.getAndSet(0);
|
||||
|
||||
value.physicalConnectCount = createCount.getAndSet(0);
|
||||
value.physicalCloseCount = destroyCount.getAndSet(0);
|
||||
value.physicalConnectErrorCount = createErrorCount.getAndSet(0);
|
||||
|
||||
value.executeCount = this.executeCount.getAndSet(0);
|
||||
value.errorCount = errorCount.getAndSet(0);
|
||||
value.commitCount = commitCount.getAndSet(0);
|
||||
value.rollbackCount = rollbackCount.getAndSet(0);
|
||||
|
||||
value.PSCacheHitCount = cachedPreparedStatementHitCount.getAndSet(0);
|
||||
value.PSCacheMissCount = cachedPreparedStatementMissCount.getAndSet(0);
|
||||
|
||||
value.startTransactionCount = startTransactionCount.getAndSet(0);
|
||||
value.transactionHistogram = this.getTransactionHistogram().toArrayAndReset();
|
||||
|
||||
value.connectionHoldTimeHistogram = this.getDataSourceStat().getConnectionHoldHistogram().toArrayAndReset();
|
||||
value.removeAbandoned = this.isRemoveAbandoned();
|
||||
value.clobOpenCount = this.getDataSourceStat().getClobOpenCountAndReset();
|
||||
value.blobOpenCount = this.getDataSourceStat().getBlobOpenCountAndReset();
|
||||
|
||||
value.sqlList = this.getDataSourceStat().getSqlStatMapAndReset();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
public long getRemoveAbandonedCount() {
|
||||
return removeAbandonedCount;
|
||||
}
|
||||
@@ -1454,6 +1571,30 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
|
||||
|
||||
}
|
||||
|
||||
public class LogStatsThread extends Thread {
|
||||
|
||||
public LogStatsThread(String name){
|
||||
super(name);
|
||||
this.setDaemon(true);
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
for (;;) {
|
||||
try {
|
||||
logStats();
|
||||
} catch (Exception e) {
|
||||
LOG.error("logStats error", e);
|
||||
}
|
||||
|
||||
Thread.sleep(timeBetweenLogStatsMillis);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
// skip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int removeAbandoned() {
|
||||
int removeCount = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user