-
Notifications
You must be signed in to change notification settings - Fork 345
Description
Software versions
MySqlConnector version: 2.1.11
Server type (MySQL, MariaDB, Aurora, etc.) and version: MySQL 5.7
.NET version: net6.0
(Optional) ORM NuGet packages and versions: Pomelo.EntityFrameworkCore.MySql 6.0.2
Describe the bug
MySqlException continuously thrown after restart mysql server.
Step to reproduce
- Run mysql:5.7 image in docker
- Run following demo code
- Restart mysql container after the demo is fully started
- The execptions will continuously thrown
Exception
MySqlConnector.MySqlException (0x80004005): Connect Timeout expired. All pooled connections are in use. at MySqlConnector.MySqlConnection.CreateSessionAsync(ConnectionPool pool, Int32 startTickCount, Nullable`1 ioBehavior, CancellationToken cancellationToken) in D:\Repos\MySqlConnector\src\MySqlConnector\MySqlConnection.cs:line 937 at MySqlConnector.MySqlConnection.OpenAsync(Nullable`1 ioBehavior, CancellationToken cancellationToken) in D:\Repos\MySqlConnector\src\MySqlConnector\MySqlConnection.cs:line 410 at ConsoleApp1.Program.<>c.<b__2_0>d.MoveNext() in D:\Repos\MySqlConnector\ConsoleApp1\Program.cs:line 34
Code sample
using MySqlConnector;
using MySqlConnector.Logging;
namespace ConsoleApp1
{
class Logger : IMySqlConnectorLogger
{
public bool IsEnabled(MySqlConnectorLogLevel level) => true;
public void Log(MySqlConnectorLogLevel level, string message, object?[]? args = null, Exception? exception = null) => Console.WriteLine("[{0}] {1}", level, message);
}
class LoggerProvider : IMySqlConnectorLoggerProvider
{
public IMySqlConnectorLogger CreateLogger(string name) => new Logger();
}
internal class Program
{
const string connString = "server=localhost;port=3306;user=kr;password=*;database=*;Character Set=utf8mb4;";
const string sql = @"SELECT id FROM user WHERE id = 1";
static async Task Main(string[] args)
{
MySqlConnectorLogManager.Provider = new LoggerProvider();
Console.WriteLine("Hello, World!");
for (var i = 0; i < 10000; i++)
{
for (var j = 0; j < 1000; j++)
{
_ = Task.Run(async () =>
{
try
{
using (var conn = new MySqlConnection(connString))
{
await conn.OpenAsync();
using (var cmd = new MySqlCommand(sql, conn))
using (var reader = await cmd.ExecuteReaderAsync())
while (await reader.ReadAsync())
Console.WriteLine(reader.GetInt32(0));
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
});
}
await Task.Delay(1000);
}
Console.ReadLine();
}
}
}
Expected behavior
It should able to back to normal after restart finished.
Additional context
Our program is hosted on Azure and working behind a Load Balancer while the mysql server is hosted on AWS. The Load Balancer or other various network devices on the path from Azure to AWS has some potentially instability. Such as NAT aging. Restart server is just a way to simulate NAT aging. Node switching may also occur in AWS RDS. We expects there should have some resilience to recover from a bad network condition that has just been endured or node switching instead of requires manual intervention.
The issue is actually happed by using a linq with Pomelo.EntityFrameworkCore.MySql. When the pressure is high, restarting mysql repeatedly can reproduce this issue. The above code is just a simple demo, maybe there are other reasons.