GUOB Tech Day 2017

08 junho 2017

Erro ‘Got an error reading communication packets’ no MySQL

Se uma aplicação cliente se conecta com êxito no MySQL, mas depois desconecta indevidamente ou a conexão é encerrada de maneira inesperada você receberá uma mensagem de erro ‘Got an error reading communication packets’. Para solucionar o problema, primeiro tentamos identificar a causa. Porém, uma dificuldade aqui é que se trata de um erro de comunicação entre cliente e servidor e são várias as possíveis causas.

Sintomas


O MySQL Server vai registrar uma mensagem de conexão abortada no log de erros, algo como ‘[Warning] Aborted connection 9999 to db: 'xxxxxx' user: 'yyyyyy' host:'zzzzzz' (Got an error reading communication packets)’. No MySQL 5.6 você deve configurar log_warnings para 2 ou mais para que essas mensagens sejam registradas. No MySQL 5.7 não é necessário alterar a configuração padrão (log_error_verbosity) para ter estes detalhes. Do lado da aplicação, também é comum aparecer erros ‘Lost connection to MySQL server’.

Outra maneira de verificar o problema é monitorar o valor da variável de status do MySQL Aborted_clients. Ela incrementa toda vez que um erro deste tipo ocorre. Outra variável de status relacionada a problemas de comunicação é Aborted_connects, mas ela será incrementada somente no caso da aplicação cliente falhar ao estabelecer a conexão inicial com o MySQL Server. Uma forma de acompanhar os valores destas variáveis é com o comando SHOW GLOBAL STATUS LIKE 'Aborted%';.

Se você estiver usando o MySQL Enterprise Monitor também receberá alertas relacionados a este problema e poderá acompanhar as conexões abortadas no respectivo gráfico.

Causas


Algumas das principais causas do erro são:

  • A aplicação cliente tem algum bug e não fecha adequadamente as conexões ou não encerra transações corretamente com COMMIT.
  • A aplicação está configurada com algum limite máximo do tempo de conexão e o excede. Por exemplo, no caso do PHP há a opção max_execution_time. Outras linguagens e ambientes têm opções similares.
  • A aplicação cliente foi encerrada abruptamente (crash) no meio de uma transferência de dados.
  • O MySQL está com o valor para a configuração max_allowed_packet muito pequeno. Neste caso, a aplicação cliente também deve receber um erro do tipo ‘packet too large’.
  • O MySQL está configurado com limites muito baixos para wait_timeout ou interactive_timeout (em segundos). Neste caso, a conexão que permanecer no estado SLEEP por um tempo superior ao configurado será interrompida. Você poderá verificar o tempo e estado das conexões com o comando SHOW PROCESSLIST;.
  • A rede é ruim e o MySQL está configurado com limites muito baixos para net_write_timeout e net_read_timeout. Neste caso, se o cliente interromper o recebimento ou envio de resultados de queries acima destes limites, o MySQL Server pode pensar que o cliente está morto e fechar a conexão.
  • Algumas de suas queries podem precisar de mais memória do que a configurada no MySQL Server e/ou não puderam ser concluídas em tempo adequado. Tente identificar se o problema ocorre para queries específicas.
  • Firewalls, proxies, TCP/IP mal configurado,MTU auto discovery sem funcionar, DNS, hubs, switches, cabos defeituosos e outros problemas de rede/ethernet.
  • No Linux, alguns drivers apresentam problemas quando as interfaces de rede estão configuradas em Half Duplex em uma ponto e Full Duplex em outra.
  • Algum problema com a biblioteca de threads que causa interrupções nas leituras.

Solução


Se você conseguir identificar e isolar a causa, a solução será trivial. Porém, nem sempre será fácil. Você pode recorrer aos seguintes procedimentos:

  • Revise as seguintes configurações do MySQL: skip_name_resolve, max_allowed_packet, wait_timeout, interactive_timeout, net_write_timeout e net_read_timeout. Monitore o log de erros e as variáveis de status Aborted% para certificar-se de que o problema diminuiu ou desapareceu. Modifique uma configuração de cada vez e gradualmente.
  • Esse erro usualmente está relacionado às condições da sua rede. Comece certificando-se que não há erros reportados pelas interfaces de rede (ifconfig -a) e depois com ferramentas como tcpdump e netstat. Gere um pacote maior que 1GB com ping enquanto procura por anomalias com tcpdump e netstat.
  • Relacione as mensagens de erro tanto do lado da aplicação cliente quanto do lado do MySQL Server. Prefira usar os Id’s das conexões com o MySQL para fazer esta correlação ao invés do timestamp dos logs. Se puder, faça com que sua aplicação coloque esta informação (CONNECTION_ID()) no log de debug. No MySQL Server veja os Id’s das conexões problemáticas no log de erros. Se estiver trabalhando com versão mais antiga que 5.7, configure log_warnings para maior ou igual a 2.
  • Se for necessário, colete e analise os detalhes das conexões problemáticas. Se você estiver usando o MySQL Enterprise Edition, habilite o Audit Log. Se estiver usando o MySQL Community, use o General Log, mas esteja ciente de que isto pode gerar impacto indesejado na performance, portanto use com cuidado. Com a lista dos Id’s de conexões problemáticas verifique se queries específicas estão relacionadas ao problema. Se for possível isolar tais queries será mais fácil reproduzir e corrigir o problema.
  • Se você tiver acesso ao Suporte da Oracle para MySQL, poderá abrir um chamado e solicitar ajuda para identificar a causa-raíz.


Referências:
https://www.percona.com/blog/2016/05/16/mysql-got-an-error-reading-communication-packet-errors

Nenhum comentário: