Skip to content

MySqlException continuously thrown after restart mysql server #1198

@ewfian

Description

@ewfian

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

  1. Run mysql:5.7 image in docker
  2. Run following demo code
  3. Restart mysql container after the demo is fully started
  4. 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.

Releated to: #1071 #1033 #859 #947

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions