Bug #100692 class Ssl 无限期等候的情况
Submitted: 31 Aug 2020 6:27 Modified: 24 Nov 2020 15:16
Reporter: sdf sdf Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / NET Severity:S1 (Critical)
Version:8.021 OS:Windows
Assigned to: CPU Architecture:Any

[31 Aug 2020 6:27] sdf sdf
Description:
  try
        {
          tlsProtocol = (tlsProtocol == SslProtocols.None) ? SslProtocols.Tls : tlsProtocol;
          ss.AuthenticateAsClientAsync(_settings.Server, certs, tlsProtocol, false).Wait();
          tlsConnectionRef[connectionId] = tlsProtocol;
          tlsRetry.Remove(connectionId);
        }

  ss.AuthenticateAsClientAsync(_settings.Server, certs, tlsProtocol, false).Wait(); 无限期等候。

当  MySqlConnection连接mysql 路由器,而mysql 路由器因故障网络通信等原因,如路由器重启。而此时程序正在使用。MySqlConnection.open 时,会造成ss.AuthenticateAsClientAsync(_settings.Server, certs, tlsProtocol, false).Wait(); 无限期等候,阻塞程序运行。

When the MySQL connection is connected to the MySQL router, the MySQL router is restarted due to network communication failure. At this point, the program is in use. MySqlConnection.open Will cause ss.AuthenticateAsClientAsync ( settings.Server , certs, tlsprotocol, false). Wait(); wait() indefinitely, blocking program running.

How to repeat:
ss.AuthenticateAsClientAsync ( settings.Server , certs, tlsProtocol, false).Wait();

Wait indefinitely.

When the MySQL connection is connected to the MySQL router, the MySQL router is restarted due to network communication failure. At this point, the program is in use. MySqlConnection.open Will cause ss.AuthenticateAsClientAsync ( settings.Server , certs, tlsprotocol, false). Wait(); wait() indefinitely, blocking program running.

Suggested fix:
   ss.AuthenticateAsClientAsync(_settings.Server, certs, tlsProtocol, false).Wait(_settings.ConnectionTimeout);
[17 Sep 2020 12:40] MySQL Verification Team
Hello!,

Thank you for the report and feedback.
May I request you to please provide a simple test case(c# class) case to reproduce this issue at our end? If you can provide more information, feel free to add it to this bug and change the status back to 'Open'.  

Thank you for your interest in MySQL.

Regards,
Ashwini Patil
[17 Sep 2020 13:15] sdf sdf
//打开数据库链接
        public MySqlConnection Open_Conn()
        {

            MySqlConnection conn = new MySqlConnection(_connstr);

            conn.Open();

            return conn;

        }
        //关闭数据库链接
        public void Close_Conn(MySqlConnection conn)
        {
            if (conn != null)
            {
                if (conn.State == ConnectionState.Open)
                {
                    conn.Close();
                    conn.Dispose();
                }

            }

        }

        // 生成Command对象 
        public MySqlCommand Create_Cmd(string SQL, MySqlConnection _Connn)
        {

            MySqlCommand Cmd = new MySqlCommand(SQL, _Connn);
            Cmd.CommandTimeout = _commandtimeout;
            return Cmd;
        }

        //运行MySql语句,反回受影响的行
        public int Run_SQL(string SQL, string name)
        {
            string errmsg = string.Empty;
            System.Diagnostics.Stopwatch Executiontime = new System.Diagnostics.Stopwatch();

          

                for (int i = 0; i < _maxcommanderrorcount;i++)
            {
                MySqlConnection _conn = null;

                try

                {
                    Executiontime.Reset();
                 

                    Executiontime.Start();
                    Console.WriteLine(name + ",for," + i + ",Open_Conn start," + Executiontime.ElapsedMilliseconds);
                    Log.Write(name + ",for," + i + ",Open_Conn  start," + Executiontime.ElapsedMilliseconds, EAF.Log.MsgType.Information);

                    _conn = Open_Conn();

                    Executiontime.Stop();

                    Console.WriteLine(name + ",for," + i + ",Open_Conn ok," + Executiontime.ElapsedMilliseconds);
                    Log.Write(name + ",for," + i + ",Open_Conn ok," + Executiontime.ElapsedMilliseconds, EAF.Log.MsgType.Information);
                    Executiontime.Reset();
                    Executiontime.Start();
                    MySqlCommand Cmd = Create_Cmd(SQL, _conn);
                    Executiontime.Stop();
                    Console.WriteLine(name + ",for," + i + ",Create_Cmd ok," + Executiontime.ElapsedMilliseconds);
                    Log.Write(name + ",for," + i + ",Create_Cmd ok", EAF.Log.MsgType.Information);
                    Executiontime.Reset();
                    Executiontime.Start();
                    int result_count = Cmd.ExecuteNonQuery();
                    Executiontime.Stop();
                    Console.WriteLine(name + ",for," + i + ",ExecuteNonQuery ok," + Executiontime.ElapsedMilliseconds);
                    Log.Write(name + ",for," + i + ",ExecuteNonQuery ok", EAF.Log.MsgType.Information);
                    Executiontime.Reset();
                    Executiontime.Start();
                    Close_Conn(_conn);
                    Executiontime.Stop();
                    Console.WriteLine(name + ",for," + i + ",Close_Conn ok," + Executiontime.ElapsedMilliseconds);
                    Log.Write(name + ",for," + i + ",Close_Conn ok", EAF.Log.MsgType.Information);
                    return result_count;

                }
                catch (MySqlException ex)
                {
                    Close_Conn(_conn);
                    Executiontime.Stop();

                    Console.WriteLine(name + ",for," + i + ",MySqlException ok," + Executiontime.ElapsedMilliseconds+",errmsg,"+ex.Message);

                    errmsg = "MySqlException," + Executiontime.ElapsedMilliseconds + ",errcode," + ex.Number + "name," + name + ",for, " + i + ", errmsg," +ex.Message + ",StackTrace," + ex.StackTrace;

                    Log.Write(name + ",for," + i + "," + errmsg, EAF.Log.MsgType.Error);
                    changecurrentmarks();

                }

                catch (Exception ex)
                {
                    Close_Conn(_conn);
                    Executiontime.Stop();
                    Console.WriteLine(name + ",for," + i + ",Exception ok," + Executiontime.ElapsedMilliseconds + ",errmsg," + ex.Message);

                    errmsg = "Exception," + Executiontime.ElapsedMilliseconds + ",errcode," + ex.HResult + "name," + name + ",for, " + i + ", errmsg," + ex.Message+ ",StackTrace," + ex.StackTrace;

                    Log.Write(name + ",for," + i + "," + errmsg, EAF.Log.MsgType.Error);
                    changecurrentmarks();
                }
            }
       
        throw new MysqlProgressException("stop mysql " + _maxcommanderrorcount + "max count,Run_SQL1," + nowaddress + "," + errmsg, new Exception(errmsg));

        }
   
        //运行MySql语句,反回受影响的行
        public int Run_SQL(string SQL, object[] obj, string[] ParameterName)
        {
            if (ParameterName.Length < 1)
            {
                return -1;
            }
            string errmsg = string.Empty;

            for (int i = 0; i < _maxcommanderrorcount; i++)
            {
                MySqlConnection _conn = null;
                try
                {
                    _conn = Open_Conn();
                    MySqlCommand Cmd = Create_Cmd(SQL, _conn);
                    int k = 0;
                    foreach (string name in ParameterName)
                    {
                        MySqlParameter mysqlparameter = new MySqlParameter(name, MySqlDbType.LongBlob);
                        mysqlparameter.Value = obj[k];
                        Cmd.Parameters.Add(mysqlparameter);
                        k++;
                    }
                    int result_count = Cmd.ExecuteNonQuery();
                    Close_Conn(_conn);
                    return result_count;
                }
                catch (MySqlException ex)
                {
                    Close_Conn(_conn);
                    changecurrentmarks();

                    if (OnMysqlConnMoreEvent != null)
                    {
                        OnMysqlConnMoreEvent.BeginInvoke(this, new MysqlConnMoreEventArgs(nowaddress, "Run_SQL2," + nowaddress + ",MySqlException,错误编码," + ex.Number + ",错误消息," + i + "," + ex.Message + ",[" + SQL + "]"), null, null);
                    }

                    errmsg = "MySqlException,错误编码," + ex.Number + ",错误消息," + i + "," + ex.Message + ",[" + SQL + "]";

                }
                catch (Exception ex)
                {
                    Close_Conn(_conn);
                    changecurrentmarks();
                    if (OnMysqlConnMoreEvent != null)
                    {
                        OnMysqlConnMoreEvent.BeginInvoke(this, new MysqlConnMoreEventArgs(nowaddress, "Run_SQL2," + nowaddress + ",Exception,错误编码," + ex.HResult + ",错误消息," + i + "," + ex.Message + ",[" + SQL + "]"), null, null);
                    }

                    errmsg = "Exception,错误编码," + ex.HResult + ",错误消息," + _maxcommanderrorcount + "," + ex.Message + ",[" + SQL + "]";

                }
            }
            throw new MysqlProgressException("停止数据库操作超" + _maxcommanderrorcount + "最大重试次数,Run_SQL2," + nowaddress + "," + errmsg, new Exception(errmsg));
        }
[24 Nov 2020 15:16] Christine Cole
Posted by developer:
 
Fixed as of the upcoming MySQL Connector/NET 8.0.23 release, and here's the proposed changelog entry from the documentation team:

A connection timeout was added to prevent the MySqlConnection.Open method
from waiting indefinitely for a response after MySQL Router restarted
unexpectedly.

Thank you for the bug report.