how does Hikari recycle connections? - java

I please you all for an answer I could not find in the HikariCP doc. Given I set the following pool parameters:
minimumIdle 1
idleTimeout 10 minutes
maxLifeTime 20 minutes
When my app stays idle (with nobody making requests) during the night, I expect Hikari to close each connection 10 minutes after the connection's last request, after the last connection being closed create a new one (and hold it in the pool), and then close and re-create this idle connection every 20 minutes.
Did I understood correctly?
The fact is that after an idle period on my app, I see (uppon the next request) the following exception:
WARN c.z.hikari.proxy.ConnectionProxy - Connection oracle.jdbc.driver.T4CConnection#3c63f80e <POOL_NAME> marked as broken because of SQLSTATE(08003), ErrorCode(17008).
java.sql.SQLRecoverableException: Closed Connection
The connection has probably been closed by Oracle and cannot be used. I'll try to avoid this using the above config. Another point is that I do not understand why I get a closed connection from the pool. This should never happen, as Hikari does test the connection's state before returning it...
Note: I am not the owner of the DB, I cannot configure it or let it be reconfigured to suit my needs. I also have no access to its config.
Our set-up is Spring 4.1.6, Hibernate 4.3.7 with JPA 2.1 API, Hikari 2.1.0

Your understanding of the pool parameters is correct. It is possible that the Oracle instance has a shorter idle timeout than 10 minutes. One thing you can do is to enable DEBUG level logging for the com.zaxxer.hikari package. You'll get a lot more information about what is going on internally within HikariCP, without being too noisy.
Feel free to post the log as an issue on Github and we'll take a look at it.

We face the almost similar issue and resolved it. I reported this issue to HikariCP team. Here is the link: https://github.com/brettwooldridge/HikariCP/issues/683

Related

Can oracle trigger idle timeout error for connection idle for specific time in java

I have created a connection using connection pool in init() method of servlet and and closing / returning the connection in destroy() method. Basically idea is to use single connection for all time and for all users of application. Now my question is , If users are idle for some time say for 15 mins , does oracle trigger any error related to idle timeout (idle timeout is set to 10 mins.)? and if yes how could i prevent the same ?..
Seems like by default there is no any timeouts. See this answer for details. In short, there is no timeouts but you can configure it. Also you can configuration dead connection detection.
But if I'm not mistaken you asking if you have such an opportunity to disable it. In short: you may not do anything and everything will work as you wish. But why? You should configure such idle timeouts and dead connection detection if you don't want some user occasionally hang you application with a single connection.
It was the first point. The other one: actually, you should have a connection pool, not a single connection, in order to serve many requests concurrently.
So sorry, the answer is the following: there is no such timeouts by default but I don't understand you intentions:) Hope this helps.

MySQL connection doesnt close by C3P0

We are using MySQL database along with C3P0ComboPooledDataSource for pooling. Below are the configuration:
minPoolSize=10
maxPoolSize=50
maxStatements=50
idleConnectionTestPeriod=3600
acquireIncrement=5
maxIdleTime=600
numHelperThreads=6
unreturnedConnectionTimeout=3600
maxIdleTimeExcessConnections=600
As per document after maxIdleTime the connection should close automatically, and this happens when we debug locally. But on production server we see the MySQL connection count (show processlist) exceeds more than 50 and they are in sleep mode from last 2400 seconds, ideally which should get closed after 600 seconds.Due to this the application is not able to establish connection through pooled data source as it exceeds maxPoolSize. Please let me know what can be done in order to debug this and how can we resolve it.
This is almost certainly a Connection leak. Please be sure to reliably close your Connections, ideally using something like the try-with-resources.
If you don't understand where your application is not reliably closing Connnections See e.g. C3P0 Spring Hibernate: Pool maxed out. How to debug?

Proper way to keey always alive database connection

