...

Tratamento do tempo limite da ligação MySQL no alojamento: sugestões e soluções

Os timeouts do MySQL no alojamento ocorrem frequentemente precisamente quando as consultas estão à espera ou as ligações permanecem abertas durante demasiado tempo. Vou mostrar-lhe como reconhecer as causas, definir timeouts de forma direcionada e assim Falhas e Mensagens de erro reduzir.

Pontos centrais

  • CausasLigações inactivas, consultas lentas, latência
  • DiagnósticoRegisto de consultas lentas, EXPLAIN, Registos
  • Configuraçõeswait_timeout, connect_timeout, Pool
  • OtimizaçãoÍndices, junções, max_execution_time
  • HospedagemLimites de ligação, proteção DoS

Por que razão ocorrem tempos limite de ligação MySQL no alojamento

Nos ambientes de alojamento, muitas aplicações são executadas em paralelo, partilham recursos e, por conseguinte, geram Tempos de espera e Carga de pico. Os tempos limite ocorrem se uma ligação permanecer inativa durante demasiado tempo ou se uma consulta ultrapassar o limite; as variáveis wait_timeout (para clientes não interactivos) e interactive_timeout (para ligações à consola) são particularmente eficazes neste caso. Connect_timeout conta para estabelecer uma ligação, enquanto net_read_timeout e net_write_timeout são relevantes para os processos de leitura e escrita. Um único pedido lento sem um índice adequado pode demorar minutos e entupir o pool de ligações, bloqueando outros pedidos. A elevada latência da rede ou as grandes distâncias entre o servidor de aplicações e a base de dados agravam o problema, razão pela qual avalio sempre os tempos limite juntamente com a qualidade da consulta e o caminho da rede.

Classificar corretamente as mensagens de erro

Em primeiro lugar, distingo entre „Connection timed out“ (a configuração falha) e „Command timeout“ (o comando é executado durante demasiado tempo), porque ambos são diferentes. Causas e Soluções têm. Mensagens como „O servidor MySQL foi-se embora“ indicam muitas vezes ligações interrompidas, pacotes demasiado pequenos (max_allowed_packet) ou um reinício forçado. Reconheço padrões nos registos: se os timeouts se acumulam nas horas de ponta, é mais provável que se devam à carga ou à falta de pooling; se ocorrem imediatamente, verifico a rede, o DNS ou as firewalls. Para um mergulho profundo estruturado, utilizo o registo de consultas lentas e analiso as instruções críticas com o EXPLAIN. Resumo uma visão geral compacta das causas e limites aqui: Causas e limites do servidor.

Definir especificamente as variáveis do sistema

Ajusto primeiro os tempos limite na sessão e verifico o comportamento antes de iniciar os tempos limite globais. Predefinições e Arquivos mudança. Por exemplo, eu defino o. SET SESSION wait_timeout = 3600;, global per SET GLOBAL wait_timeout = 3600;, onde as alterações globais são perdidas após um reinício. Introduzo valores permanentes em my.cnf/my.ini, por exemplo em [mysqld] com wait_timeout, interactive_timeout, connect_timeout, net_read_timeout e net_write_timeout. Em seguida, reinicio o serviço e meço se as taxas de erro e os tempos de resposta melhoram. Evito tempos limite muito elevados porque as ligações inactivas abertas ocupam recursos e podem desencadear reacções em cadeia mais tarde.

Diagnóstico: Registos, consultas lentas e tempos de execução

Para a análise, activei o registo de consultas lentas (slow_query_log = 1) e verificar quais as afirmações que ultrapassam regularmente o limiar, pois é frequentemente aqui que a verdadeira Travões e Fechaduras. Utilizo o EXPLAIN para detetar índices em falta, sequências de junção desfavoráveis ou a utilização de filesort/temporary, o que indica uma necessidade de otimização. Durante as horas de ponta, verifico com MOSTRAR LISTA DE PROCESSOS, se as ligações estão à espera umas das outras, e com SHOW VARIABLES LIKE '%timeout%', se as definições da sessão são diferentes do esperado. Em PHP, procuro em tempo_de_execução_máx; Se o valor for demasiado pequeno, o script termina, embora a base de dados ainda esteja a calcular. Para uma comparação significativa, executo as mesmas consultas localmente contra uma cópia e verifico se o armazenamento em cache, quantidades menores de dados ou outros buffers distorcem a imagem.

Delimitar claramente os tempos limite do servidor Web, do proxy e do cliente

