Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# MySql长时间运行查询在Docker.NET Core上失败:试图读取超过流结尾的数据/预期读取4个头字节,但仅收到0_C#_Mysql_Docker_.net Core - Fatal编程技术网

C# MySql长时间运行查询在Docker.NET Core上失败:试图读取超过流结尾的数据/预期读取4个头字节,但仅收到0

C# MySql长时间运行查询在Docker.NET Core上失败:试图读取超过流结尾的数据/预期读取4个头字节,但仅收到0,c#,mysql,docker,.net-core,C#,Mysql,Docker,.net Core,我试图用一个在非索引列上有where子句的查询来查询一个95M行的MySql数据库(请不要判断,我无法控制这部分,因为服务器不是我们的) 我尝试了MySqlConnector和MySqlClient,结果都是一样的。持续5分钟后,它们都会出错: 使用MySqlConnector: 应读取4个标头字节,但仅接收到0 使用MySql.Data.MySqlClient 试图读取超过流结尾的内容 此仅在docker容器中发生(在Windows上运行docker Desktop的aspnet:3.1-bu

我试图用一个在非索引列上有where子句的查询来查询一个95M行的MySql数据库(请不要判断,我无法控制这部分,因为服务器不是我们的)

我尝试了MySqlConnector和MySqlClient,结果都是一样的。持续5分钟后,它们都会出错:

使用MySqlConnector:

应读取4个标头字节,但仅接收到0

使用MySql.Data.MySqlClient

试图读取超过流结尾的内容

仅在docker容器中发生(在Windows上运行docker Desktop的
aspnet:3.1-buster-slim
图像,但我尝试了其他具有相同结果的方法)

通过IIS express托管的web api或控制台应用程序运行相同的代码可以正常工作

连接字符串指定
连接超时=21600;默认命令超时=21600;最小池大小=0我尝试了各种最小/最大池大小配置,并在没有运气的情况下关闭了池

我已尝试将连接字符串
SslMode
更改为
None
,但没有更改

查询数据的代码非常简单:

protected virtual async IAsyncEnumerable<List<object>> GetDataAsync(string connectionString, string sql, int timeout = 21600, IsolationLevel isolationLevel = IsolationLevel.ReadCommitted)
{
    await using var conn = new MySqlConnection { ConnectionString = connectionString };
    await conn.OpenAsync();
    using var trans = await conn.BeginTransactionAsync(isolationLevel);
    await using var cmd = new MySqlCommand { Connection = conn, CommandText = sql, CommandTimeout = timeout, Transaction = trans };
    await using (var reader = await cmd.ExecuteReaderAsync())
    {
        while (await reader.ReadAsync())
        {
            var values = new object[reader.FieldCount];
            reader.GetValues(values);
            yield return values.Select(v => v is DBNull ? null : v).ToList();
        }
    }

    await trans.CommitAsync();
}
受保护的虚拟异步IAsyncEnumerable GetDataAsync(string connectionString,string sql,int timeout=21600,IsolationLevel IsolationLevel=IsolationLevel.ReadCommitted)
{
等待使用var conn=new MySqlConnection{ConnectionString=ConnectionString};
等待连接OpenAsync();
使用var trans=await conn.BeginTransactionAsync(隔离级别);
等待使用var cmd=new MySqlCommand{Connection=conn,CommandText=sql,CommandTimeout=timeout,Transaction=trans};
使用wait(var reader=wait cmd.ExecuteReaderAsync())
{
while(等待reader.ReadAsync())
{
var值=新对象[reader.FieldCount];
reader.GetValues(值);
产生返回值;
}
}
等待trans.CommitAsync();
}
我试过有交易和没有交易-没有变化

如果我尝试一个更简单的查询,我将使用相同的
GetDataAsync
方法返回结果,而不考虑问题。更奇怪的是,其他长时间运行的查询也运行良好。如果我尝试对一个有3000万行的表执行类似的、无索引的查询,它会运行5分钟,最终(超过一小时)返回结果

运行
show variables
会产生以下结果(其中似乎没有一个指向问题):

  • 连接超时10
  • 延迟插入超时300
  • innodb\u在\u超时1时刷新\u日志\u
  • innodb\u锁定\u等待\u超时50
  • innodb\u回滚\u打开\u超时关闭
  • 交互式超时28800
  • 锁定等待超时31536000
  • 网络读取超时30
  • 净写入超时60
  • rpl_停止_从站_超时31536000
  • 从网络超时3600
  • 等待超时28800

docker容器中是否出现某种空闲网络超时?

在连接字符串中设置
Keepalive=120
;这将每两分钟(120秒)发送TCP keepalive数据包,这将阻止连接关闭。(您可能需要根据具体情况调整
Keepalive
值。)


请注意,如果您在Linux上使用MySqlConnector,由于.NET Core的限制,此选项仅在.NET Core 3.0(或更高版本)上实现。

感谢您提出的详细问题和所有相关细节。但我不明白为什么30M行查询会运行一个小时,而95M行查询会在5分钟后超时。您是否在连接字符串中尝试了
KeepAlive=120
,以强制TCP保留数据包?(MySqlConnector文档已经过时;该选项应该得到尊重,并在Linux上通过
netcoreapp3.0
或更高版本实现。)赢家!!!谢谢你,@BradleyGrainger!!如果你想写下来作为答案,我很乐意接受。mysql和你引用的mysql.Data库的版本是什么?有一段时间也面临类似的问题back@KamranShahid我用最新版本的MySql.Data(v8.0.21)和MySqlConnector(v1.0.1)进行了尝试。多亏了布拉德利,我才能够使用MySqlConnector和
KeepAlive=120
。我没有在MySql.Data上试过,我想他使用的是.NETCore3.1