MySQL .NET Connector: Ungwöhnliche Timeout Probleme (Connection Attributes)
MySQL .NET Connector: Ungwöhnliche Timeout Probleme (Connection Attributes)

Der MySQL .NET Connector ist der einfachste Weg um in C# einen MySQL Server abzufragen. So habe ich mein gesamtes CMS darauf aufgebaut und eine Klasse dafür geschrieben. Ich hatte bis jetzt die Version 6.6.4 im Einsatz. Beim aktualisieren hatte ich aber unerklärliche Timeouts bei der ersten Verbindung.

Das Problem lokalisieren

Ich konnte das Problem schlussendlich identifizieren das lediglich schon die Datenbankzugriffe ohne Polling immer ~5'000ms auf dem LIVE Server dauerte. Ohne Polling war die erste Verbindung auch über ~8'000ms danach aber sehr schnell bei ~25ms. Ich konnte das Problem mit meinem Hoster relativ schnell verifizieren.

Die Ursache

Seit der Version 6.6.5 bez. MySQL Server Version 5.6.6 wurden die so genannten Connection Attributes eingeführt. Dabei wird eine langsame WMI Abfrage erzeugt welche den ganzen Delay erzeugt.

  • MySql Server ab Version 5.6.6
  • MySql Connector/Net ab Version 6.6.5

Die Behebung

Im MySQL Forum bin ich auf einen Eintrag gestossen der genau meine Problematik behebt. So habe ich den Patch erfolgreich bei der Version 6.9.10 angewendet. Danach waren die Verbindungen alle bei ~15ms.

From e057f0de5b8507ba758f5811c75fe737c658bf6e Mon Sep 17 00:00:00 2001
From: szalicil <szalicil@gmail.com>
Date: Wed, 7 Sep 2016 11:56:52 +0200
Subject: [PATCH] client properties performance

---
 Source/MySql.Data/MysqlDefs.cs | 209 ++++++++++++++++++++++++-----------------
 1 file changed, 125 insertions(+), 84 deletions(-)

diff --git a/Source/MySql.Data/MysqlDefs.cs b/Source/MySql.Data/MysqlDefs.cs
index d8ed0da..92db977 100644
--- a/Source/MySql.Data/MysqlDefs.cs
+++ b/Source/MySql.Data/MysqlDefs.cs
@@ -423,132 +423,173 @@ namespace MySql.Data.MySqlClient
 
   internal class MySqlConnectAttrs
   {
-    [DisplayName("_client_name")]
-    public string ClientName
+#if !RT
+    static string pid;
+    static string version;
+    static string platform;
+    static string name;
+    static string os;
+    static string osDetails;
+    static string thread;
+
+    static MySqlConnectAttrs()
     {
-      get { return "MySql Connector/NET"; }
+      InitPid();
+      InitVersion();
+      InitPlatform();
+      InitName();
+      InitOs();
+      InitOsDetails();
+      InitThread();
     }
 
-#if !RT
-    [DisplayName("_pid")]
-    public string PID
+    private static void InitPid()
+    {
+      pid = string.Empty;
+      try
+      {
+        pid = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
+      }
+      catch (Exception ex)
+      {
+        System.Diagnostics.Debug.WriteLine(ex.ToString());
+      }
+    }
+
+    private static void InitVersion()
+    {
+      version = string.Empty;
+      try
+      {
+        version = Assembly.GetAssembly(typeof(MySqlConnectAttrs)).GetName().Version.ToString();
+      }
+      catch (Exception ex)
+      {
+        System.Diagnostics.Debug.WriteLine(ex.ToString());
+      }
+    }
+
+    private static void InitPlatform()
+    {
+      platform = Is64BitOS() ? "x86_64" : "x86_32";
+    }
+
+    private static void InitName()
+    {
+      name = Environment.CommandLine;
+      try
+      {
+        string path = Environment.CommandLine.Substring(0, Environment.CommandLine.IndexOf("\" ")).Trim('"');
+        name = System.IO.Path.GetFileName(path);
+        if (Assembly.GetEntryAssembly() != null)
+          name = Assembly.GetEntryAssembly().ManifestModule.Name;
+      }
+      catch (Exception ex)
+      {
+        name = string.Empty;
+        System.Diagnostics.Debug.WriteLine(ex.ToString());
+      }
+    }
+
+    private static void InitOs()
     {
-      get
+      os = string.Empty;
+      try
       {
-        string pid = string.Empty;
-        try
+        os = Environment.OSVersion.Platform.ToString();
+        if (os == "Win32NT")
         {
-          pid = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
+          os = "Win";
+          os += Is64BitOS() ? "64" : "32";
         }
-        catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); }
-
-        return pid;
+      }
+      catch (Exception ex)
+      {
+        System.Diagnostics.Debug.WriteLine(ex.ToString());
       }
     }
 
-    [DisplayName("_client_version")]
-    public string ClientVersion
+    private static void InitOsDetails()
     {
-      get
+      osDetails = string.Empty;
+      try
       {
-        string version = string.Empty;
-        try
+        var searcher = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem");
+        var collection = searcher.Get();
+        foreach (var mgtObj in collection)
         {
-          version = Assembly.GetAssembly(typeof(MySqlConnectAttrs)).GetName().Version.ToString();
+          osDetails = mgtObj.GetPropertyValue("Caption").ToString();
+          break;
         }
-        catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); }
-        return version;
+      }
+      catch (Exception ex)
+      {
+        System.Diagnostics.Debug.WriteLine(ex.ToString());
       }
     }
 
+    private static void InitThread()
+    {
+      thread = string.Empty;
+      try
+      {
+        thread = System.Diagnostics.Process.GetCurrentProcess().Threads[0].Id.ToString();
+      }
+      catch (Exception ex)
+      {
+        System.Diagnostics.Debug.WriteLine(ex.ToString());
+      }
+    }
+
+    [DisplayName("_client_name")]
+    public string ClientName
+    {
+      get { return "MySql Connector/NET"; }
+    }
+
+    [DisplayName("_pid")]
+    public string PID
+    {
+      get { return pid; }
+    }
+
+    [DisplayName("_client_version")]
+    public string ClientVersion
+    {
+      get { return version; }
+    }
+
     [DisplayName("_platform")]
     public string Platform
     {
-      get { return Is64BitOS() ? "x86_64" : "x86_32"; }
+      get { return platform; }
     }
 
     [DisplayName("program_name")]
     public string ProgramName
     {
-      get
-      {
-        string name = Environment.CommandLine;
-        try
-        {
-          string path = Environment.CommandLine.Substring(0, Environment.CommandLine.IndexOf("\" ")).Trim('"');
-          name = System.IO.Path.GetFileName(path);
-          if (Assembly.GetEntryAssembly() != null)
-            name = Assembly.GetEntryAssembly().ManifestModule.Name;
-        }
-        catch (Exception ex)
-        {
-          name = string.Empty;
-          System.Diagnostics.Debug.WriteLine(ex.ToString());
-        }
-        return name;
-      }
+      get { return name; }
     }
 
     [DisplayName("_os")]
     public string OS
     {
-      get
-      {
-        string os = string.Empty;
-        try
-        {
-          os = Environment.OSVersion.Platform.ToString();
-          if (os == "Win32NT")
-          {
-            os = "Win";
-            os += Is64BitOS() ? "64" : "32";
-          }
-        }
-        catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); }
-
-        return os;
-      }
+      get { return os; }
     }
 
     [DisplayName("_os_details")]
     public string OSDetails
     {
-      get
-      {
-        string os = string.Empty;
-        try
-        {
-          var searcher = new System.Management.ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem");
-          var collection = searcher.Get();
-          foreach (var mgtObj in collection)
-          {
-            os = mgtObj.GetPropertyValue("Caption").ToString();
-            break;
-          }
-        }
-        catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); }
-
-        return os;
-      }
+      get { return osDetails; }
     }
 
     [DisplayName("_thread")]
     public string Thread
     {
-      get
-      {
-        string thread = string.Empty;
-        try
-        {
-          thread = System.Diagnostics.Process.GetCurrentProcess().Threads[0].Id.ToString();
-        }
-        catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); }
-
-        return thread;
-      }
+      get { return thread; }
     }
 
-    private bool Is64BitOS()
+    private static bool Is64BitOS()
     {
 #if CLR4
       return Environment.Is64BitOperatingSystem;
-- 
2.9.0.windows.1


 

Blog-iT

Interessantes aus dem www, kleine Anekdoten, wissenswertes, Problembehandlungen aus der IT, meine Sammlung an virtuellen Merkzettelchen.
.
JahrArchiv
Tag(s):