Bug #40036 Connector "lost" pooled connections.
Submitted: 15 Oct 2008 6:25 Modified: 30 Nov 2009 15:46
Reporter: Moshe Lampert Email Updates:
Status: Duplicate Impact on me:
None 
Category:Connector / NET Severity:S2 (Serious)
Version:6.0.3 OS:Any
Assigned to: CPU Architecture:Any
Tags: NET, pooling

[15 Oct 2008 6:25] Moshe Lampert
Description:
I am using mysql last connector with mysql 5.0.20 @ debian. two Windows/IIS servers whith 2 similar websites.

all connections closed with Conn.close / Conn.dispose

when I enabled pooling (pooling=true;Connection Lifetime=10;), I see after a while a "sleep" connections for long time.

after a half an hour - I recived error:
System.InvalidOperationException: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached. 

I can kill the sleeped connections but it doesn't help. when I recycled App Pool - all connections closed and it's leaks connections again (slowly but safely).

When I disabled pooling - all works, but the polling make all website faster.

Windows 2003, IIS6, ASP.net 2

How to repeat:
some heavy website (100 asp.net requests/sec) with pooling=true.
[15 Oct 2008 6:30] Moshe Lampert
(fix a mistake)
[21 Oct 2008 15:53] Tonci Grgin
Hello Moshe and thanks for your report. I am puzzled as to what do you expect from me now? To build-up "heavy" web site and test? If not then there must be a test case but I don't see it attached.

However, I feel this needs some investigation but don't know where to start...
[21 Oct 2008 17:28] Moshe Lampert
My testcase is super-simple.

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
	Dim Conn As New MySqlConnection("server=localhost;user id=root; password=...; database=...; pooling=true;")
		Conn.Open()