Separo rigorosamente os limites de tempo do MySQL dos limites da web/proxy e do cliente, para que não sejam distorcidos no sítio errado. No Nginx, por exemplo. tempo_limite_de_leitura_proxy, fastcgi_read_timeout e tempo de espera de keepalive os tempos de espera para os fluxos ascendentes; no Apache Tempo limite e ProxyTimeout relevante. O PHP-FPM termina os pedidos através de request_terminate_timeout, mesmo que o MySQL ainda esteja a calcular. Na influência do HAProxy cliente timeout, servidor de tempo limite e tempo limite do túnel ligações longas. No lado do cliente, defino explicitamente os limites de tempo para que não sejam herdados implicitamente:

// PHP PDO
$pdo = new PDO($dsn, $user, $pass, [
  PDO::ATTR_TIMEOUT => 5, // segundos para o estabelecimento da ligação
  PDO::ATTR_PERSISTENT => false
]);

// mysqli
$mysqli = mysqli_init();
$mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5); // tempo_de_conexão
$mysqli->options(MYSQLI_OPT_READ_TIMEOUT, 10); // net_read_timeout (lado do cliente)
$mysqli->real_connect($host, $user, $pass, $db);

// Node.js (mysql2)
const pool = createPool({
  host, utilizador, palavra-passe, base de dados,
  connectionLimit: 20, waitForConnections: true, queueLimit: 100,
  connectTimeout: 7000, acquireTimeout: 10000, enableKeepAlive: true
});

Importante: A soma do tempo limite do servidor Web, da aplicação e da BD não deve resultar numa „sanduíche“ em que a camada exterior (por exemplo, Nginx) termina mais cedo do que as camadas interiores (aplicação/DB). Ajusto os valores para que os erros possam ser claramente atribuídos.

Utilização direcionada do esquema de desempenho e do esquema sistémico

O esquema de desempenho e o esquema sys fornecem-me informações reproduzíveis para além do registo de consultas lento. Ativo os instrumentos relevantes e analiso os pontos de acesso através do resumo:

-- Principais extractos por percentil 95
SELECT * FROM sys.statements_with_runtimes_in_95th_percentile
ORDER BY avg_timer_wait DESC LIMIT 20;

-- Eventos de espera activos (bloqueios, E/S, mutex)
SELECT EVENT_NAME, SUM_TIMER_WAIT, COUNT_STAR
FROM performance_schema.events_waits_summary_global_by_event_name
ORDER BY SUM_TIMER_WAIT DESC LIMIT 20;

-- Instruções „suspensas“ atuais
SELECT THREAD_ID, DIGEST_TEXT, TIMER_WAIT, CURRENT_SCHEMA
FROM performance_schema.events_statements_current
ONDE TIMER_WAIT NÃO É NULO;

Isto permite-me reconhecer se os timeouts são mais prováveis de vir de tempos de espera de I/O, cadeias de bloqueios ou planos com uso intensivo de CPU. Eu também verifico sys.user_summary e sys.host_summary, para restringir os outliers reconhecíveis por conta/hospedeiro. Isso evita que eu „estenda“ sintomaticamente os tempos limite, mesmo que os bloqueios ou E/S sejam realmente o gargalo.

Valores óptimos de timeout por cenário

Adapto os tempos limite à utilização pretendida porque a interatividade, os tempos de execução das tarefas e Latência e volume de dados variam muito. As aplicações Web com muitos pedidos curtos beneficiam de tempos limite de inatividade mais pequenos, para que a pool seja limpa e os novos utilizadores recebam ligações imediatamente. O processamento de dados com relatórios de uma hora precisa de limites mais generosos, caso contrário, trabalhos importantes acabam em timeouts. Para alta latência, eu aumento o connect_timeout moderadamente para que os tempos de configuração da conexão não apareçam falsamente como erros. A tabela seguinte fornece valores iniciais estáveis, que depois afino usando valores reais medidos.

Definição Aplicações Web de elevado tráfego Processamento de dados Nota
tempo limite de espera 60–300 s 3600-7200 s Mais curto para muitos utilizadores, mais longo para trabalhos em lote
tempo limite interativo 1800 s 7200 s Para CLI/consola, raramente crítico para a Web
tempo limite de ligação 5-10 s 10-20 s Aumenta moderadamente com latência elevada
innodb_lock_wait_timeout 10-30 s 50-120 s Dependendo da duração da transação

Pooling de ligações e tempos de inatividade

Um pool corretamente configurado evita ligações inactivas e assegura que os pedidos são encaminhados mais rapidamente para uma ligação livre. Recursos e Ligação venha. Defino o tempo limite de inatividade do grupo para cerca de 10-15 % abaixo do wait_timeout do MySQL, de modo a que as sessões fechem de forma ordenada antes de expirarem. A pool também limita as ligações simultâneas, o que evita transbordos em servidores partilhados. Para o WordPress, Nextcloud e ferramentas semelhantes, monitorizo a inatividade após as fases de início de sessão e configuro as ligações em pool para que não morram demasiado cedo. Resumi mais informações de base e exemplos práticos aqui: Pooling de ligações no alojamento.