I'm working on a backend web server using Mybatis to query MySQL DB.
The web server only has requested in limited (but not fixed) time periods, so nearly every day I will receive the warning log like below.
pooled.PooledDataSource: Execution of ping query 'SELECT 1' failed: The last packet successfully received from the server was 51,861,027 milliseconds ago. The last packet sent successfully to the server was 51,861,027 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem.
autoReconnect=true (Why does autoReconnect=true not seem to work?) looks close to my problem but it's not what I expected.
I'm wondering is that possible to make connections NEVER timeout by ping it when it has been in an idle state for some time (maybe 1 hour).
Since Mybatis are using a connection pool, it's hard to force ping a specified idle connection and make it never timeout.
I've done some search on Google but looks like it's not easy to hack into Mybatis.
My questions are:
Are there any suggestions, references, or alternative libraries for this problem?
Or
Are there reasons that I should not try to keep always alive connections? (potential risks? violate best practices? etc)
Use connection pool manager like C3P0. You will be able to configure permanent connections. It works just like you have described - "pings" connection with example query like SELEC 1 to keep them alive if the connection is idle for some N seconds (thats configurable).
Some guidence here http://gbif.blogspot.com/2011/08/using-c3p0-with-mybatis.html or here http://edwin.baculsoft.com/2012/09/connecting-mybatis-orm-to-c3p0-connection-pooling/. Configuration options of C3P0 can be googled out.
Periodically execute a "select" simply for keeping db connection alive.
When connected to MySQL server default "wait_timeout" is 8 hours(28800 seconds), which means that a connection is idle more than eight hours, Mysql will automatically disconnect the connection. Can be checked using show variables like '%timeout%';
But java connection does not know about this connection being closed from DB side.
To address this issue you have multiple options:
Increase the value of wait_timeout properties. This will for all applications connecting the database and might not be the best solution
set interactive_timeout=432000;
set wait_timeout=432000;
Use connection pool manager like C3P0. It will ping DB using preferredTestQuery after some intervals for you and then you will have permanent connections.

Connection pool expires silently in Tomcat 7 but autoReconnect=true doesn't fix it

I have been getting these exceptions for a number of weeks with no solution...
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:
The last packet successfully received from the server was 179,695,604 milliseconds ago.
The last packet sent successfully to the server was 179,695,604 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem
So I have altered my application's Context.xml to have the autoReconnect=true tag set with my databases for connection pooling in Tomcat 7. I have even set wait_timeout to infinity in the context file.
What am I missing? Is this a common problem? It seems to have a small amount of information around on the net, but when I follow these guides, the same thing happens the next day after a period of inactivity.
The more I use the server, the less this happens. I think it is expiration of the pool connections but how can I stop them expiring if wait_timeout is failing? Any ideas on how to diagnose the problem or config files?
I was facing a similar problem, autoReconnect=true throws the CommunicationsException exception, but then creates a new connection to mysql. So the next request would succeed. This behavior would continue to occur and the first request after an idle time would fail.
To add to what Alex has already answered, I added the following params to my JDBC connection string and I don't see the error any more.
testOnBorrow="true" validationQuery="SELECT 1" validationInterval="60000"
The description of testOnBorrow sufficiently explains it. And the good thing is I do not have to make any changes in my code.
References:
https://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html
http://www.tomcatexpert.com/blog/2010/04/01/configuring-jdbc-pool-high-concurrency
The MySQL Connector/J documentation says about autoReconnect:
If enabled the driver will throw an exception for a queries issued on
a stale or dead connection, which belong to the current transaction,
but will attempt reconnect before the next query issued on the
connection in a new transaction.
Meaning you will still get exceptions.
Connectors such as JDBI get around this by adding optional test queries on idle, borrow from pool and return to pool. Perhaps you could add something to your own JDBC connection wrapper to do the same. Alternatively, follow the documentation for autoReconnect and properly catch SQLExceptions arising from dead/stale connections.
There are further useful references on this answer using DBCP and c3p0

How to mark a connection for eviction from the pool in Tomcat 6

We have an application using an Oracle StoredProc. When the stored proc is upgraded or recompiled from outside of our application, the database connections have to be closed and reopened. Otherwise we get an Oracle Exception ORA-20003.
Until now, we were using a WebLogic specific solution, where we were throwing a specific Exception and the Weblogic connection pool would mark the connection for eviction. We are now moving to Tomcat 6.
Is there a similar solution for Tomcat 6 ? Or even better, a generic solution ?
We could configure our connection pool with minIdle=0 and timeBetweenEvictionRunsMillis=some small number, but there still would be no garantie, only a mitigation of the problem.
Thanks for your help !
Can you come up with a SELECT statement that would validate whether the connection is up to date? If so, you could use it to configure the connection pool with validationQuery (potentially combined with connectionInitSqls).
Edit: Perhaps USER_OBJECTS.LAST_DDL_TIME can be of some help?

Categories