在使用 MySqlConnector 套件连接 mysql 的时候,偶发性的出现 MySqlConnector.MySqlException (0x80004005): Connect Timeout expired. All pooled connections are in use 错误,这里将展示怎么重现这个问题
呈上篇 出现的错误,相伴随的也可能会出现另一种错误 All pooled connections are in use
测试工具与套件
c# 7.0
RoslynPad
MySqlConnector
重现方式
Step1 查询现在的最大连线数
SHOW GLOBAL VARIABLES LIKE 'max_connections';
Step2 设定最大连线数量为 151
SET GLOBAL max_connections = 151;
Step3 使用 client1 建立100条连线后,并设定 connection pool 连线最大长度为 100,但是不关闭,先等待 5 秒
#r "nuget: MySqlConnector, 2.3.5"
using System.Data;
using MySqlConnector;
for (var i = 1; i <= 100; i++)
{
try
{
var db = GetDbConnection(@"Server=127.0.0.1;Database=db1;Uid=root;Pwd=123;Port=3306;MaximumPoolSize=100");
//slow it
Thread.Sleep(20);
}
catch (Exception ex)
{
Console.WriteLine($"{i}, {ex}");
break;
}
}
Thread.Sleep(5000);
"done".Dump();
try
{
var db = GetDbConnection(@"Server=127.0.0.1;Database=db1;Uid=root;Pwd=123;Port=3306;MaximumPoolSize=100");
}
catch (Exception ex)
{
Console.WriteLine($"{ex}");
}
IDbConnection GetDbConnection(string strConn)
{
var connection = new MySqlConnection(strConn);
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
return connection;
}
step4 使用client2,建立51条连线后,等待 10 秒后关闭
#r "nuget: MySqlConnector, 2.3.5"
using MySqlConnector;
using System.Data;
for (var i = 1; i <= 51; i++)
{
try
{
var db = GetDbConnection(@"Server=127.0.0.1;Database=db2;Uid=root;Pwd=123;Port=3306;MaximumPoolSize=100");
//show it
Thread.Sleep(20);
}
catch (Exception ex)
{
Console.WriteLine($"{i}, {ex}");
break;
}
}
"done".Dump();
Thread.Sleep(10 * 1000);
IDbConnection GetDbConnection(string strConn)
{
var connection = new MySqlConnection(strConn);
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
return connection;
}
在 client1 就会因为 connection pool 都在使用了,且去要连线的时候,已经超过 151个连线数量,就会出现 Connect Timeout expired. All pooled connections are in use 的错误讯息