Błąd MySQL podczas odczytu pakietów komunikacyjnych

42

W dziennikach błędów MySQL widzę kilka takich ostrzeżeń:

120611 16:12:30 [Warning] Aborted connection 2619503 to db: 'db_name' user: 'user_name' host: 'webapp_hostname' (Got an error reading communication packets)

Nie zauważyłem żadnej utraty danych per se, więc zastanawiam się, co oznacza to ostrzeżenie lub co go powoduje i jak można rozwiązać problem powodujący to ostrzeżenie. Dotyczy to wersji RHEL 6.1 i MySQL Enterprise 5.5.

KM.
źródło

Odpowiedzi:

50

Jednym z cichych zabójców połączeń MySQL jest pakiet MySQL.

Najpierw dowiedzmy się, czym jest pakiet MySQL.

Zgodnie ze stroną 99 „Understanding MySQL Internal” (ISBN 0-596-00957-7) , oto akapity 1-3 wyjaśniające pakiety MySQL:

Kod komunikacji sieciowej MySQL został napisany przy założeniu, że zapytania są zawsze dość krótkie, a zatem mogą być wysyłane i przetwarzane przez serwer w jednym kawałku, co w terminologii MySQL nazywa się pakietem . Serwer przydziela pamięć tymczasowemu buforowi do przechowywania pakietu i żąda wystarczającej ilości, aby go całkowicie dopasować. Ta architektura wymaga środków ostrożności, aby uniknąć wyczerpania pamięci serwera --- ograniczenie rozmiaru pakietu, co osiąga ta opcja.

Kod zainteresowania związany z tą opcją znajduje się w sql / net_serv.cc . Spójrz na my_net_read () , a następnie postępuj zgodnie z wywołaniem my_real_read () i zwróć szczególną uwagę na net_realloc () .

Ta zmienna ogranicza również długość wyniku wielu funkcji strunowych. Aby uzyskać szczegółowe informacje, zobacz sql / field.cc i sql / intem_strfunc.cc .

Wiedza na temat pakietów MySQL pozwala programistom / DBA na ich rozmiar, aby pomieścić wiele BLOBów w jednym pakiecie, nawet jeśli są nieprzyzwoicie duże. Zdecydowanie zbyt mały pakiet spowoduje pod tym względem problemy dla otwartych połączeń.

Według dokumentacji MySQL

  • Te błędy można również uzyskać, wysyłając zapytanie do serwera, które jest niepoprawne lub zbyt duże. Jeśli mysqld otrzyma pakiet, który jest zbyt duży lub nie działa, zakłada, że ​​coś poszło nie tak z klientem i zamyka połączenie. Jeśli potrzebujesz dużych zapytań (na przykład, jeśli pracujesz z dużymi kolumnami BLOB), możesz zwiększyć limit zapytań, ustawiając zmienną max_allowed_packet serwera, która ma domyślną wartość 1 MB. Konieczne może być również zwiększenie maksymalnego rozmiaru pakietu po stronie klienta. Więcej informacji na temat ustawiania rozmiaru pakietu znajduje się w rozdziale C.5.2.10, „Pakiet za duży”.

  • Instrukcja INSERT lub REPLACE, która wstawia wiele wierszy, może również powodować tego rodzaju błędy. Każda z tych instrukcji wysyła pojedyncze żądanie do serwera, niezależnie od liczby wstawianych wierszy; w ten sposób często można uniknąć błędu, zmniejszając liczbę wierszy wysyłanych na WSTAW lub WYMIANA.

ZALECENIE

Spróbuj podnieść max_allowed_packet do znacznie większej liczby, ponieważ domyślnie jest to 1M. Sugerowałbym około 10-krotność największego pola TEKST lub BLOB w twoim bieżącym zestawie danych.

Aby ustawić max_allowed_packet na 256M, możesz dodać go do /etc/my.cnf lub my.ini

[mysqld]
max_allowed_packet=256M

aby pokryć przyszłe ponowne uruchomienie mysqld. Aby zainstalować wartość teraz na serwerze, uruchom to:

SET GLOBAL max_allowed_packet = 1024 * 1024 * 256;

Spróbuj !!!

RolandoMySQLDBA
źródło
Bardzo dobre wytłumaczenie.
Vasilis Lourdas
4

Najczęściej domyślnie max_connections będzie wynosił 100. Spróbuj zwiększyć parametr config

max_connections = 400, po ustawieniu w my.cnf zrestartuj serwer lub ustaw go dynamicznie:

    set @@global.max_connections = 400;

Wystarczy wypróbować powyższe zalecenie, aby uniknąć komunikatów ostrzegawczych, a także upewnić się, że w sieci nie spadają pakiety.

Gopinath
źródło
2

Ostatnio napotkałem ten problem po przejściu z MySQL Enterprise 5.1.x do 5.7.x , bez żadnych znaczących zmian kodu w aplikacji , zaczęła pojawiać się „ uwaga ”.

W moim przypadku główną przyczyną pojawienia się „ notatki ” było wyjście programu z wciąż otwartymi połączeniami. Okoliczności, w których połączenia nie zostały zamknięte, były nieco bardziej zaangażowane i nie dotyczyły MySQL, ale ACE, wątków i TSS.

Wolter
źródło
0

Ta linia my.ini rozwiązała mój problem:

log_error_verbosity=1

Odwołaj się do tego linku

JeWoPeR
źródło
16
Nie sądzę, że rozwiązałeś podstawowy problem, ale po prostu przestałeś go logować.
user19292
1
Otrzymałem tę samą wiadomość jako „Uwaga”. Użycie log_error_verbosity = 2 faktycznie rozwiązuje „problem” (ale „Ostrzeżenie” powinno zostać rozwiązane, a nie ignorowane)
xtian