Skip to content

Connection pool entry is leaked if MySqlConnection is not disposed #251

@bgrainger

Description

@bgrainger

Execute the following code:

var csb = new MySqlConnectionStringBuilder
{
	// server, username, password, etc.
	Pooling = true,
	MaximumPoolSize = 5,
	ConnectionTimeout = 5u,
};

for (int i = 0; i < 6; i++)
{
	var connection = new MySqlConnection(csb.ConnectionString);
	connection.Open(); // throws when i == 5
	GC.Collect();
}

If MySqlConnection is not disposed, then MySqlSession.ReturnToPool is not called, so ConnectionPool.Return doesn't release m_sessionSemaphore. If this happens repeatedly in client code, then eventually all open slots in the pool are leaked, and clients start timing out in ConnectionPool.GetSessionAsync.

One strategy to mitigate this might be for the connection pool to maintain a list of WeakReference<MySqlSession> objects. If a weak reference's target was null, we would know that a connection had been GC'ed without having been disposed, so could manually Release the semaphore to free up that slot. This could be done explicitly in GetSessionAsync (if CurrentCount == 0) or perhaps periodically in the background, e.g., by the connection pool reaper. (Disposing the connection would have to remove the weak reference from the list.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions