MySQL to druga znana baza danych na świecie według strony internetowej DB Engine stojącej za Oracle. To, co sprawia, że MySQL jest sławny, to prawdopodobnie dlatego, że jest bardzo szybkim, niezawodnym i elastycznym systemem zarządzania bazami danych. MySQL jest również jedną z obsługiwanych baz danych w ClusterControl. Możesz łatwo wdrażać, skalować, monitorować i robić wiele rzeczy za pomocą ClusterControl.
Dzisiaj nie będziemy rozmawiać o żadnym z nich, ale omówimy jeden z typowych błędów MySQL i możliwe wskazówki dotyczące rozwiązywania problemów. Podczas pracy z biletami, dużo czasu, gdy sprawdzamy raporty o błędach lub dzienniki, dość często widzieliśmy ten wiersz „Wystąpił błąd odczytu pakietu komunikacyjnego”. Uważamy, że byłoby korzystne pisanie bloga związanego z tym błędem nie tylko dla naszych klientów, ale także dla innych czytelników. Nie czekajmy dalej, czas na więcej nurkowania!
Protokół klienta/serwera MySQL
Przede wszystkim musimy zrozumieć sposób, w jaki MySQL komunikuje się między klientem a serwerem. Zarówno klient, jak i serwer korzystają z protokołu MySQL, który jest realizowany przez Connectors, MySQL Proxy, a także komunikację między serwerami replikacji master i slave. Protokół MySQL obsługuje takie funkcje, jak przezroczyste szyfrowanie przez SSL, przezroczysta kompresja, faza połączenia oraz faza poleceń.
Zarówno liczby całkowite, jak i łańcuchy są podstawowymi typami danych używanymi w całym protokole MySQL. Ilekroć klient i serwer MySQL chcą się ze sobą komunikować lub wysyłać dane, podzieli dane na pakiety o maksymalnym rozmiarze 16 MB, a także doda nagłówek pakietu do każdego kawałka. Wewnątrz każdego pakietu znajduje się ładunek, w którym typy danych (liczby całkowite/łańcuchy) odgrywają swoją rolę.
Biorąc pod uwagę, że CLIENT_PROTOCOL_41 jest włączony, dla prawie każdego polecenia, które klient wysyła do serwera, serwer odpowie na dowolny z następujących pakietów jako odpowiedź:
OK_Pakiet | To jest sygnał dla każdego udanego polecenia. |
ERR_Pakiet | Sygnał wskazuje błąd pakietu. |
EOF_Pakiet | Ten pakiet zawiera ostrzeżenie lub flagę stanu. |
Jak diagnozować problemy
Zazwyczaj istnieją dwa rodzaje problemów z połączeniem, którymi są błędy komunikacji lub przerwane połączenia. Gdy wystąpi którykolwiek z tych problemów z połączeniem, dobrym punktem wyjścia do rozwiązywania problemów i analizy są następujące źródła informacji:
-
Dziennik błędów
-
Ogólny dziennik zapytań
-
Zmienne stanu Aborted_xxx i Connection_errors_xxx
-
Pamięć podręczna hosta
Błędy połączenia i możliwe przyczyny
W przypadku wystąpienia jakichkolwiek błędów połączenia iw zależności od błędów, zwiększy się licznik stanu dla Aborted_clients lub Aborted_connects w zmiennych stanu. Jak zaczerpnięto z dokumentacji MySQL, Aborted_clients oznacza liczbę połączeń, które zostały przerwane, ponieważ klient umarł bez prawidłowego zamknięcia połączenia. Jeśli chodzi o Aborted_connects, oznacza to liczbę nieudanych prób połączenia z serwerem MySQL.
Jeśli uruchomisz serwer MySQL z opcją --log-warnings, prawdopodobnie zobaczysz przykład następującej wiadomości w swoim dzienniku błędów. Jak zauważyłeś, wiadomość wyraźnie mówiła, że dotyczy przerwania połączenia, dlatego licznik stanu Aborted_connects zostanie zwiększony w zmiennej status:
[Ostrzeżenie] Przerwano połączenie 154669 z bazą danych:użytkownik „wordpress”:host „wpuser”:„nazwa hosta” (wystąpił błąd podczas odczytu pakietów komunikacyjnych)
Normalnie nieudane próby połączenia mogą mieć miejsce z następujących powodów. Kiedy to zauważyłeś, prawdopodobnie oznacza to, że nieupoważniona osoba zamierza włamać się do bazy danych i możesz chcieć się jej przyjrzeć jak najszybciej:
-
Klient nie ma uprawnień dostępu do bazy danych.
-
Użyto nieprawidłowego poświadczenia.
-
Pakiet połączenia, który zawiera nieprawidłowe informacje.
-
Ze względu na osiągnięty limit połączenia connect_timeout.
Zmienna stanu dla Aborted_clients zostanie zwiększona przez serwer, jeśli klientowi uda się połączyć, ale zostanie rozłączony lub zakończony w niewłaściwy sposób. Oprócz tego serwer zarejestruje również komunikat o przerwanym połączeniu w dzienniku błędów. W przypadku tego typu błędu często może to być spowodowane następującym powodem:
-
Klient nie zamyka prawidłowo połączenia przed zakończeniem (nie wywołuje mysql_close()).
-
Klient przekroczył wait_timeout lub interactive_timeout sekund.
-
Program kliencki lub aplikacja nagle zakończyła się w trakcie przesyłania danych.
Poza wcześniejszymi przyczynami, inne prawdopodobne przyczyny przerwanych połączeń i problemów z przerwanymi klientami mogą być związane z dowolnym z poniższych:
-
Nieudana konfiguracja TCP/IP.
-
Wartość zmiennej jest za mała dla max_allowed_packet.
-
Niewystarczająca alokacja pamięci dla zapytań.
-
Wadliwy sprzęt, taki jak Ethernet, przełączniki, kable itp.
-
Problemy z biblioteką wątków.
-
Problem z zespołem dupleksu polegający na tym, że transfer odbywa się w trybie burst-pause-burst-pause (jeśli używasz protokołu Ethernet z Linuksem, zarówno z półdupleksem, jak i pełnym dupleksem).
Jak naprawić błędy komunikacji MySQL
Teraz, gdy poznaliśmy wiele możliwości, które powodowały błędy połączenia MySQL. Z naszego doświadczenia wynika, że w większości przypadków ten problem jest związany z zaporą sieciową lub problemami z siecią. Można też śmiało powiedzieć, że nie jest łatwo zdiagnozować tego rodzaju problem. Niemniej jednak poniższe rozwiązanie może być pomocne w rozwiązaniu tego błędu:
-
Jeśli Twoja aplikacja polega na wait_timeout do zamknięcia połączenia, warto zmienić logikę aplikacji, aby prawidłowo zamknięte po zakończeniu jakiejkolwiek operacji.
-
Upewnienie się, że wartość max_allowed_packet mieści się w dopuszczalnym zakresie, aby klient nie otrzymał żadnego błędu związanego z „pakiet jest za duży”.
-
W przypadku problemów z opóźnieniami połączenia, które mogą być spowodowane przez DNS, warto sprawdzić, czy masz skip-name- rozwiązywanie włączone.
-
Jeśli używasz aplikacji PHP lub innego programowania, najlepiej jest upewnić się, że nie zostanie przerwane połączenia, które są zazwyczaj ustawione na max_execution_time.
-
Jeżeli zauważyłeś dużo powiadomień TIME_WAIT z netstata, warto potwierdzić, że połączenia są dobrze zarządzane na koniec aplikacji.
-
Jeśli używasz Linuksa i podejrzewasz, że problem jest związany z siecią, najlepiej sprawdzić interfejs sieciowy używając polecenia ifconfig-a i sprawdź dane wyjściowe na serwerze MySQL pod kątem błędów.
-
Dla użytkowników ClusterControl, możesz włączyć Dziennik audytu z Klaster -> Bezpieczeństwo -> Dziennik audytu. Włączenie tej funkcji może pomóc w określeniu, które zapytanie jest winowajcą.
-
Narzędzia sieciowe, takie jak tcpdump i Wireshark, mogą być przydatne w identyfikowaniu potencjalnych problemów z siecią, przekroczenia limitu czasu i problemów z zasobami dla MySQL.
-
Regularnie sprawdzaj sprzęt, upewniając się, że nie ma uszkodzonych urządzeń, zwłaszcza w przypadku sieci Ethernet, koncentratorów, przełączników, kabli itp. Warto wymienić wadliwe urządzenie, aby mieć pewność, że połączenie jest dobre przez cały czas.
Wnioski
Istnieje wiele przyczyn, które mogą prowadzić do problemów z pakietami połączeń MySQL. Ilekroć wystąpi ten problem, z pewnością wpłynie to na działalność biznesową i codzienne operacje. Chociaż tego typu problem nie jest łatwy do zdiagnozowania i najczęściej jest spowodowany siecią lub zaporą sieciową, warto wziąć pod uwagę wszystkie kroki, które zostały sugerowane wcześniej, aby naprawić problem. Mamy nadzieję, że ten post na blogu może ci w jakiś sposób pomóc, zwłaszcza gdy napotkasz ten problem.