Analyse und Lösung der MySQL-Verbindung, die den Fehler „Authentifizierung fehlgeschlagen“ auslöst

Analyse und Lösung der MySQL-Verbindung, die den Fehler „Authentifizierung fehlgeschlagen“ auslöst

[Problembeschreibung]

Auf der Anwendungsseite wird gelegentlich der folgende Fehler angezeigt:

Die Authentifizierung beim Host „xxxx“ für den Benutzer „yyyy“ mit der Methode „mysql_native_password“ ist mit der Meldung fehlgeschlagen: Das Lesen aus dem Stream ist fehlgeschlagen.

Leistungsmerkmale:

1. Dieses Problem tritt nur bei Verwendung von Connector/NET auf. Bei Verwendung des JDBC-Treibers gibt es kein ähnliches Problem.

2. Es gibt mehrere Anwendungsserver, aber nur einer meldet diesen Fehler, sodass das Problem auf der Serverseite ausgeschlossen werden kann.

3. Das Problem tritt sehr zufällig auf. Ein Neustart des Servers/IIS kann das Problem vorübergehend lösen.

4. In einigen Szenarien ist die CPU-Auslastung des Anwendungsservers nicht sehr hoch und dieser Fehler kann gelegentlich auftreten.

Der Client ist eine Windows-Maschine, der Treiber ist MySQL Connector ADO.NET Driver for MySQL (Connector/NET) und die verwendete Version ist 6.9.9, also eine relativ neue Version.

Werfen wir einen Blick auf die detaillierte Analyse und Lösungen.

【Problemanalyse】

Wir erfassen Pakete auf der Anwendungsserver- und Datenbankseite. Die von beiden Seiten erfassten Pakete sind konsistent. Netzwerkprobleme können ausgeschlossen werden. Nachfolgend sind die erfassten Pakete und Zeitpunkte aufgeführt:

Seriennummer Absolute Zeit Relative Zeit (Sekunden) Quelle Zweck Inhalt der Netzwerkpakete
1 12:58:47 9.07 Anwendungsserver Datenbankserver ......S.
2 12:58:47 9.07 Datenbankserver Anwendungsserver …ALS.
3 12:58:47 9:07 Anwendungsserver Datenbankserver …A….
4 12:58:47 9:07 Datenbankserver Anwendungsserver …AP…
5 12:58:47 9.27 Anwendungsserver Datenbankserver …A….
6 12:58:57 19.12 Datenbankserver Anwendungsserver …A…F
7 12:58:57 19.12 Anwendungsserver Datenbankserver …A….
8 12:59:10 32,00 Anwendungsserver Datenbankserver …AP…
9 12:59:10 32,00 Datenbankserver Anwendungsserver …..R..

Gemessen an der Interaktion der obigen Netzwerkpakete handelt es sich bei den ersten drei Paketen um das Drei-Wege-Handshake-Protokoll von TCP. Das Problem liegt im sechsten Paket. Der Datenbankserver sendet ein Finish-Paket an den Anwendungsserver, um die Datenbankverbindung zu beenden. Die Datenbank sendet ein Finish-Paket, weil sie feststellt, dass die Verbindung abgelaufen ist. Dies wird durch die Variable Connect_timeout auf der Serverseite gesteuert. Der Grund liegt darin, dass die Anwendung seit mehr als 10 Sekunden kein Netzwerkpaket an den Datenbankserver gesendet hat. Gemessen an der Netzwerkpaketinteraktion beträgt das Zeitintervall zwischen dem fünften und sechsten Paket genau 10 Sekunden.

Vergleichen Sie oben die normale Datenbankverbindung mit der abnormalen Datenbankverbindung. Nachdem der Anwendungsserver das fünfte Paket an die Datenbank gesendet hat, sollte er sofort das folgende Netzwerkpaket an die Datenbank senden. Dieses Paket sendet hauptsächlich Kontonummer, Treiberversion, Betriebssysteminformationen usw. an den Datenbankserver. [Unten sind einige Screenshots von normalen Netzwerkpaketen]. Im Falle eines abnormalen Fehlers verzögert der Client das Senden des Pakets. Es wird in Frame 8 gesendet. Zu diesem Zeitpunkt ist die Verbindung beendet. In Frame 9 sendet die Datenbank ein Reset-Paket an den Anwendungsserver und beendet damit die Verbindung vollständig.

