Detaillierte Erläuterung des Ausführungsprinzips des MySQL-Kill-Befehls

Detaillierte Erläuterung des Ausführungsprinzips des MySQL-Kill-Befehls

Es gibt zwei Möglichkeiten, den Kill-Befehl zu schreiben: „Kill-Abfrage + Thread-ID“ und „Kill-Verbindung (optional) + Thread-ID“. Sie geben jeweils das Schließen der vom angegebenen Thread ausgeführten Anweisung und das Trennen der Verbindung des mit dem angegebenen Thread verbundenen Clients an (wenn gerade eine Operation ausgeführt wird, wird die Operation gestoppt, bevor die Verbindung geschlossen wird). Aber in manchen Fällen wird es nach der Verwendung von kill query und anschließendem Anzeigen der Befehlsspalte mit show processlist als beendet angezeigt (was bedeutet, dass es auf die Wiederverwendung des Recycling-Threads wartet, aber noch nicht wiederverwendet wurde). Warum ist das so?

Bevor Sie diese Frage beantworten können, müssen Sie wissen, wie der Thread ausgeführt wird, der die Anfragen auf dem Server verarbeitet, und wie der Kill-Befehl funktioniert.

Prinzip der Kill-Befehlsausführung

Eigenschaften der Befehlsausführung

1. Während der Ausführung einer Anweisung gibt es mehrere „vergrabene Punkte“. Der Thread-Status wird an diesen „vergrabenen Punkten“ beurteilt. Wenn der Thread-Status THD:KILL_QUERY lautet, wird die Anweisungsbeendigungslogik aufgerufen.

2. Wenn es sich in einem Wartezustand befindet, muss es ein Wartezustand sein, der aufgeweckt werden kann, sonst wird es überhaupt nicht bis zum "vergrabenen Punkt" ausgeführt.

3. Es gibt einen Prozess vom Beginn der Anweisung, die in die Beendigungslogik eintritt, bis zur Vervollständigung der Beendigungslogik.

Kill-Query-Ausführungsprinzip

Die Kill-Abfrage führt hauptsächlich zwei Schritte aus:

1. Ändern Sie den Ausführungsstatus des Threads in THD::KILL_QUERY (weisen Sie THD::KILL_QUERY die Variable „killed“ zu);

2. Senden Sie ein Signal an den Ausführungsthread der Sitzung, um den Blockierungszustand zu verlassen und diesen Zustand zu verarbeiten.

Implementierungsprinzip von Kill Connection

1. Setzen Sie den Status von Thread 12 auf KILL_CONNECTION;

2. Schalten Sie die Netzwerkverbindung von Thread 12 aus.

Kann es unterbrochen werden?

1. Im Allgemeinen wird nach der Ausführung der Kill-Abfrage der Status normal ausgeführter Anweisungen von „killed“ in „KILL_QUERY“ geändert und die Ausführung wird unterbrochen, wenn der „eingebettete Punkt“ erreicht wird.

2. Wenn es sich um eine blockierte Anweisung handelt, müssen Sie prüfen, ob der aktuelle blockierte Wartezustand aufgeweckt werden kann. Wenn dies möglich ist, besteht die Möglichkeit, die aktuelle Anweisung zu unterbrechen.

Szenarien, die unterbrochen werden können: normale Ausführung oder in einem blockierten Wartezustand, der aufgeweckt werden kann.

Da beim Warten auf die Zeilensperre die Funktion pthread_cond_timedwait verwendet wird, kann dieser Wartezustand aufgeweckt werden. Es kann direkt durch eine Kill-Abfrage aktiviert werden, um die Ausführung bis zur Entscheidung über den „Begrabungspunkt“ fortzusetzen.

Nicht unterbrechbare Szenarien: blockiert und können nicht geweckt werden.

Beispiel: Blockierung aufgrund fehlender gleichzeitiger Threads.

Setzen Sie den Parameter innodb_thread_concurrency (die Anzahl gleichzeitiger Threads für MySQL) auf 2. Gehen Sie dann wie folgt vor:

Nachdem Sitzung D die Kill-Abfrage C ausgeführt hat, verlässt Sitzung C den Blockierungszustand nicht.

  • Frage 1: Warum unterbricht das Beenden der Abfrage den Blockierungsprozess nicht?

Antwort: Weil diese Art der Blockade aus mikroskopischer Sicht keine Blockade ist, sondern ein Zirkelschluss. Alle 10 Millisekunden wird festgestellt, ob Innodb zur Ausführung aufgerufen werden kann. Wenn nicht, wird die Nanosleep-Funktion aufgerufen, um in den Ruhezustand zu wechseln. Das heißt, obwohl der Thread-Status auf KILL_QUERY (THD::KILL_QUERY) gesetzt wurde, wird der „vergrabene Punkt“ während der Schleife, in der auf den Eintritt in InnoDB gewartet wird, nicht ausgeführt und der Thread-Status wird nicht beurteilt, sodass die Phase der Beendigungslogik überhaupt nicht betreten wird. Es kommt also zu keiner Unterbrechung.

  • Frage 2: Wenn Sie die Prozessliste anzeigen, werden Sie feststellen, dass der Befehl als beendet aufgeführt wird. Warum ist das so?

Antwort: Die Kill-Abfrageanweisung setzt den Thread-Status auf KILL_QUERY. Zu diesem Zeitpunkt wird aufgrund dieses Status davon ausgegangen, dass eine Interrupt-Logik ausgeführt wird, sodass der Befehlswert beendet wird.

  • Frage 3: Warum kann das Trennen einer Verbindung den Blockierungsprozess unterbrechen?

Antwort: Da durch „Kill Connection“ die Netzwerkverbindung des Threads direkt geschlossen und zum Schließen gezwungen wird, erhält Sitzung C zu diesem Zeitpunkt eine Aufforderung zur Trennung der Verbindung.

  • Frage 4: Wann kann die Blockierung unterbrochen werden, wenn nur eine Kill-Abfrage verwendet wird?

Antwort: Das Programm wird erst beendet, wenn der Sitzung ein Thread zugewiesen wird und die Ausführung den „eingebetteten Punkt“ erreicht. Anschließend wird die Interrupt-Logik ausgeführt. Nachdem ein Thread zugewiesen wurde, wird er jedoch nicht unbedingt unterbrochen. Wenn der Thread freigegeben wird, bevor die Ausführung den "vergrabenen Punkt" erreicht, wartet er erneut. MySQL-Threads werden multiplexiert.

andere

1. Tatsächlich können Sie den Blockierungszustand nicht nur mit dem Kill-Befehl beenden, sondern auch direkt in der Sitzung mit „Strg+C“ beenden. Was ist das Prinzip dahinter?

Antwort: Zunächst müssen Sie wissen, dass der Client den Server betreibt, indem er einen Thread auf dem Client öffnet, diesen Thread verarbeiten lässt, Anforderungsdaten sendet, sie über das Netzwerk an den Server überträgt und der Server dann einen Thread zur Verarbeitung zuweist. „Strg + C“ weist den Client an, eine weitere Verbindung zu öffnen und einen Kill-Query-Befehl zu senden. Obwohl es so aussieht, als hätten wir die Blockierung unterbrochen, wird der Server-Thread, der die vorherige Verbindung verarbeitet hat, nicht unbedingt unterbrochen.

2. Warum ist die Verbindung durch Angabe des Bibliotheksnamens so langsam? Wie unten dargestellt:

Antwort: Dies liegt daran, dass die Autovervollständigungsfunktion von MySQL standardmäßig aktiviert ist (Sie können bei der Eingabe von Tabellennamen die Tabulatortaste zur automatischen Vervollständigung verwenden). Seine Implementierung besteht darin, bei der Verbindung mit der Datenbank einige weitere Vorgänge auszuführen:

1. Führen Sie „Datenbanken anzeigen“ aus.
2. Wechseln Sie zur Datenbank db1 und führen Sie „show tables“ aus.
3. Verwenden Sie die Ergebnisse dieser beiden Befehle, um eine lokale Hash-Tabelle zu erstellen. (Am zeitaufwendigsten)

Diese Funktion kann deaktiviert werden, indem dem Befehl -A hinzugefügt wird. Es kann auch mit -quick deaktiviert werden. Die Verwendung von -quick kann jedoch die Clientleistung beeinträchtigen. warum ist das so? Damit kommen wir zum Prozess des Datenübertragung zwischen Server und Client.

