Zombie Connections to MySQL using c3p0 with tomcat

2019-04-02 04:40发布

问题:

I'm using c3p0 to manage my Database Connections to MySQL. The problem is that some connections are being hold forever. I have a limit of 1000 connections, but for some unknown reason, there are 1200 open connections. To investigate it, I do this command in the tomcat server shell:

netstat -n |grep 3306|grep ESTABILISHED|wc -l

and it returns 1200

here is the c3p0 configuration in context.xml

 <Resource name="jdbc/xxxx" auth="Container"
          user="xxxxxx"
          password="xxxxx"
          driverClass="com.mysql.jdbc.Driver"
          jdbcUrl ="jdbc:mysql://xxxx:3306/xxx"
          factory="org.apache.naming.factory.BeanFactory"
          type="com.mchange.v2.c3p0.ComboPooledDataSource"
          maxPoolSize="1000"
          minPoolSize="200"
          numHelperThreads="10"
          acquireIncrement="50"
          maxStatementsPerConnection="0"
          idleConnectionTestPeriod="200"
          maxIdleTime = "1000"
          maxIdleTimeExcessConnections = "180"
          maxStatements="200"
          unreturnedConnectionTimeout="10"
          debugUnreturnedConnectionStackTraces="true"
          />

How is it possible to have 1200 established connections if the pool max size is 1000? My MySQL server is configured with

interactive_timeout 28800
wait_timeout    1300

OBS: I'm not using hibernate in this application (just in a few classes). Most of the connections are made via pure JDBC code.

回答1:

There are a couple of possibilities.

The most likely is that you have placed this Resource element in $CATALINA_BASE/conf/context.xml That file provides the default context.xml for every web application. Therefore, if you have six web applications you will have six connection pools. Since the minimum poll size is 200, there will be a minimum of 200*6=1200 connections opened to the database.

The other possibility is that the web application has been reloaded. You should get a new connection pool and the old one will be GC'd. However, if you have a memory leak on reload (very easy to do without realising) it may keep the connection pool, along with its open connections, in memory increasing your total connections.

To put the definitions in server.xml:

<Server>
  <GlobalNamingResources>
     <Resource name="jdbc/xxxx">...</Resource>
  </GlobalNamingResources>
</Server>

and this in context.xml:

  <ResourceLink name="jdbc/xxxx"
      global="jdbc/xxxx"
      type="com.mchange.v2.c3p0.ComboPooledDataSource" />