Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.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实体框架-连接超时已过期_C#_Mysql_Entity Framework_.net Core_Google Cloud Sql - Fatal编程技术网

C# MySql实体框架-连接超时已过期

C# MySql实体框架-连接超时已过期,c#,mysql,entity-framework,.net-core,google-cloud-sql,C#,Mysql,Entity Framework,.net Core,Google Cloud Sql,我正在使用C#.NET core 2.2和entity framework 6应用程序中的Google Cloud SQL和MySql v5.7 在我的日志中,我可以从使用数据库的代码中的多个位置看到以下异常: MySql.Data.MySqlClient.MySqlException (0x80004005): Connect Timeout expired. ---> System.OperationCanceledException: The operation was cancel

我正在使用C#.NET core 2.2和entity framework 6应用程序中的Google Cloud SQL和MySql v5.7

在我的日志中,我可以从使用数据库的代码中的多个位置看到以下异常:

MySql.Data.MySqlClient.MySqlException (0x80004005): Connect Timeout expired. ---> System.OperationCanceledException: The operation was canceled.
   at System.Threading.CancellationToken.ThrowOperationCanceledException()
   at System.Threading.SemaphoreSlim.WaitUntilCountOrTimeoutAsync(TaskNode asyncWaiter, Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at MySqlConnector.Core.ConnectionPool.GetSessionAsync(MySqlConnection connection, IOBehavior ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\Core\ConnectionPool.cs:line 42
   at MySql.Data.MySqlClient.MySqlConnection.CreateSessionAsync(Nullable`1 ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlConnection.cs:line 507
   at MySql.Data.MySqlClient.MySqlConnection.CreateSessionAsync(Nullable`1 ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlConnection.cs:line 523
   at MySql.Data.MySqlClient.MySqlConnection.OpenAsync(Nullable`1 ioBehavior, CancellationToken cancellationToken) in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlConnection.cs:line 232
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenDbConnectionAsync(Boolean errorsExpected, CancellationToken cancellationToken)
   at Microsoft.EntityFrameworkCore.Storage.RelationalConnection.OpenAsync(CancellationToken cancellationToken, Boolean errorsExpected)
   at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteAsync(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues, CancellationToken cancellationToken)
当数据库上有一些负载时(不是很高,大约是数据库机器的20%cpu),这种情况会在瞬间临时发生

配置上下文:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    if (!optionsBuilder.IsConfigured)
    {
        optionsBuilder.UseMySql(
            new System.Net.NetworkCredential(string.Empty, ConfigurationManager.CacheCS).Password, builder =>
            {
                builder.EnableRetryOnFailure(15, TimeSpan.FromSeconds(30), null);
            }
            );
    }
}
这将设置最多15次重试,重试间隔最长为30秒

从日志中可以看出,
MySqlConnector
没有重试此特定错误

我的尝试

已尝试将暂时错误号添加到要添加的错误号列表中:

builder.EnableRetryOnFailure(15, TimeSpan.FromSeconds(30), MySqlErrorCodes.TransientErrors);
其中
MySqlErrorCodes.TransientErrors
定义为:

 public enum MySqlErrorCode
    {
        // Too many connections
        ConnectionCountError = 1040,
        // Unable to open connection
        UnableToConnectToHost = 1042,
        // Lock wait timeout exceeded; try restarting transaction
        LockWaitTimeout = 1205,
        // Deadlock found when trying to get lock; try restarting transaction
        LockDeadlock = 1213,
        // Transaction branch was rolled back: deadlock was detected
        XARBDeadlock = 1614

    }

    public class MySqlErrorCodes
    {
        static MySqlErrorCodes()
        {
            TransientErrors = new HashSet<int>()
            {
                (int)MySqlErrorCode.ConnectionCountError,
                (int)MySqlErrorCode.UnableToConnectToHost,
                (int)MySqlErrorCode.LockWaitTimeout,
                (int)MySqlErrorCode.LockDeadlock,
                (int)MySqlErrorCode.XARBDeadlock
            };
        }

        public static HashSet<int> TransientErrors { get; private set; }
    }
我想这就是为什么连接超时没有重试的原因

如何在不执行同一存储过程两次的情况下安全地重试此操作

编辑

以下是全局变量:

显示全局变量,如“%timeout%”

connect_timeout 10
delayed_insert_timeout  300
have_statement_timeout  YES
innodb_flush_log_at_timeout 1
innodb_lock_wait_timeout    50
innodb_rollback_on_timeout  OFF
interactive_timeout 28800
lock_wait_timeout   31536000
net_read_timeout    30
net_write_timeout   60
rpl_semi_sync_master_async_notify_timeout   5000000
rpl_semi_sync_master_timeout    3000
rpl_stop_slave_timeout  31536000
slave_net_timeout   30
wait_timeout    28800
Ssl_default_timeout 7200
Ssl_session_cache_timeouts  0
Uptime  103415
Uptime_since_flush_status   103415
显示全局状态,如“%timeout%”

connect_timeout 10
delayed_insert_timeout  300
have_statement_timeout  YES
innodb_flush_log_at_timeout 1
innodb_lock_wait_timeout    50
innodb_rollback_on_timeout  OFF
interactive_timeout 28800
lock_wait_timeout   31536000
net_read_timeout    30
net_write_timeout   60
rpl_semi_sync_master_async_notify_timeout   5000000
rpl_semi_sync_master_timeout    3000
rpl_stop_slave_timeout  31536000
slave_net_timeout   30
wait_timeout    28800
Ssl_default_timeout 7200
Ssl_session_cache_timeouts  0
Uptime  103415
Uptime_since_flush_status   103415
显示全局状态,如“%正常运行时间%”

connect_timeout 10
delayed_insert_timeout  300
have_statement_timeout  YES
innodb_flush_log_at_timeout 1
innodb_lock_wait_timeout    50
innodb_rollback_on_timeout  OFF
interactive_timeout 28800
lock_wait_timeout   31536000
net_read_timeout    30
net_write_timeout   60
rpl_semi_sync_master_async_notify_timeout   5000000
rpl_semi_sync_master_timeout    3000
rpl_stop_slave_timeout  31536000
slave_net_timeout   30
wait_timeout    28800
Ssl_default_timeout 7200
Ssl_session_cache_timeouts  0
Uptime  103415
Uptime_since_flush_status   103415
除了连接超时问题,我还看到以下日志:

MySql.Data.MySqlClient.MySqlException (0x80004005): MySQL Server rejected client certificate ---> System.IO.IOException: Unable to read data from the transport connection: Broken pipe. ---> System.Net.Sockets.SocketException: Broken pipe
这似乎是与数据库连接相关的问题


重试此类异常是否安全?

发生此问题的原因是连接字符串中的
maximumpoolsize
值较低

当有多个线程在使用数据库,但没有足够的连接来处理所有请求时,这可能会导致连接超时

要修复此问题,请将连接字符串中的此更改为更高的值:

Max Pool Size={maxConnections};

请在MySQL命令提示符下发布A)SHOW全局变量(如“%timeout%)的文本结果;和B)显示全局状态,如“%timeout%;和C)显示全局状态,如“%正常运行时间%”;我认为在云计算环境下登录机器是不可能的。你们有办法进入MySQL命令提示符运行SELECT NOW()吗;返回一天中的时间?或显示数据库?如果不能,请请求Google支持为您运行查询并与您共享结果。这可能是代理和数据库实例之间的连接问题,而不是正确终止连接?