Upłynął limit czasu klienta, podczas gdy zapytanie MySQL nadal działa?

9

Wystąpił problem polegający na tym, że zapytanie tylko do odczytu, uruchamiane przez środowisko robocze MySQL, przekroczyło limit czasu z punktu widzenia interfejsu użytkownika i pozostawało uruchomione na serwerze (i najwyraźniej zużywało coraz więcej zasobów) aż do awarii.

pytania

  • Czy istnieje standardowy sposób radzenia sobie z tego rodzaju problemami w MySQL?
  • Czy istnieje podstawowa przyczyna, której musimy unikać?
asthasr
źródło

Odpowiedzi:

11

Musisz sprawdzić, jakie wartości domyślne obowiązują w przypadku przekroczenia limitu czasu:

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)

Zwykle obserwuję kilka zmiennych limitu czasu. Jest to bardzo konieczne, jeśli używasz MySQL zdalnie z MySQL Workbench, klienta mysql lub aplikacji PHP na serwerze aplikacji kontaktującym się z MySQL na serwerze DB.

Oto, co mówi Dokumentacja MySQL, jeden z tych ustawień:

  • wait_timeout (Domyślnie 28800 [8 godzin]): Liczba sekund, przez które serwer czeka na aktywność na nieinteraktywnym połączeniu przed jego zamknięciem. Limit czasu dotyczy tylko połączeń plików gniazd TCP / IP i Unix, a nie połączeń wykonanych przy użyciu nazwanych potoków lub pamięci współużytkowanej. Podczas uruchamiania wątku wartość wait_timeout sesji jest inicjowana z globalnej wartości wait_timeout lub z globalnej wartości Interactive_timeout, w zależności od typu klienta (zgodnie z opcją połączenia CLIENT_INTERACTIVE z mysql_real_connect ()). Zobacz także: Interactive_timeout.
  • czas_aktywny (domyślnie 28800 [8 godzin]): liczba sekund, przez które serwer czeka na aktywność na połączeniu interaktywnym przed jego zamknięciem. Klient interaktywny jest zdefiniowany jako klient, który korzysta z opcji CLIENT_INTERACTIVE do mysql_real_connect (). Zobacz także wait_timeout.
  • net_read_timeout (domyślnie 30): liczba sekund oczekiwania na więcej danych z połączenia przed przerwaniem odczytu. Gdy serwer czyta od klienta, net_read_timeout to wartość limitu czasu kontrolująca, kiedy należy przerwać. Gdy serwer pisze do klienta, net_write_timeout to wartość limitu czasu kontrolująca, kiedy należy przerwać. Zobacz także slave_net_timeout.
  • net_write_timeout (domyślnie 60): liczba sekund oczekiwania na zapisanie bloku do połączenia przed przerwaniem zapisu. Zobacz także net_read_timeout.

Upewnij się, że te limity czasu są wystarczająco wysokie, aby uwzględnić zapytania, które mogą być uruchamiane przez bardzo długi czas, w tym:

  • Masa UPDATEs
  • Masa DELETEs
  • ENABLE KEYS na dużym MyISAM

Aby poradzić sobie z zapytaniami, które są uruchamiane po utracie kontaktu, musisz uruchomić KILL dla identyfikatora procesu dla długo działającego zapytania. Nawet z poleceniem KILL będziesz musiał czekać na każde zapytanie, które jest w trakcie intensywnych operacji na dysku lub w toku mają wewnętrzne muteksy.

RolandoMySQLDBA
źródło
Czy istnieje standardowy, niezawodny sposób uruchamiania KILL na procesach, które działały od dłuższego czasu, czy zwykle odbywa się to za pomocą skryptu bash / zadania cron?
asthasr
Napisałem post w maju 2011 r. O tym, jak uruchomić skrypt za pomocą programu information_schema, aby zabić kilka połączeń DB: dba.stackexchange.com/a/2637/877
RolandoMySQLDBA
„Upewnij się, że limity czasu są wystarczająco wysokie, aby uwzględnić zapytania, które mogą być uruchamiane przez bardzo długi czas, w tym: Mass UPDATEs ...” przykład: php + mysql muszę wybrać każdy rekord z kolumny tabeli, więc pobierz wiersze, a następnie zrób coś ... a następnie zaktualizuj kolejny rekord o nową wartość. Załóżmy, że ten skrypt wymaga około 5 minut. Jeden SELECT na początku i jeden UPDATE na końcu, pobierz wiersze i wykonaj ... w środku. Czy możesz wyjaśnić, co ma wspólnego z oczekiwaniem w tej sytuacji? Naprawdę nie jest dla mnie jasne ... jaka jest bezpieczna wartość wait_timeout do darmowego zasobu