MySQL е втората известна база данни в света според уебсайта на DB Engine зад Oracle. Това, което прави MySQL известен, вероятно е защото е много бърза, надеждна и гъвкава система за управление на бази данни. MySQL също е една от поддържаните бази данни в ClusterControl. Можете лесно да разгръщате, мащабирате, наблюдавате и правите много неща с ClusterControl.
Днес няма да говорим за нито едно от тях, но ще обсъдим една от често срещаните грешки за MySQL и възможни съвети за отстраняване на неизправности. Когато работим с билети, много време, когато проверяваме отчетите за грешки или регистрационните файлове, виждахме този ред „Имаме грешка при четене на комуникационен пакет“ доста често. Смятаме, че би било от полза, ако напишем блог, свързан с тази грешка, не само за нашите клиенти, но и за други читатели. Нека не чакаме повече, време е да се гмуркаме повече!
MySQL клиент/сървър протокол
На първо място, трябва да разберем начина, по който MySQL комуникира между клиент и сървър. И клиентът, и сървърът използват MySQL протокол, който се изпълнява от конектори, MySQL Proxy, а също и комуникацията между главни и подчинени сървъри за репликация. Протоколът MySQL поддържа функции като прозрачно криптиране чрез SSL, прозрачна компресия, фаза на свързване, както и фаза на команди.
И цели числа, и низове са основните типове данни, които се използват в целия MySQL протокол. Всеки път, когато MySQL клиент и сървър искат да комуникират помежду си или да изпращат данните, той ще раздели данните на пакети с максимален размер от 16MB и също така ще добави заглавка на пакета към всяка част. Вътре във всеки пакет ще има полезен товар, където типовете данни (цели числа/низове) играят своята роля.
Като се има предвид, че CLIENT_PROTOCOL_41 е активиран, за почти всяка команда, която клиентът изпраща към сървъра, сървърът ще отговори на някой от следните пакети като отговор:
OK_Packet | Това е сигналът за всяка успешна команда. |
ERR_Packet | Сигналът показва грешка за пакета. |
EOF_Packet | Този пакет съдържа предупреждение или флаг за състояние. |
Как да диагностицирам проблемите
Обикновено има два типа проблеми с връзката, които са комуникационни грешки или прекъснати връзки. Когато възникне някой от тези проблеми с връзката, следните източници на информация са добрата отправна точка за отстраняване на неизправности и анализ:
-
Регистърът на грешките
-
Общият регистър на заявките
-
Променливите на състоянието Aborted_xxx и Connection_errors_xxx
-
Кешът на хоста
Грешки при свързване и възможни причини
В случай, че възникнат грешки при свързване и в зависимост от грешките, той ще увеличи брояча на състоянието или за Aborted_clients, или за Aborted_connects в променливите на състоянието. Както е взето от документацията на MySQL, Aborted_clients означава броя на връзките, които са били прекъснати, защото клиентът е починал, без да затвори връзката правилно. Що се отнася до Aborted_connects, това означава броя на неуспешните опити за свързване към MySQL сървъра.
Ако стартирате MySQL сървъра с опцията --log-warnings, има вероятност да видите примера на следното съобщение във вашия регистър за грешки. Както забелязахте, в съобщението ясно се казва, че се отнася до прекратената връзка, следователно броячът на състоянието Aborted_connects ще бъде увеличен в променливата на състоянието:
[Предупреждение] Прекъсната връзка 154669 към db:'wordpress' потребител:'wpuser' хост:'hostname' (Има грешка при четене на комуникационни пакети)
Обикновено неуспешни опити за свързване могат да възникнат поради следните причини. Когато сте забелязали това, това вероятно означава, че неупълномощено лице е на път да наруши базата данни и може да искате да я разгледате възможно най-скоро:
-
Клиентът няма привилегии за достъп до базата данни.
-
Използва се грешен идентификационен номер.
-
Пакет за връзка, който има неправилна информация.
-
Поради достигнатото ограничение за connect_timeout за свързване.
Променливата на състоянието за Aborted_clients ще бъде увеличена от сървъра, ако клиентът успее да се свърже, но бъде прекъснат или прекратен по неправилен начин. В допълнение към това, сървърът също ще регистрира съобщение за прекратена връзка в регистъра за грешки. За този тип грешка обикновено това може да се дължи на следната причина:
-
Клиентът не затваря правилно връзката преди да излезе (не извиква mysql_close ()).
-
Клиентът е превишил wait_timeout или interactive_timeout секунди.
-
Клиентската програма или приложение внезапно приключиха по средата на трансфера на данни.
Освен причините по-рано, други вероятни причини както за прекъснатите връзки, така и за проблемите с прекъснатите клиенти могат да бъдат свързани с някое от следните:
-
Конфигурацията на TCP/IP е объркана.
-
Стойността на променливата е твърде малка за max_allowed_packet.
-
Недостатъчно разпределение на паметта за заявки.
-
Дефектен хардуер като Ethernet мрежи, превключватели, кабели и др.
-
Проблеми с библиотеката с нишки.
-
Проблем с дуплексния синдром, при който прехвърлянето преминава в режим пауза-пауза-пориви-пауза (ако използвате ethernet протокол с Linux, както полудуплекс, така и пълен дуплекс).
Как да поправя грешки в комуникацията с MySQL
Сега, когато научихме много възможности, които причиняват грешки при връзката с MySQL. Въз основа на нашия опит, през повечето време този проблем е свързан със защитната стена или проблеми с мрежата. Също така е справедливо да се каже, че не е лесно да се диагностицира този вид проблем. Независимо от това, следното решение може да ви е от полза при решаването на тази грешка:
-
Ако приложението ви разчита на wait_timeout за затваряне на връзката, струва си да промените логиката на приложението, така че да е правилно затворен в края на всяка операция.
-
Уверете се, че стойността за max_allowed_packet е в рамките на приемливия диапазон, така че клиентът да не получи грешка, свързана с „пакетът е твърде голям“.
-
За проблеми със забавянето на връзката, които може да се дължат на DNS, си струва да проверите дали имате skip-name- разрешаването е активирано.
-
Ако използвате PHP приложение или друго програмиране, най-добре е да се уверите, че не се прекъсва връзките, които обикновено се задават в max_execution_time.
-
Ако сте забелязали много TIME_WAIT известия от netstat, струва си да потвърдите, че връзките се управляват добре на края на приложението.
-
Ако използвате Linux и подозирате, че проблемът се дължи на мрежата, най-добре е да проверите мрежовия интерфейс като използвате командата ifconfig-a и проверете изхода на MySQL сървъра за грешка.
-
За потребители на ClusterControl можете да активирате дневника за одит от Cluster -> Security -> Audit Log. Като активирате тази функция, тя може да ви помогне да стесните търсенето коя заявка е виновникът.
-
Мрежовите инструменти като tcpdump и Wireshark могат да бъдат полезни при идентифициране на потенциални проблеми с мрежата, изчакване и проблеми с ресурсите за MySQL.
-
Редовно проверявайте хардуера, като се уверите, че няма дефектни устройства, особено за Ethernet мрежи, концентратори, превключватели, кабели и т.н. Струва си да смените дефектния уред, за да сте сигурни, че връзката е добра през цялото време.
Заключение
Има много причини, които биха могли да доведат до проблеми с пакета за връзка с MySQL. Всеки път, когато възникне този проблем, той определено ще се отрази на бизнеса и ежедневните операции. Въпреки че този тип проблем не е лесен за диагностициране и през повечето време се дължи на мрежата или защитната стена, струва си да вземете предвид всички стъпки, които са били предложени по-рано, за да отстраните проблема. Наистина се надяваме, че тази публикация в блога може да ви помогне по някакъв начин, особено когато се сблъскате с този проблем.