Druid connection pool setting triggers a blood case [abandon connection, open stackTrace]

Keywords: Programming Java Druid JDBC SQL

Running batch updates on a very low-configuration machine today~~~

Running for about 30 minutes ~~This configuration ~~This program~~~

And then the magnificent newspaper went off the beaten track.~~~

This is the specific exception.

DEBUG: (BaseJdbcLogger.java:132)    ooo Using Connection [com.alibaba.druid.proxy.jdbc.ConnectionProxyImpl@4d4e22e1]

[2014-07-17 15:19:35]5363945354 [Druid-ConnectionPool-Destory-1422598563] com.alibaba.druid.pool.DruidDataSource:1132 

WARN : (DruidDataSource.java:1132)   get/close not same thread

 

ERROR: (DruidDataSource.java:1815)   abandon connection, open stackTrace

        at java.lang.Thread.getStackTrace(Thread.java:1588)

    at com.alibaba.druid.pool.DruidDataSource.getConnectionDirect(DruidDataSource.java:942)

    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4534)

    at com.alibaba.druid.filter.stat.StatFilter.dataSource_getConnection(StatFilter.java:661)

    at com.alibaba.druid.filter.FilterChainImpl.dataSource_connect(FilterChainImpl.java:4530)

    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:880)

    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:872)

    at com.alibaba.druid.pool.DruidDataSource.getConnection(DruidDataSource.java:97)

This is the initial anomaly, followed by One big Batch exception

Caused by: java.sql.SQLException: connection holder is null

    at com.alibaba.druid.pool.DruidPooledConnection.checkState(DruidPooledConnection.java:1085)

    at com.alibaba.druid.pool.DruidPooledConnection.getMetaData(DruidPooledConnection.java:825)

    at org.springframework.jdbc.support.JdbcUtils.extractDatabaseMetaData(JdbcUtils.java:285)

    ... 70 more

Say holder is empty

The first sight of holder is like the source code to Spring, which is full of holders (laughter).

But the holder here is not in Spirng, it's Druid.

This holder is probably used to hou the connection in the connection pool.

Then why is it empty? Visually, which link is broken or unexpectedly shut down ____________

According to the abnormal source code at com.alibaba.druid.pool.DruidDataSource.getConnection Direct (DruidDataSource.java:942)

if (isRemoveAbandoned()) {

              StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();

              poolalbeConnection.setConnectStackTrace(stackTrace);

              poolalbeConnection.setConnectedTimeNano();

              poolalbeConnection.setTraceEnable(true);

 

              synchronized (activeConnections) {

                  activeConnections.put(poolalbeConnection, PRESENT);

              }

         }

You can't see anything. You can only keep looking at the log, or you can't see anything.

After looking at the above code several times, I always feel that isRemoveAbandoned() is a ghost method.

Look at the caller.

 

Well, this Destroy Connection Thread is very suspicious, jump.

if (isRemoveAbandoned()) {

   removeAbandoned();

}
public int removeAbandoned() {

        int removeCount = 0;

 

        long currrentNanos = System.nanoTime();

 

        List<DruidPooledConnection> abandonedList = new ArrayList<DruidPooledConnection>();

 

        synchronized (activeConnections) {

            Iterator<DruidPooledConnection> iter = activeConnections.keySet().iterator();

 

            for (; iter.hasNext();) {

                DruidPooledConnection pooledConnection = iter.next();

 

                if (pooledConnection.isRunning()) {

                    continue;

                }

 

                long timeMillis = (currrentNanos - pooledConnection.getConnectedTimeNano()) / (1000 * 1000);

 

                if (timeMillis >= removeAbandonedTimeoutMillis) {

                    iter.remove();

                    pooledConnection.setTraceEnable(false);

                    abandonedList.add(pooledConnection);

                }

            }

        } ....slightly

    }

Erase, it's not right here, = removeAbandoned Timeout Millis timeMillis This is the time when getConnection() was called.

It means that after a connection is got, I'll kill you for so long after it's over removeAbandoned Timeout Millis.

Then continue looking for removeAbandoned Timeout Millis where it was set up, and finally find out that

<property name="removeAbandoned" value="true" />

<property name="removeAbandonedTimeout" value="1800" />

The initialization configuration is set here, and the two parameters roughly mean that,

Connections made through datasource.getConnontion() must call close() within so many seconds of removeAbandonedTimeout, or I'll kill you. (That is, conn can't exceed the specified lease period)

Then set it to two hours.~~~

Then the program successfully ran through ~~gorgeous wait for 50 minutes

Summary:

In order to prevent the program from forgetting to return the connection from the pool, connection pool provides some parameters to set a lease period, which can prevent connection leakage to some extent.

But if your business really needs to run for so long, pay attention to this setup.

Posted by Wo0tHigh on Tue, 19 Mar 2019 19:09:27 -0700