Client-Timeout, während MySQL-Abfrage ausgeführt wird?

9

Wir hatten ein Problem, bei dem eine schreibgeschützte Abfrage, die über die MySQL-Workbench ausgeführt wurde, aus Sicht der Benutzeroberfläche eines Benutzers eine Zeitüberschreitung aufwies und auf dem Server ausgeführt wurde (und anscheinend immer mehr Ressourcen verbrauchte), bis wir einen Ausfall hatten.

Fragen

  • Gibt es eine Standardmethode, um mit solchen Problemen in MySQL umzugehen?
  • Gibt es eine grundlegende Ursache, die wir vermeiden müssen?
asthasr
quelle

Antworten:

11

Sie müssen sich ansehen, welche Standardwerte für Zeitüberschreitungen vorhanden sind:

mysql> show variables like '%timeout';
+----------------------------+-------+
| Variable_name              | Value |
+----------------------------+-------+
| connect_timeout            | 10    |
| delayed_insert_timeout     | 300   |
| innodb_lock_wait_timeout   | 50    |
| innodb_rollback_on_timeout | OFF   |
| interactive_timeout        | 60    |
| net_read_timeout           | 30    |
| net_write_timeout          | 60    |
| slave_net_timeout          | 3600  |
| table_lock_wait_timeout    | 50    |
| wait_timeout               | 60    |
+----------------------------+-------+
10 rows in set (0.00 sec)

Normalerweise achte ich auf mehrere Timeout-Variablen. Dies ist sehr wichtig, wenn Sie MySQL remote von MySQL Workbench, MySQL-Client oder PHP-App auf einem App-Server verwenden und MySQL auf einem DB-Server kontaktieren.

In der MySQL-Dokumentation steht Folgendes zu folgenden Einstellungen:

  • wait_timeout (Standard 28800 [8 Stunden]): Die Anzahl der Sekunden, die der Server auf die Aktivität einer nicht interaktiven Verbindung wartet, bevor er diese schließt. Dieses Zeitlimit gilt nur für TCP / IP- und Unix-Socket-Dateiverbindungen, nicht für Verbindungen, die über Named Pipes oder gemeinsam genutzten Speicher hergestellt wurden. Beim Start des Threads wird der Wert für "wait_timeout" der Sitzung je nach Clienttyp aus dem globalen Wert "wait_timeout" oder aus dem globalen Wert "interaktives Zeitlimit" initialisiert (wie durch die Verbindungsoption CLIENT_INTERACTIVE zu mysql_real_connect () definiert). Siehe auch interactive_timeout.
  • Interactive_timeout (Standard 28800 [8 Stunden]): Die Anzahl der Sekunden, die der Server auf die Aktivität einer interaktiven Verbindung wartet, bevor er diese schließt. Ein interaktiver Client ist als Client definiert, der die Option CLIENT_INTERACTIVE für mysql_real_connect () verwendet. Siehe auch wait_timeout.
  • net_read_timeout (Standard 30): Die Anzahl der Sekunden, die auf weitere Daten von einer Verbindung gewartet werden muss, bevor der Lesevorgang abgebrochen wird. Wenn der Server vom Client liest, ist net_read_timeout der Timeout-Wert, der steuert, wann abgebrochen werden soll. Wenn der Server auf den Client schreibt, ist net_write_timeout der Timeout-Wert, der steuert, wann der Vorgang abgebrochen werden soll. Siehe auch Slave_net_timeout.
  • net_write_timeout (Standard 60): Die Anzahl der Sekunden, die gewartet werden muss, bis ein Block in eine Verbindung geschrieben wurde, bevor der Schreibvorgang abgebrochen wird. Siehe auch net_read_timeout.

Stellen Sie sicher, dass diese Zeitüberschreitungen hoch genug sind, um Abfragen zu berücksichtigen, die möglicherweise sehr lange ausgeführt werden. Dazu gehören:

  • Masse UPDATEs
  • Masse DELETEs
  • ENABLE KEYS auf einem großen MyISAM

Um Abfragen zu bearbeiten, die weiter ausgeführt werden, nachdem Sie den Kontakt verloren haben, müssen Sie KILL für die Prozess-ID der lang laufenden Abfrage ausführen . Selbst mit dem Befehl KILL müssen Sie auf alle Abfragen warten, die sich mitten in festplattenintensiven Schritten befinden oder interne Mutexe ausführen.

RolandoMySQLDBA
quelle
Gibt es eine standardmäßige, robuste Methode, um KILL für Prozesse auszuführen, die schon lange ausgeführt werden, oder erfolgt dies normalerweise über ein Bash-Skript / einen Cron-Job?
Asthasr
Ich habe bereits im Mai 2011 einen Beitrag darüber geschrieben, wie man ein Skript mit dem information_schema startet, um eine Reihe von DB-Verbindungen zu beenden
RolandoMySQLDBA
"Bitte stellen Sie sicher, dass diese Zeitüberschreitungen hoch genug sind, um Abfragen aufzunehmen, die möglicherweise sehr lange ausgeführt werden. Dazu gehören: Massen-UPDATEs ..." Beispiel: php + mysql Ich muss jeden Datensatz aus einer Tabellenspalte auswählen, also abrufen Zeilen und dann etwas tun ... dann einen anderen Datensatz mit einem neuen Wert aktualisieren. Stellen Sie den Fall auf, dass dieses Skript mehr als 5 Minuten benötigt. Ein SELECT am Anfang und ein UPDATE am Ende, Zeilen abrufen und ... in der Mitte. Können Sie erklären, was das wait_timeout in dieser Situation zu tun hat? Wirklich ist mir nicht klar ... was ist ein sicherer Wert für wait_timeout, um Ressourcen