随机 MySQL 异常 - 更改数据库时'Reading from the stream has failed'



这个问题在我们的生产中已经存在很长时间了。 有成千上万的用户机器不断尝试同时连接到MySQL,并通过根据需要不断更改数据库来触发对多个数据库的查询。

要更改数据库,这是客户端计算机具有的 -

private MySqlConnection Conn;
public void ChangeDatabase(string DatabaseName)
{
if (Conn.State != ConnectionState.Open)
{
Conn.Open();
}
Conn.ChangeDatabase(DatabaseName);
}

根据我们的猜测,在某些情况下,当数据库更改发生时,我们会得到 Exeption-

[捕获标准异常:MySql.Data.MySqlClient.MySqlException] 使用方法"mysql_native_password"对用户"----"的主机"_._.__._"进行身份验证失败,并显示消息:从流读取失败。

这是堆栈跟踪 -

Void Trace(System.Exception) [FileName: ; Line:0].
Void TimerProcess_Elapsed(System.Object, System.Timers.ElapsedEventArgs) [FileName: ; Line:0].
Void MyTimerCallback(System.Object) [FileName: ; Line:0].
Void CallCallbackInContext(System.Object) [FileName: ; Line:0].
Void RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) [FileName: ; Line:0].
Void Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) [FileName: ; Line:0].
Void CallCallback() [FileName: ; Line:0].
Void Fire() [FileName: ; Line:0].
Void FireNextTimers() [FileName: ; Line:0].
Void AppDomainTimerCallback() [FileName: ; Line:0]. at
MySql.Data.MySqlClient.Authentication.MySqlAuthenticationPlugin.AuthenticationFailed(Exception ex) at
MySql.Data.MySqlClient.Authentication.MySqlAuthenticationPlugin.ReadPacket() at
MySql.Data.MySqlClient.Authentication.MySqlAuthenticationPlugin.Authenticate(Boolean reset) at
MySql.Data.MySqlClient.NativeDriver.Authenticate(String authMethod, Boolean reset) at
MySql.Data.MySqlClient.NativeDriver.Open() at
MySql.Data.MySqlClient.Driver.Open() at
MySql.Data.MySqlClient.Driver.Create(MySqlConnectionStringBuilder settings) at
MySql.Data.MySqlClient.MySqlConnection.Open() at
FSCCClientUploadServiceLive.ProcessClientUpload.TimerProcess_Elapsed(Object sender, ElapsedEventArgs e)
----------------------------------------------------------
Time stamp 18/09/2018 12:25:48.325
Thread details 27
Message:    [InnerException] Reading from the stream has failed.
Detail: [Source] MySql.Data
Stack Trace:
Void Trace(System.Exception) [FileName: ; Line:0].
Void TimerFinish_Elapsed(System.Object, System.Timers.ElapsedEventArgs) [FileName: ; Line:0].
Void MyTimerCallback(System.Object) [FileName: ; Line:0].
Void CallCallbackInContext(System.Object) [FileName: ; Line:0].
Void RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) [FileName: ; Line:0].
Void Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) [FileName: ; Line:0].
Void CallCallback() [FileName: ; Line:0].
Void Fire() [FileName: ; Line:0].
Void FireNextTimers() [FileName: ; Line:0].
Void AppDomainTimerCallback() [FileName: ; Line:0].
at MySql.Data.MySqlClient.MySqlStream.LoadPacket()
at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
at MySql.Data.MySqlClient.Authentication.MySqlAuthenticationPlugin.ReadPacket()
----------------------------------------------------------
Time stamp 18/09/2018 12:25:49.093
Thread details 27
Message:    [InnerException] Attempted to read past the end of the stream.
Detail: [Source] MySql.Data
Stack Trace:
Void Trace(System.Exception) [FileName: ; Line:0].
Void TimerFinish_Elapsed(System.Object, System.Timers.ElapsedEventArgs) [FileName: ; Line:0].
Void MyTimerCallback(System.Object) [FileName: ; Line:0].
Void CallCallbackInContext(System.Object) [FileName: ; Line:0].
Void RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) [FileName: ; Line:0].
Void Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean) [FileName: ; Line:0].
Void CallCallback() [FileName: ; Line:0].
Void Fire() [FileName: ; Line:0].
Void FireNextTimers() [FileName: ; Line:0].
Void AppDomainTimerCallback() [FileName: ; Line:0].
at MySql.Data.MySqlClient.MySqlStream.ReadFully(Stream stream, Byte[] buffer, Int32 offset, Int32 count)
at MySql.Data.MySqlClient.MySqlStream.LoadPacket()

此问题不会定期出现。当一切正常时,它突然突然出现。

为此,我已经尝试了SO上可用的其他解决方案,但是它们都没有帮助我们。正如我所猜测的,此异常主要出现在数据库更改的情况下。

解决方案 1:如果不需要 SSL。由于它是由 SSL 引起的,我们可以通过将"SslMode=None"附加到连接字符串来关闭 SSL。

解决方案 2:如果需要 SSL,则服务器身份很重要,需要验证。服务器需要互联网连接才能进行证书验证。请注意,加密 API 不会为每个进程更新 CTL。CTL 在操作系统级别进行维护。一旦您将服务器连接到互联网并与服务器建立 SSL 数据库连接,CTL 将自动更新。然后,您可以断开互联网连接。再次注意CTL有其到期日期,之后Windows需要再次更新它。这可能会在几个月后发生。

解决方案 3:如果需要 SSL,但服务器标识不重要。通常,在这种情况下,SSL 仅用于加密网络传输。我们可以关闭 CTL 更新:

  1. 按 Win+R 打开"运行"对话框,键入"gpedit.msc"(不带引号(,然后按 Enter
  2. 在"本地组策略编辑器"中,依次展开"计算机配置"、"管理模板"、"系统"、"Internet 通信管理",然后单击"Internet 通信设置"。
  3. 在详细信息面板中,双击"关闭自动根证书更新",单击启用,然后单击确定。此更改将立即生效,无需重新启动。

https://blog.csdn.net/fancyf/article/details/78295964 清楚地解释根本原因和解决方案。

我读了很多解决方案,最困惑和出现到处都是这个链接,因为它被引用了很多。 https://blog.csdn.net/fancyf/article/details/78295964

但问题很简单,无法建立连接。

就我而言,本地在连接到mySQL服务器时运行良好。 但是当部署到Windows Server 2012 R2时,我得到了错误。

在谷歌上搜索一段时间后的解决方案是:

通过将以下内容添加到连接字符串来增加连接超时: 连接超时 = 30 https://www.connectionstrings.com/mysql-connector-net-mysqlconnection/specifying-connection-attempt-timeout/

所以我认为 2 台服务器需要时间来协商和握手,所以默认的时间范围是不够的。

最新更新