Ausführungsfluss des Server-Threads

Der Client überprüft zunächst den Benutzernamen und das Kennwort beim Server. Nach der Überprüfung wird eine Verbindung formal hergestellt. Der Client sendet dann eine Anforderung, und der Server nimmt einen Thread aus dem Thread-Pool, um diese zu verarbeiten. Verarbeitungsprozess:

1. Holen Sie sich eine Zeile und schreiben Sie sie in den Net_Buffer. Die Größe dieses Speichers wird durch den Parameter net_buffer_length definiert, der standardmäßig 16 KB beträgt.
2. Rufen Sie wiederholt Zeilen ab, bis der Netzpuffer voll ist, und rufen Sie dann die Netzwerkschnittstelle auf, um sie zu senden.
3. Wenn die Übertragung erfolgreich ist, löschen Sie den Net_Buffer, fahren Sie dann mit der nächsten Zeile fort und schreiben Sie sie in den Net_Buffer.
4. Wenn die Sendefunktion EAGAIN oder WSAEWOULDBLOCK zurückgibt, bedeutet dies, dass der lokale Netzwerkstapel (Socket-Sendepuffer) voll ist und in den Wartezustand wechselt. Warten Sie, bis der Netzwerkstapel wieder beschreibbar ist, bevor Sie mit dem Senden fortfahren.

Aus dem obigen Prozess können wir erkennen, dass, wenn die auf einmal zu sendende Datenmenge den Sendepufferspeicherplatz des Sockets überschreitet, die Daten aufgeteilt und gesendet werden und es nicht zu einer „Speicherexplosion“ kommt. Daraus können wir erkennen, dass MySQL gleichzeitig liest und sendet.

1. Wenn die von der Anforderung zurückgegebene Datenmenge groß ist, überprüfen Sie beim Warten auf die Rückgabe mit „show processlist“ den Wert der Spalte „Status“. Er lautet „An Client senden“, was darauf hinweist, dass der Netzwerkstapel auf der Serverseite voll ist.

Dies liegt daran, dass sich der Wert der Spalte „Sate“ ändert, wenn die Abfrageanforderung eintrifft und ausgeführt wird, und er wird zu „Daten werden gesendet“. Wenn der Netzwerkstapel voll ist, wechselt er zu „An Client senden“, was bedeutet, dass „auf den Client gewartet wird, bis er das Ergebnis erhält“. Das „Senden von Daten“ kann sich in jeder Phase des Thread-Ausführungsprozesses befinden, z. B. wenn es durch eine Sperre blockiert ist.

2. Wenn die Spalte Status der Prozessliste immer "Senden an Client" lautet, dann können Sie

1) Überprüfen Sie diese SQL-Anweisung, um zu sehen, ob sie optimiert werden kann, um den Rückgabewert zu reduzieren.

2) Setzen Sie net_buffer_length auf einen größeren Wert, um eine Sendeblockierung zu vermeiden oder die Dauer zu verkürzen.

Client-Ausführungsprozess

Zu Beginn erstellt der Client einen Thread, um eine Verbindung zum Server herzustellen, und empfängt dann die vom Server zurückgegebenen Daten. Der Client kann die vom Server zurückgegebenen Daten auf zwei Arten empfangen:

1. Lokaler Cache. Öffnen Sie lokal einen Speicherbereich und speichern Sie zunächst die Ergebnisse. Wenn Sie mithilfe der API entwickeln, ist die entsprechende Methode mysql_store_result. Bei einem großen Client-Verarbeitungsvolumen empfiehlt sich die Verwendung eines lokalen Cache. Sie können mysql -h$host -P$port -u$user -p$pwd -e "select * from db1.t" > $target_file verwenden, um die zurückgegebenen Daten in der angegebenen Datei zu speichern.

2. Kein Caching, jeweils einzeln lesen und verarbeiten. Wenn Sie mithilfe der API entwickeln, lautet die entsprechende Methode mysql_use_result.