[21 Oct 2008 17:30] Moshe Lampert
(sorry, 'enter' pressed)

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles
Me.Load
	Dim Conn As New MySqlConnection("server=localhost;user id=root; password=...;
database=...; pooling=true;")
	Conn.Open()

	Dim Cmd As New MySqlCommand("select * from homepage", Conn)
	Dim oReader As MySqlDataReader = Cmd.ExecuteReader()
	While oReader.Read
		' do something / do nothing
	End While
	oReader.Close()
	Cmd.Dispose()
	Conn.Close()
	Conn.Dispose()
End Sub
[21 Oct 2008 17:30] Moshe Lampert
(sorry, 'enter' pressed)

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles
Me.Load
	Dim Conn As New MySqlConnection("server=localhost;user id=root; password=...;
database=...; pooling=true;")
	Conn.Open()

	Dim Cmd As New MySqlCommand("select * from homepage", Conn)
	Dim oReader As MySqlDataReader = Cmd.ExecuteReader()
	While oReader.Read
		' do something / do nothing
	End While
	oReader.Close()
	Cmd.Dispose()
	Conn.Close()
	Conn.Dispose()
End Sub
[21 Oct 2008 17:30] Moshe Lampert
(sorry, 'enter' pressed)

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles
Me.Load
	Dim Conn As New MySqlConnection("server=localhost;user id=root; password=...;
database=...; pooling=true;")
	Conn.Open()

	Dim Cmd As New MySqlCommand("select * from homepage", Conn)
	Dim oReader As MySqlDataReader = Cmd.ExecuteReader()
	While oReader.Read
		' do something / do nothing
	End While
	oReader.Close()
	Cmd.Dispose()
	Conn.Close()
	Conn.Dispose()
End Sub
[21 Oct 2008 17:34] Moshe Lampert
sleeped connections

Attachment: Untitled.gif (image/gif, text), 21.71 KiB.

[21 Oct 2008 17:35] Moshe Lampert
(Sorry, 'enter' pressed - my keyboard need to replaced!)

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles
Me.Load
	Dim Conn As New MySqlConnection("server=localhost;user id=root; password=...;
database=...; pooling=true;")
	Conn.Open()

	Dim Cmd As New MySqlCommand("select * from homepage", Conn)
	Dim oReader As MySqlDataReader = Cmd.ExecuteReader()
	While oReader.Read
		' do something / do nothing
	End While
	oReader.Close()
	Cmd.Dispose()
	Conn.Close()
	Conn.Dispose()
End Sub

I'm used Microsoft's Web Applications Stress Tool to make a 100 requests/sec and after a while I get this:
[12 Nov 2008 17:33] Moshe Lampert
after a some weeks of testing (Windows 2003 - IIS6, Windows Vista - IIS7), my conclusion is that connection get re-used 20-30 times (with 1-2 secs) and after a while "losted".

when I set  "Connection Lifetime" to 1 sec, I see much less losted connections.

show full processlist (lifetime=10) result:
1040, 'a7', 'localhost:57158', 'a7new', 'Sleep', 226, '', ''
1041, 'a7', 'localhost:57164', 'a7new', 'Sleep', 203, '', ''
1042, 'a7', 'localhost:57177', 'a7new', 'Sleep', 183, '', ''
1044, 'a7', 'localhost:57188', 'a7new', 'Sleep', 126, '', ''
1045, 'a7', 'localhost:57220', 'a7new', 'Sleep', 103, '', ''
1046, 'a7', 'localhost:57222', 'a7new', 'Sleep', 83, '', ''
1048, 'a7', 'localhost:57248', 'a7new', 'Sleep', 26, '', ''
1049, 'a7', 'localhost:57258', 'a7new', 'Sleep', 3, '', ''
1050, 'a7', 'localhost:57259', 'a7new', 'Sleep', 3, '', ''
1051, 'root', 'localhost:57260', 'a7new', 'Query', 0, '', 'show full processlist'
[18 Feb 2009 10:34] Tonci Grgin
Moshe, I think the problem is in IIS pooling. Can you please try and shut it down (again, not c/NET but IIS pooling) and retest as IIS is partly responsible for pooling mechanisms and I want to check if it does not release connections from pool properly.
Again, probably stale connections are not released from pool by IIS and/or you are not checking them before reuse and/or pool can not accommodate such high traffic and/or MySQL server is configured so that it can't give you requested number of connections (you should be able to find out which scenario is in effect with netstat and "show processlist") .
[18 Feb 2009 11:04] Bogdan Degtyariov
Moshe,

If your web server is heavily loaded you should consider increasing the "max pool size" connection string parameter, which is 100 by default. For the environments with medium and low database activity the default value is ok, but in your case the pool can exhaust too quickly.
Thanks.
[18 Feb 2009 12:11] Moshe Lampert
IIS pooling/webgarden disabled.

Max pool size is not the problem in this server (without pooling, show full processlist shows 10-12).
I think the problem is in the connector itself, while connections still opened when "Connection Lifetime" is reached, and the max pool (any pool, 300 for example) will be reached.

(I checked 5.2.4, 5.2.5 - same problem)
[14 Mar 2009 6:28] Antonio García
I have a WindowsForms application running using connector for .NET, just sitting MySQL next to my app on the same machine, and I have the very same problem that Moshe explains.
You can use the code he provided in his last post, and it will fail on winforms application too.
I also made a debug on the sources and I could see that the error is because when a new connection is requested this test fails:

if (!HasIdleConnections)   <--- This condition FAILS
    driver = CreateNewPooledConnection();  <--- So it creates a new connection
else
    driver = CheckoutConnection();  <--- Instead of reusing an existing one

(located in GetPooledConnection function on MySQLPool.cs, line 150)

and it fails because idlePool is empty, but MySQL Administrator shows THERE ARE idle connections, so due to that fact, connector makes the decision to create a new connection and therefore the idle connection is wasted and never recovered because the reference to the connection has been lost.
I couldn't figure out the condition that makes idlePool to be empty when there still are connections available (understanding all of connector code was out of scope to me)

The error is present in connector 6 too. I tried both versions and fails the same way.
[14 Mar 2009 6:30] Antonio García
Screenshot showing the error described

Attachment: ScreenShot.JPG (image/jpeg, text), 131.89 KiB.

[14 Mar 2009 21:07] Tonci Grgin
Antonio, "SLEEP" word has mislead you. Connection to MySQL server that is in "SLEEP" state actually *waits* for something from server. So please do not mix c/NET or IIS pooled connection state with MySQL server connection state.

As I am not convinced there is no bug here, it's still in analyzing.
[14 Mar 2009 23:33] Antonio García
Let's say I'm wrong, due to the fact connections are sleeping and waiting for something to happen instead of IDLE.
But anyway, connection pooling means reusing connections, the connections shown are connections that were used, then they were closed/disposed and are supposed to go back to the pool.
Well that's something that doesn't happen.  If I continue executing the application, a lot more "sleeping" connections appear until I reach max pool size and then MySQL refuses further connections with error "Too many connections"

Ok, they are not idle, they're sleeping, but why??
I closed/disposed every connection (I need to use many connections since connector doesn't support MARS) so why they sleep instead of getting idle?
Why connection pool doesn't reuse them?
You say they are waiting for something in server, please tell me what can possibly be waiting a connection that was closed? Why connection pooling are not  reusing them?

As you can see, maybe the names of the connection states are not correct, but I think THERE is a bug, since connection pool is NOT reusing them.

The connection String I'm using is this, hope it helps

"Database=omnivent;Port=3306;Pooling=True;Use Compression=True;Server=localhost;User Id=XXXXX;Password=YYYYY;Allow Batch=True;Connect Timeout=10"

Thanks in advance
[19 Mar 2009 23:26] Milan Burmaja
I just want to confirm same problem with WinForms and 5.2.5 connector. Until few  weeks ago I've used 5.0.6 and there was no problem

Milan
[23 Mar 2009 4:13] Antonio García
Tonci:
Any news on this?
[26 Mar 2009 16:04] Nicklas Holmgren
Hi I also have the same problem... I use Subsonic 2.1 with mysql 5.2.5. (maybe I can upgrade to mysql 6.0 and it'll magically go away?)
I had same problem with 5.2.3 just so u know.

[MySqlException (0x80004005): error connecting: Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.  This may have occurred because all pooled connections were in use and max pool size was reached.]
   MySql.Data.MySqlClient.MySqlPool.GetConnection() +184
   MySql.Data.MySqlClient.MySqlConnection.Open() +335
   SubSonic.MySqlDataProvider.CreateConnection(String newConnectionString) +61
   SubSonic.MySqlDataProvider.CreateConnection() +46
[26 Mar 2009 16:09] Tonci Grgin
Guys, this is very stretched but try this:
  o Increase connection timeout
  o Change the registry parameter responsible for the number of TCP ports on Windows as described in http://dev.mysql.com/doc/refman/5.0/en/can-not-connect-to-server.html#can-not-connect-to-s...
  o Retest

Remember that for each different connection string you get separate pool.
[26 Mar 2009 16:11] Tonci Grgin
too fast...
  o Check max_connections on server and adjust all pool sizes accordingly
[26 Mar 2009 20:07] Tonci Grgin
Guys, we are working vigorously but with no progress... All we've gathered so far are bits and pieces.
So here's another one:  http://msdn.microsoft.com/en-us/library/system.threading.threadpool.setmaxthreads.aspx
Do you errors appear when you're close to or over the MaxWorkerThreads? If so, it's limitation of framework and OS. This might also be the answer to Antonio's questions "sleeping but why?".
[26 Mar 2009 21:03] Antonio García
Tonci:
I already tried your suggestions, but with no success =(
Increasing pool size just delays the error but it happens anyway.
In the other hand, I don't really think that worker threads has something to do, at least in my particular case, due to the fact that connections go to sleep immediatly after connection is closed/disposed. And even if I don't reach the connection limit (e.g. I quit from the application), I have a lot of sleeping connections that never get reused, but interesting thing is when application is closed all the connections are freed correctly (because they are in the "InUse" or" ActivePool" -don't remember variable name- collection, I noticed that when debugged the code).  Nothing is left behind.

I do use worker threads, they are in the worst case 3 worker threads concurrently working, but the problem reported is easily reproduced even with just the main thread of the application.

Error regarding connection limit ("Too many connections") is only thrown when I reach the max pool size (I also tried with a hardcoded version of connection string just to avoid getting different pools. The problem is just the same)

I hope this info help you to detect the problem.

Thanks
[27 Mar 2009 12:56] Nicklas Holmgren
I'm looking forward to hear more in the matter. Do you think things will be solved if I switch over to mysql 6.0 on server and connector?
[27 Mar 2009 16:33] Tonci Grgin
There's been new update on this. Support is currently testing workaround for possible cause of this problem. More to the point, we are to moving Ping() requests out of the locked section.

Workflow:
  Now:
   (1) lock the pool object
   (2) get pooled connection or create a new one if pool is empty
   (3) ping the server using the connection from step 2
   (4) mark connection as valid if ping finished successfully or create a new connection
   (5) unlock the pool object

Consequently, all requests to the pool have to wait until ping() finishes and the pool is unlocked.

  Testing:
   (1) lock the pool object
   (2) get pooled connection or create a new one if pool is empty
   (3) unlock the pool object
   (4) ping the server using the connection from step 2
   (5) mark connection as valid if ping finished successfully or create a new connection

We have high hopes this will cure the problem you're seeing or, at least, improve status a bit. After testing, Reggie will make the final call.
[1 Apr 2009 15:04] Nicklas Holmgren
Currently I've set pooling=false which solves it for me, but I'm guessing at a pretty high loss of speed. I am waiting for this solution eagerly :) How's the testing going?
[2 Apr 2009 9:54] Nicklas Holmgren
The change to pooling=false hasn't solved the issue for me! I'm still getting occurencies of unable to connect to any of the specified mysql hosts. when clearly the mysql host is up and alive. what suggestions do you have for me?
[2 Apr 2009 10:07] Tonci Grgin
Nicklas, there have been situations in which new code could produce deadlock so we're refining it. As for you concrete case, I am really not a magician... Probably you're hitting some framework or server limitation, don't know...
[8 Apr 2009 14:03] Nicklas Holmgren
I did the adjustments you told about [26 Mar 17:09] and site has been running stable since.. also did some optimizations where I saw I opened so many unecessary connections. I made stored procs of them and joined the results and gained much nicer performance and much much less connections opened... thx.

obviously we hit the limit of 5000 connections at once, probably due to sloppy coding
[8 Apr 2009 14:22] Tonci Grgin
Nicklas, glad things function now... This is just to show how complex connectors matter are. You never know where the devil is. Especially on windows.
[8 Apr 2009 16:24] Antonio García
Hi Toncy,
Is there any news on the correction you told us about (March 27th)?
[9 Apr 2009 6:20] Tonci Grgin
Antonio, unfortunately no news for now. Each patch goes through rigorous testing process even though it appears to be correct or functioning...
[9 Apr 2009 15:57] Tonci Grgin
Probably same problem as described in Bug#43349.
[21 Apr 2009 0:35] José García
Hi.
 I am just migarting an appication I have with .Net C# from SQL Express to MySQL 6.0. Same problem with connections and timeing out.

Do you have any news on this issue?
[21 Apr 2009 0:39] José García
By the way, solution from March 26th didn't work for me either; however pooling=false worked, but very slow; end user is gona kill me if I release my system with this "solution"

I would appreciate if you have any news on this.
[18 May 2009 18:39] Moshe Lampert
After a deep searching inside code, on our test and production servers, I found solution for a 50%~  of the connections losted.

If pooling is disabled and something fail:
open > work > error > GC closed connection

If pooling is open, pooler has a some type of array of in-use connections,
when some code fail, GC found  refrence to opened connection in the array and keeps the connection object, and the object will marked "in-use" forever.

I solve it (not 100% ! the problem is inside from other reasons) with using "With":

Using Conn As New MySqlConnection(ConnString)
	Conn.Open()
End Using

in ASP.NET page (or base-class), option two:

Private Sub Page_Error(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Error
	Conn.Close() : Conn.Dispose()
End Sub

this is not a perefect solution, but reduced losted connections.
[20 Jun 2009 8:51] Tonci Grgin
Bug#43349 is marked as duplicate of this report.
[19 Jul 2009 22:15] d di
Hi guys

I'd like to know if this problem can be reproduced with an alternative pooling algorithm, if you have time try out http://bugs.mysql.com/file.php?id=12463 (from issue #40684) and see if that helps or makes things worse.
[24 Sep 2009 11:29] Moshe Lampert
something new?

The connector may need to check if connection losted open, then return to the pool, or set a "timeout" for connection, and return automatically to the pool to solve this problem.
[24 Sep 2009 19:12] Tonci Grgin
Moshe, not that I know of. Will look into status when I return from vacation.
I also made mistake by leaving report in Analyzing instead of Verified...
[28 Sep 2009 8:59] Dan orsborne
I had the same issue with the connector. Turns out there is an issue with pooling that exists in all versions from 5.1.7 up to current version (It's still not fixed).  Download the complete source and apply the changes in this post and it works perfectly!

http://bugs.mysql.com/bug.php?id=31996
[30 Nov 2009 15:46] Vladislav Vaintroub
Closing as duplicate of Bug #31996
[21 Mar 2011 23:08] LoxeloreFex LoxeloreFex
В случае если у Вас совершенно не складывается сексуальная деятельность, а её сильно не хватает, то вам нужно всего посетить ресурс x-stars.ru. На Ваш выбор здесь находятся дешевые путаны Столицы. С ними Вы сможете провести первоклассный интим досуг. Тарифы на сервис отображены на их анкетных страницах, что несомненно поможет Вам определиться при выборе девушки по вызову. С целью Вашего удобства на сайте есть территориальный поиск, для того чтобы вы имели представление, где именно та или иная девушка по вызову может Вас встретить у себя.