Manter os bloqueios, deadlocks e transacções curtos e nítidos

Muitos timeouts são causados por transações longas e cadeias de bloqueios. Mantenho as transacções pequenas, leio primeiro os dados sem bloqueios e só abro a transação de escrita imediatamente antes da atualização/inserção. No caso de problemas de espera, verifico innodb_lock_wait_timeout e, sobretudo, bloqueios:

-- Deadlocks e status do InnoDB
SHOW ENGINE INNODB STATUS\G

-- Ver bloqueios activos (MySQL 8+)
SELECT * FROM performance_schema.data_locks\G
SELECT * FROM performance_schema.data_lock_waits\G

Evito padrões que não sejam favoráveis ao autocommit (por exemplo, longas sessões abertas com cursores „esquecidos“). Certifico-me de que os padrões de isolamento e escrita correspondem (por exemplo, REPEATABLE READ vs. READ COMMITTED) e que os processos secundários (relatórios, exportações) não mantêm bloqueios desnecessariamente longos. Resolvo os impasses utilizando a lógica de repetição na aplicação, mas nunca aumentando cegamente os tempos limite.

Tornar as consultas mais rápidas: Índices e junções

Acelero as consultas primeiro com Índices e mais magro Junta-se, antes de aumentar os tempos limite. No EXPLAIN, espero a utilização do índice para filtros e ordenação; se não for o caso, acrescento a chave especificamente ou altero a condição. Para tabelas grandes, não armazeno campos TEXT/BLOB largos no mesmo caminho de acesso se forem irrelevantes para a consulta. Também verifico se um LEFT JOIN é realmente necessário ou se um INNER JOIN é suficiente, pois isso reduz o conjunto de resultados. Estas etapas reduzem visivelmente o tempo de execução e o pool permanece disponível.

Afinação de PHP, Node e WordPress na prática

Em PHP, para relatórios longos, aumento o tempo_de_execução_máx moderadamente e evitar cancelamentos que parecem erros da base de dados mas que são causados pelo script. mentira. Sempre que possível, ativo as reconexões automáticas no controlador ou trato os erros para que uma nova tentativa de ligação comece de forma limpa. No Node.js, mantenho o keep-alive, os tamanhos de pool e os tempos de inatividade com base em medições reais de latência e rendimento. Com o WordPress, presto atenção ao cache, aos plug-ins enxutos e aos cron jobs fora dos horários de pico. Isto mantém a carga do MySQL baixa e os timeouts são raros.

Manter-se atento ao caminho da rede, ao DNS e ao TLS

Verifico todo o caminho entre a aplicação e a base de dados: resolução de DNS, encaminhamento, firewalls, NAT e handshakes TLS. Se possível, utilizo IPs estáveis ou DNS internos com TTLs curtos, mas não demasiado agressivos. Impedido no lado do servidor ignorar_nome_resolver pesquisas inversas dispendiosas (cuidado em ambientes partilhados). Com o TLS, presto atenção à retoma da sessão e mantenho a sobrecarga do aperto de mão baixa. O TCP-Keepalive ajuda a reconhecer mais rapidamente as ligações mortas; a nível do SO tempo de espera e keepalive_intvl Activei o Keep-Alive no controlador da aplicação. Nas configurações de nuvem, tenho em conta os tempos de inatividade NAT para que as ligações em pool não sejam eliminadas „silenciosamente“ enquanto a aplicação ainda as considera activas.

Limites e números de ligação no alojamento

O alojamento partilhado limita frequentemente as ligações simultâneas, o que significa que, apesar dos curtos tempos de execução em Tacos ou Erro executar. Configuro o pool de aplicações para que respeite estes limites superiores e reconheça os excessos no início da monitorização. Se os erros 500 aumentarem, verifico a relação entre max_connections, tamanho do pool e timeouts. Se a otimização for pouco útil, falo com o fornecedor sobre limites adequados ou considero planos maiores (vServer, BD dedicada). Pode encontrar um guia compacto de resolução de problemas aqui: Limites de ligação e erros 500.

Escolha o orçamento de recursos e max_connections de forma realista

Cada ligação custa RAM: os buffers de ordenação, junção e leitura são utilizados por cada thread. Por isso, estou a planear max_conexões não por pico de solicitação, mas por memória disponível. Demasiadas threads simultâneas geram mudanças de contexto e pressão de E/S, o que tende a encorajar timeouts. Eu mantenho tamanho_da_cache_de_fios e table_open_cache para que as alterações de ligações e tabelas não sejam desnecessariamente dispendiosas. Grande max_allowed_packet-Só defino valores elevados quando as exportações/uploads precisam disso - pacotes globalmente demasiado grandes consomem RAM e, combinados com muitas ligações, podem causar estrangulamentos.