Zurück zur obigen Frage: Warum kann die Verwendung von -quick zu einer Verschlechterung der Client-Leistung führen? Dies liegt daran, dass der Client den Cache standardmäßig zum Empfangen verwendet. Wenn der Client also andere Daten verarbeitet, kann er diese zuerst zwischenspeichern und den Cache später direkt lesen. Die Verwendung von quick bewirkt, dass der Client Daten empfängt, ohne den Cache zu verwenden. Wenn der Client andere Vorgänge ausführt, werden die Daten blockiert und der entsprechende Thread auf dem Server unterbricht die Transaktion nicht, da er kein Feedback vom Client erhalten hat. Die an dieser Transaktion beteiligten Ressourcensperren werden nicht freigegeben, was zu Parallelitätsproblemen führt und die Effizienz beeinträchtigt. Darüber hinaus verfügt Quick über drei weitere Effekte.

1. Überspringen Sie, wie bereits erwähnt, die automatische Vervollständigungsfunktion des Tabellennamens.
2. Der Client empfängt Daten ohne Caching. Die Methode mysql_store_result muss lokalen Speicher beantragen, um Abfrageergebnisse zwischenzuspeichern. Wenn die Abfrageergebnisse zu groß sind, wird mehr lokaler Speicher verbraucht und die Leistung des lokalen Computers des Clients kann beeinträchtigt werden.
3. Die ausgeführten Befehle werden nicht in der lokalen Befehlsverlaufsdatei aufgezeichnet.

Oben finden Sie eine ausführliche Erläuterung des Ausführungsprinzips des MySQL-Kill-Befehls. Weitere Informationen zum MySQL-Kill-Befehl finden Sie in den anderen verwandten Artikeln auf 123WORDPRESS.COM!

Das könnte Sie auch interessieren:
  • MySQL-Kill-Befehl – ​​Verwendungshandbuch
  • Lösung für das versehentliche Löschen von Daten in MySQL und Kill-Anweisungsprinzip
  • Mysql verwendet den Kill-Befehl, um das Deadlock-Problem zu lösen (eine bestimmte SQL-Anweisung, die ausgeführt wird, abzubrechen).
  • Lösung für MySQL Slave, der Oom-Killer auslöst
  • MySQL OOM-Serie 3: Befreien Sie sich vom Pech, dass MySQL abgeschafft wurde
  • MySQL OOM System 2 OOM-Killer
  • pt-kill-Methode des Percona-Toolkits zum Beenden von MySQL-Abfragen oder -Verbindungen
  • Batch-Kill-SQLs, die für eine lange Zeit in MySQL ausgeführt werden
  • Gründe, warum MySQL Kill Threads nicht beenden kann

<<:  So verwenden Sie benutzerdefinierte Tags in HTML

>>:  CSS3-Mobil-Vw+Rem-Methode zum Erreichen eines reaktionsfähigen Layouts ohne Abhängigkeit von JS

Artikel empfehlen

Detaillierte Erklärung der Javascript-String-Methoden

Inhaltsverzeichnis Zeichenfolgenlänge: Länge char...

JS implementiert die Benutzerregistrierungsschnittstellenfunktion

In diesem Artikelbeispiel wird der spezifische JS...

Detaillierte Erklärung der Angular-Komponentenprojektion

Inhaltsverzeichnis Überblick 1. Einfaches Beispie...

Der Unterschied zwischen KEY, PRIMARY KEY, UNIQUE KEY und INDEX in MySQL

Das im Titel angesprochene Problem lässt sich sch...

So kapseln Sie Abfragekomponenten basierend auf Element-UI Schritt für Schritt

Inhaltsverzeichnis Funktion Grundlegende Abfragef...

Implementierung der Header-Informationen für Nginx-Operationsantworten

Voraussetzung: Sie müssen das Modul ngx_http_head...

MySQL-Abfragemethode mit mehreren Bedingungen

MySQL-Abfrage mit mehreren Bedingungen Umgebung: ...

js zur Implementierung einer Interferenz mit Verifizierungscodes (statisch)

In diesem Artikel wird der spezifische Code von j...

Wie setze ich eine Unterstreichung in HTML? So unterstreiche ich Text in HTML

Früher bestand das Unterstreichen in HTML darin, ...

Grundlegende Anwendungsbeispiele für benannte Slots in Vue

Vorwort Benannte Slots werden mithilfe des Attrib...