On 12/8/21 6:36 AM, Christopher Schultz wrote:
Jerry,
On 12/7/21 20:59, Jerry Malcolm wrote:
Chris, The way I thought it worked was if I configured
'RemoveAbandonedOnBorrow' and RemoveAbandonedTimeout="15" was that
each time I requested a new connection from the pool, any connections
that had been idle for >15 minutes and had not been returned by my
code to the pool would be recovered, returned to the pool and logged
(assuming logAbandoned was set).
Nope. "removeAbandoned" causes any connection that isn't returned to
the pool to be *removed from the pool*, and replaced with a new
(presumably working) connection. The connection that was never
returned ... stays out there, doing whatever it was doing.
Not exactly. Abandoned connection cleanup does try to physically close
connections [1] that are deemed abandoned. It creates capacity to
create new ones but it does not create them immediately.
"logAbandoned" just lets you know when the pool gives up. It doesn't
"do" anything (other than the logging).
The alternative would be for the pool to forcibly terminate the
connection, which could cause all kinds of chaos, so it does the only
thing it can reasonably do: forget the connection ever existed in the
first place. If your code never closes it, and the Connection object
never gets GC'd (and, presumably, closed in the process), then it just
lived forever, wasting an open-connection to your db. Since you have
limited your total connections (per user? per host?) you eventually
run out due to the leak.
This is why you need to be careful to set the abandoned timeout long
enough so that "chaos" does not ensue. The pool tries to physically
close abandoned connections when this is configured to happen. If
clients retain handles to them and later try to use them, they will get
exceptions. You can see this confirmed in DBCP's
TestAbandonedBasicDataSource unit tests.
Until a few days ago I had a code error that was bypassing the
closing of the connection in certain situations, and after 12-24
hours the pool had worked its way up to maxing out. My problem is
fixed now, and the numActive count is staying fairly flat during
normal activity. But the way I understood removeAbandonedOnBorrow
was that TC connection pooling code would not allow errant
connections to remain in use forever.
I'm sure I'm just misunderstanding how it works. Again, not critical
at this moment. But I'd like to figure out where my understanding is
wrong for future situations.
I think that the reason that you did not see connections closed by the
pool may have been that you did not get close enough to the maxTotal
setting (see other response above) or you had idle connections in the
pool as it was leaking and you did not have
timeBetweenEvictionRunsMillis set. If you set
timeBetweenEvictionRunsMillis to a positive value, that will trigger
unconditional removal when it runs (i.e., it does not check how close
the pool is to maxTotal or how many idle connections there are). The
removeAbandonedOnBorrow setting is really more of a liveness than a
cleanup feature - basically trying to keep the pool ahead of demand by
cleaning up when it is exhausted or close to it.
Phil
[1] As of DBCP 2.9.0, abort is used in place of close. See
https://issues.apache.org/jira/browse/DBCP-567
You thought the pool would "clean-up" the mess. IT doesn't. What it
*does* do is allow the pool to continue to function and provide its
service to the application, even when the application is leaking
connections.
So, rather than starving clients when connections leak, those
connections are simply allowed to leak.
I always recommend running with maxActive="1" in development, with
removeAbandoned="false" and logAbandoned="true". You'll find any leaks
VERY quickly. ;)
-chris
On 12/7/2021 2:31 PM, Christopher Schultz wrote:
Jerry,
On 12/4/21 23:06, Jerry Malcolm wrote:
I had a db connection leak in my code where an error condition
would throw an exception and bypass the connection cleanup code. I
found that and fixed it. But before I found the problem, my
program was overrunning the max connections and locking out. It
would take sometimes 12 hours after a reboot to go from 0
connections to max. Normal steady state connections should
currently be under 50. The ramp over several hours to max was very
obvious in my numActive log. What I'm confused about is why
removeAbandoned didn't recover those connections.
When you say "recover"... what exactly do you mean?
Granted, if I write my code correctly, removeAbandoned shouldn't be
necessary. The coding problem is solved now. But apparently my
understanding/configuration of removeAbandoned is not correct.
Possibly, but you didn't state your expectations.
I'd like to have that figured out in case there's a next time
(which sadly there probably will be....). Basically, with the
configuration below, I'm not getting any idle connections detected
and returned. This is TC 8.5.73. And the leak was happening on a
basic request/response (no threads involved). I requested the
connection, encountered an error, and returned without closing the
connection. Ideas? Thx.
-chris
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org
For additional commands, e-mail: users-h...@tomcat.apache.org