Replicação, failover e escalonamento de leitura

Em configurações replicadas, verifico se a aplicação reage adequadamente em caso de falha ou atraso da réplica. Utilizo réplicas de leitura para cargas de leitura, mas presto atenção aos atrasos: uma réplica demasiado pequena net_read_timeout ou o tempo limite da aplicação pode interpretar respostas de replicação longas como erros. Implemento verificações de saúde e um backoff nas desconexões em vez de uma nova tentativa agressiva. Para a divisão de leitura/escrita, certifico-me de que os pedidos de leitura transaccionalmente consistentes não vão erradamente para réplicas atrasadas - caso contrário, aparecem „timeouts“ aparentes que se devem, na realidade, à espera de dados novos.

Manutenção, backups e DDL sem surpresas

As cópias de segurança, as DDL em linha e a criação de índices podem aumentar as E/S e os bloqueios. Programo esse trabalho fora das horas de ponta e utilizo algoritmos online sempre que possível. Durante a DDL, verifico innodb_lock_wait_timeout de forma conservadora, para que as transacções de produção não fiquem bloqueadas para sempre. Eu meço a utilização de E/S durante os backups; se a taxa de leitura e o rendimento do buffer pool colidirem, os tempos de resposta e a taxa de timeout a jusante aumentam. Também TABELAS DE DESCARGA COM BLOQUEIO DE LEITURA Utilizo-o apenas de forma selectiva, uma vez que pode bloquear globalmente.

Acompanhamento dos índices e valores-alvo

Defino SLOs e meço-os de forma consistente: latência p95/p99 das consultas mais importantes, taxa de erro por tipo (ligação vs. timeout de comando) e utilização. As métricas importantes incluem. Threads_running (manter premido por breves instantes), Threads_connected (ajustamento da dimensão da piscina), Ligações_abortadas e Erros_de_ligação_* (problemas de rede/auth), e Leitor_de_manipulador_* (utilização de índices). Uma proporção constantemente elevada de „pesquisas de tabelas completas“ está frequentemente relacionada com picos de timeout. Também utilizo um resumo para apresentar os principais consumidores de CPU, E/S e tempo de espera, de modo a aplicar optimizações que reduzam realmente a taxa de timeout.

Timeouts seguros vs. risco de DoS

Equilibro os tempos limite entre a facilidade de utilização e a proteção, de modo a que nenhum dos dois Abuso ainda Interrupções predominam. Com uma latência de rede elevada, aumento cuidadosamente o connect_timeout para que as ligações não falhem demasiado cedo. Em configurações vulneráveis, reduzo o mesmo valor para que ataques com handshakes longos tenham menos efeito. Para uploads ou grandes conjuntos de resultados, aumento o max_allowed_packet para que as transferências não sejam interrompidas. Implemento sempre estas intervenções monitorizando a taxa de erro e os tempos de resposta, para que possa ver imediatamente os efeitos e os efeitos secundários.

Evitar erros comuns

Nunca aumento os tempos limite cegamente porque abrem-se janelas de espera alargadas Reuniões e Fechaduras acumular. Em vez disso, corrijo primeiro as consultas lentas e depois ajusto minimamente os valores limite. Separo as transacções longas, defino pontos de controlo sensatos e verifico se o innodb_lock_wait_timeout corresponde ao padrão de escrita. Se forem necessários pacotes grandes, aumento o max_allowed_packet apenas na medida do necessário e testo os caminhos de carregamento, exportação e importação de forma realista. Com a monitorização contínua, reconheço as recaídas logo no início e mantenho o sistema fiável.

Resumo: Como manter as ligações fiáveis

Começo com diagnósticos claros, separo os erros de ligação dos tempos limite de comando e verifico Registos e Consultas no registo de consultas lentas. Em seguida, optimizo os índices e as junções, defino o tempo de inatividade do pool para um valor ligeiramente inferior a wait_timeout e defino tempos limite realistas de ligação, leitura e escrita. Escolho valores de inatividade curtos para o tráfego Web e limites mais longos para trabalhos em lote; testo ambas as variantes sob carga. Harmonizo os limites do PHP/nó e os parâmetros do MySQL para que a aplicação e a base de dados respirem durante o mesmo período de tempo. Isto reduz as taxas de erro, as consultas permanecem rápidas e os tempos limite do MySQL perdem o seu horror.

Artigos actuais