Lassen Sie uns nun im Detail analysieren, warum der Client so langsam ist, wenn er Konto-, Treiberversions- und Betriebssysteminformationen an die Datenbank sendet. Dieser Teil des Codes befindet sich in der Datei Connector/NET MySQLAuthenticationPlugin.cs. Wir ändern diesen Teil des Codes und führen eine Zeiterfassung durch, um das Problem weiter zu lokalisieren. Nachfolgend werden die Tracking-Informationen je nach Zeitpunkt ausgedruckt.

Laut Trace kommt es zu einer Betriebsverzögerung von ca. 30 Sekunden. Wenn MySQLDefs::OSDetails zurückgegeben wird. Dieser Teil des Codes lautet wie folgt:

[DisplayName("_os_details")]

öffentliche Zeichenfolge OSDetails

{

erhalten

{

Zeichenfolge os = Zeichenfolge.Leer;

versuchen

{

var searcher = neues System.Management.ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem");

var Sammlung = Sucher.Get();

foreach (var mgtObj in Sammlung)

{

os = mgtObj.GetPropertyValue("Beschriftung").ToString();

brechen;

}

}

abfangen (Ausnahme Beispiel) { System.Diagnostics.Debug.WriteLine(ex.ToString()); }

Rückkehr-OS;

}

}

Dieser Code erhält die Untertitelinformationen über eine WMI-Abfrage. Das heißt, die Versionsinformationen des Betriebssystems. Da es sich um einen WMI-Aufruf handelt, bestehen zahlreiche Abhängigkeiten.

【Problemüberprüfung】

Lassen Sie uns diesen Code extrahieren. Hier ist ein kurzer Reproduktionscode:

statischer void Main(string[] args)

{

Stoppuhr watch = neue Stoppuhr();

während (wahr)

{

beobachten.Neustart();

var searcher = neues System.Management.ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem");

var Sammlung = Sucher.Get();

foreach (var mgtObj in Sammlung)

{

Zeichenfolge os = mgtObj.GetPropertyValue("Beschriftung").ToString();

}

uhr.Stopp();

Console.WriteLine(watch.ElapsedMilliseconds);

wenn (watch.ElapsedMilliseconds >= 1000)

{

Console.WriteLine("-------------");

File.AppendAllText("abc.txt", DateTime.Now.ToString("jjjj-MM-tt HH:mm:ss.fff") +","+ watch.ElapsedMilliseconds + "\r\n");

}

}

}

Wenn wir den obigen Code auf dem problematischen Anwendungsserver ausführen, können wir tatsächlich feststellen, dass die WMI-Abfrage abgelaufen ist: Die folgenden Punkte sind die Punkte, an denen wir mehr als 30 Sekunden erfasst haben:

21.11.2017 17:19:30.208, 33638

21.11.2017 17:20:09.193, 33199

21.11.2017 17:20:53.086, 33201

21.11.2017 17:27:05.114, 32976

21.11.2017 17:28:19.178, 33635

21.11.2017 17:30:07.130, 65977

21.11.2017 17:30:49.051, 40478

21.11.2017 17:31:15.126, 26072

21.11.2017 17:38:16.048, 66671

21.11.2017 17:38:49.204, 33152

21.11.2017 17:39:53.161, 33828

21.11.2017 17:40:38.121, 33549

21.11.2017 17:47:09.179, 33775

21.11.2017 17:47:57.174, 33164

【Lösung】

Langsame WMI-Abfragen können verschiedene Ursachen haben. Beispielsweise ist die CPU-Auslastung des Betriebssystems hoch oder die Abfrage selbst ist blockiert. Dieses Problem bedarf einer weiteren Analyse. Wenn wir uns jedoch den Code ansehen, wissen wir, dass diese WMI-Abfrage nur dazu dient, Informationen über das Betriebssystem abzurufen. Diese Informationen können zwischengespeichert werden. Es ist nicht erforderlich, bei jeder Verbindung eine WMI-Abfrage durchzuführen.

Die Hauptursache des Fehlers liegt darin, dass das Abrufen von Betriebssysteminformationen im MySQL C#-Connector zu lange dauert, was zu einer Zeitüberschreitung der Verbindung mit dem Trigger-Server führt. Kommentieren Sie diesen Teil aus (der zu langen Vorgängen führen kann) und führen Sie eine weitere Überprüfung durch. Es treten keine Timeout-Fehler auf.

öffentliche Zeichenfolge OSDetails
{
erhalten
{
dbglog.dolog("MysqlDefs::OSDetails1");
Zeichenfolge os = Zeichenfolge.Leer;
/*versuchen
{
var searcher = neues System.Management.ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem");
var Sammlung = Sucher.Get();
foreach (var mgtObj in Sammlung)
{
os = mgtObj.GetPropertyValue("Beschriftung").ToString();
dbglog.dolog(String.Format("MysqlDefs::OSDetails::foreach{0}", os.ToString()));
brechen;
}
}
abfangen (Ausnahme Beispiel) { System.Diagnostics.Debug.WriteLine(ex.ToString()); }*/
dbglog.dolog("MysqlDefs::OSDetails2");
Rückkehr-OS;
}
}

Zusammenfassen

Das Obige ist der vollständige Inhalt dieses Artikels. Ich hoffe, dass der Inhalt dieses Artikels einen gewissen Lernwert für Ihr Studium oder Ihre Arbeit hat. Wenn Sie Fragen haben, können Sie eine Nachricht hinterlassen. Vielen Dank für Ihre Unterstützung von 123WORDPRESS.COM.

Das könnte Sie auch interessieren:
  • mysql_connect(): Verbindung mit altem (vor 4.1.1) Authentifizierungsprotokoll abgelehnt
  • Lösung für „Client unterstützt keine Authentifizierung“ in MySQL
  • Lösung für das Problem „Client unterstützt kein Authentifizierungsprotokoll“ bei der Verbindung mit MySQL Version 4.1 oder höher

<<:  Detaillierte Erklärung zur Verwendung von nohup /dev/null 2>&1

>>:  So installieren Sie Tomcat-8.5.39 auf centos7.6

Artikel empfehlen

Detaillierte Erklärung der Methode getBoundingClientRect() in js

1. getBoundingClientRect() Analyse Die Methode ge...

Tutorial-Diagramm zur Konfiguration der Tomcat-Umgebungsvariablen unter Win10

Vor der Konfiguration müssen wir Folgendes tun: 1...

MySQL-Operationen: Operationen mit JSON-Datentyp

Im vorherigen Artikel haben wir das ausführliche ...

JavaScript zum Erreichen eines Mouse-Tailing-Effekts

Mauseffekte erfordern die Verwendung von setTimeo...

Detailliertes Installationstutorial für Zabbix 4.04 (basierend auf CentOS 7.6)

1. Vorbereitung vor der Installation: 1.1 JDK ins...

Was bedeutet das „a“ in rgba? CSS RGBA-Farbleitfaden

RGBA ist eine CSS-Farbe, mit der Farbwert und Tra...

Die 6 effektivsten Möglichkeiten zum Schreiben von HTML und CSS

In diesem Artikel werden die sechs wirksamsten Me...

Mysql Workbench - Abfragemethode für MySQL-Datenbanken

Mysql Workbench ist ein Open-Source-Datenbankclie...

MySql-Import - CSV-Datei oder tabulatorgetrennte Datei

Manchmal müssen wir Daten aus einer anderen Bibli...

Javascript Blob-Objekt zum Erzielen eines Dateidownloads

Inhaltsverzeichnis veranschaulichen 1. Blob-Objek...