Monitoramento de Desempenho do MySQL: Usando SHOW STATUS e SHOW PROCESSLIST
Domine o monitoramento de desempenho do MySQL em tempo real usando dois comandos essenciais: SHOW STATUS e SHOW PROCESSLIST. Aprenda a interpretar contadores globais de desempenho, identificar conexões ativas, detectar consultas de longa duração ou bloqueadas e diagnosticar gargalos de recursos imediatamente. Este guia fornece exemplos práticos para analisar atividade de threads, métricas do InnoDB e executar ações direcionadas como KILL.
Monitoramento de Desempenho do MySQL: Usando SHOW STATUS e SHOW PROCESSLIST
Quando um aplicativo baseado em MySQL fica lento, SHOW STATUS e SHOW PROCESSLIST são as verificações internas mais rápidas que você pode executar antes de abrir um painel. Eles não explicarão todos os problemas por si só, mas respondem a duas perguntas práticas: o que o servidor tem feito e o que está sendo executado agora?
Entendendo a Saúde do Sistema em Tempo Real com SHOW STATUS
O comando SHOW STATUS, frequentemente usado de forma intercambiável com SHOW GLOBAL STATUS ou SHOW SESSION STATUS, fornece uma riqueza de informações sobre a atividade do servidor desde a última reinicialização ou desde o início da sessão atual. Essas variáveis de status atuam como contadores, rastreando desde tentativas de conexão até eficiência de cache e esperas por bloqueios.
Status Global vs. Sessão
Ao executar este comando, é crucial entender o escopo:
SHOW GLOBAL STATUS: Mostra contadores acumulados desde que a instância do servidor MySQL foi iniciada. Isso fornece uma visão geral da saúde do servidor e tendências de longo prazo.SHOW SESSION STATUS: Mostra contadores específicos apenas para a conexão (sessão) que você está usando atualmente. Isso é útil para isolar o impacto de desempenho de transações específicas.
Indicadores Chave de Desempenho (KPIs) do SHOW GLOBAL STATUS
Embora SHOW GLOBAL STATUS retorne centenas de variáveis, várias são críticas para a triagem inicial de desempenho. Normalmente, você deseja direcionar a saída para grep ou usar uma cláusula WHERE para filtrar por relevância.
1. Monitoramento de Conexões e Threads
Essas variáveis ajudam a entender a carga de conexões:
| Nome da Variável | Descrição |
|---|---|
Threads_connected |
O número de conexões atualmente abertas (clientes). |
Threads_running |
O número de threads ativas atualmente executando consultas (geralmente deve ser baixo). |
Max_used_connections |
O maior número de conexões simultâneas desde que o servidor foi iniciado. Útil para dimensionar max_connections. |
Exemplo: Verificando conexões ativas:
SHOW GLOBAL STATUS LIKE 'Threads_%';
2. Cache de Consultas e Eficiência
Se você estiver usando o cache de consultas legado (disponível em versões mais antigas do MySQL, descontinuado/removido em versões mais recentes), essas métricas são essenciais:
Qcache_hits: Número de vezes que uma consulta foi servida a partir do cache.Qcache_lowmem_prunes: Número de consultas que fizeram o cache remover entradas mais antigas devido à baixa memória.
3. Métricas do Mecanismo InnoDB (Mais Críticas para MySQL Moderno)
Para implantações modernas usando o mecanismo de armazenamento InnoDB, monitore a atividade do buffer pool:
Innodb_buffer_pool_read_requests: Total de solicitações de leitura.Innodb_buffer_pool_reads: Número de leituras físicas do disco (uma alta proporção de leituras físicas em relação a solicitações indica a necessidade de um buffer pool maior).
Dica Prática: Para avaliar rapidamente a eficiência do buffer pool, calcule a taxa de acerto: (Innodb_buffer_pool_read_requests - Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests.
4. Tabelas Temporárias e Classificações
Isso indica quanto processamento interno o MySQL está realizando:
Created_tmp_tables: Número de tabelas temporárias em memória criadas.Created_tmp_disk_tables: Número de tabelas temporárias que tiveram que ser gravadas em disco (lento).
Se Created_tmp_disk_tables for alto, pode ser necessário aumentar tmp_table_size ou max_heap_table_size.
Diagnosticando a Carga de Trabalho Ativa com SHOW PROCESSLIST
Enquanto SHOW STATUS informa o que aconteceu, SHOW PROCESSLIST informa o que está acontecendo agora. Ele exibe informações sobre as threads atualmente em execução no servidor, permitindo identificar consultas de longa duração ou bloqueadas.
A Estrutura da Lista de Processos
O comando gera várias colunas, cada uma fornecendo contexto sobre uma conexão ativa:
| Coluna | Descrição |
|---|---|
| Id | O ID único da conexão (usado para encerrar o processo). |
| User | A conta de usuário conectada. |
| Host | O host de origem da conexão. |
| db | O banco de dados atualmente sendo usado pela thread. |
| Command | O tipo de comando sendo executado (ex.: Query, Sleep, Connect). |
| Time | O número de segundos que a thread está em seu estado atual. |
| State | A ação específica que a thread está executando (ex.: Sending data, Copying to tmp table). |
| Info | A instrução SQL real sendo executada (ou truncada se longa). |
Filtrando e Interpretando a Saída
Para sistemas de produção grandes, a lista de processos completa pode ser esmagadora. É prática comum usar a palavra-chave FULL para garantir que você veja todo o texto da consulta e, em seguida, filtrar pelas colunas Time ou State.
1. Visualizando o Texto Completo do Comando
Sempre use FULL se suspeitar de consultas lentas, pois a saída padrão frequentemente trunca o campo Info:
SHOW FULL PROCESSLIST;
2. Identificando Consultas Bloqueadas ou Lentas
Monitore as colunas Time e Command:
- Valor Alto de
Time: Qualquer consulta em execução por um período prolongado (ex.: mais de 10 segundos, dependendo do seu SLA) precisa de investigação imediata. Verifique a colunaInfocorrespondente para ver o SQL. Command= 'Sleep': Essas conexões estão ociosas, mas ainda consomem recursos. Se elas se acumularem excessivamente, considere ajustar a variávelwait_timeout.Command= 'Query': Estas são instruções em execução ativa. Preste muita atenção ao seuState.
3. Identificando Problemas de Bloqueio
Quando as consultas estão presas esperando por recursos, a coluna State frequentemente indica isso:
Waiting for table metadata lockWaiting for table lockWaiting for lock
Se você vir inúmeras threads em estado de espera, isso sinaliza contenção, geralmente causada por uma transação de longa duração mantendo bloqueios que outros precisam.
Ação: Encerrando um Processo
Se você identificar uma consulta descontrolada que está degradando severamente o desempenho, pode encerrá-la usando o comando KILL seguido do Id do processo:
KILL 12345; -- Substitua 12345 pelo Id real da lista de processos
Aviso: Use
KILLcom cautela. Encerrar uma transação ativa pode deixar o banco de dados em um estado inconsistente se a transação estiver no meio de uma operação de gravação complexa. Sempre tente identificar e otimizar a consulta primeiro, se possível.
Combinando Informações de Status e Processo para Solução de Problemas
O monitoramento eficaz do MySQL geralmente envolve correlação entre esses dois comandos:
- Verificação Inicial: Execute
SHOW FULL PROCESSLIST. Observe quaisquer consultas de alto tempo ou conexões excessivas. - Verificação de Contexto: Revise a contagem de conexões usando
SHOW GLOBAL STATUS LIKE 'Threads_connected'. Você está enfrentando uma enxurrada ou apenas uma consulta ruim? - Análise Aprofundada: Se uma consulta específica estiver lenta, analise seu impacto nos contadores de recursos revisando
Innodb_buffer_pool_readsou taxas de criação de tabelas temporárias enquanto a consulta está em execução (requer uma comparação de linha de base).
Ao verificar regularmente essas saídas dinâmicas, você vai além do palpite e aplica soluções direcionadas para melhorar a estabilidade e velocidade do MySQL.
Uma Rotina de Triagem Realista
Uma boa primeira passagem leva menos de um minuto. Comece com a lista de processos:
SHOW FULL PROCESSLIST;
Examine um monte de consultas ativas, valores longos de Time, esperas por bloqueio e muitas conexões ociosas Sleep. Uma única consulta de relatório lenta é tratada de forma diferente de centenas de conexões web esperando pelo mesmo bloqueio de tabela.
Em seguida, verifique os contadores de threads:
SHOW GLOBAL STATUS WHERE Variable_name IN (
'Threads_connected',
'Threads_running',
'Max_used_connections'
);
Threads_connected informa quantos clientes estão conectados. Threads_running geralmente é mais importante durante uma lentidão porque mostra quantas threads estão ativamente trabalhando. Muitos clientes conectados em modo sleep podem ser desperdício, mas muitas threads em execução podem significar que o servidor está sob pressão real.
Em seguida, verifique se a carga de trabalho está criando tabelas temporárias em disco:
SHOW GLOBAL STATUS WHERE Variable_name IN (
'Created_tmp_tables',
'Created_tmp_disk_tables',
'Sort_merge_passes'
);
Esses contadores são cumulativos desde a inicialização, então um único instantâneo pode enganar. Tire dois instantâneos com alguns minutos de diferença durante o incidente. Se as tabelas temporárias em disco estiverem aumentando rapidamente, inspecione consultas com GROUP BY, ORDER BY, junções grandes, colunas de texto ou índices ausentes. Aumentar tmp_table_size pode ajudar em alguns casos, mas uma consulta ou índice melhor geralmente é a correção mais limpa.
Observando a Pressão do InnoDB
A maioria das implantações modernas do MySQL usa InnoDB, então os contadores do InnoDB merecem atenção:
SHOW GLOBAL STATUS WHERE Variable_name LIKE 'Innodb_buffer_pool_read%';
Innodb_buffer_pool_read_requests conta solicitações de leitura lógica. Innodb_buffer_pool_reads conta leituras que tiveram que ir para o disco. Se as leituras físicas estão aumentando rapidamente durante o tráfego normal, o buffer pool pode ser muito pequeno para o conjunto de trabalho, as consultas podem estar escaneando muitos dados ou um trabalho em lote pode estar empurrando páginas úteis para fora do cache.
Esperas por bloqueio são outra fonte comum de dor:
SHOW GLOBAL STATUS WHERE Variable_name LIKE 'Innodb_row_lock%';
Esperas crescentes por bloqueio de linha não significam automaticamente que o InnoDB está quebrado. Elas geralmente significam que as transações estão mantendo bloqueios por mais tempo do que o aplicativo espera. Procure por transações abertas, atualizações lentas ou caminhos de código que iniciam uma transação, chamam serviços externos e confirmam muito depois.
Para detalhes mais profundos sobre bloqueio e transação, SHOW ENGINE INNODB STATUS\G pode ajudar, mas sua saída é densa. Use-o quando a lista de processos mostrar esperas por bloqueio e você precisar identificar o padrão de transação por trás delas.
Uso Mais Seguro de KILL
KILL é útil, mas não é um botão de limpeza. Se você encerrar uma conexão executando uma transação grande, o MySQL pode precisar reverter o trabalho, e a reversão pode levar tempo. Em alguns incidentes, essa ainda é a ação correta, mas tome a decisão deliberadamente.
Prefira encerrar a consulta primeiro quando sua versão do MySQL e permissões suportarem:
KILL QUERY 12345;
Isso tenta parar a instrução atual enquanto mantém a conexão ativa. Se o cliente estiver se comportando mal ou a conexão precisar ser encerrada, use:
KILL CONNECTION 12345;
Antes de encerrar qualquer coisa, capture a linha da lista de processos, o usuário, host, banco de dados e texto SQL. Após o incidente, esse detalhe ajuda você a corrigir a fonte em vez de esperar pela mesma consulta retornar.
Estados Comuns da Lista de Processos e o Que Eles Sugerem
Sending data nem sempre significa que o MySQL está enviando linhas pela rede. Muitas vezes significa que o servidor está lendo, filtrando, classificando ou preparando linhas. Se uma consulta passa muito tempo lá, execute EXPLAIN na instrução e procure por varreduras de tabela, ordem de junção ruim ou índices ausentes.
Copying to tmp table ou Creating sort index frequentemente aponta para classificação ou agrupamento caros. Verifique se um índice pode suportar o padrão WHERE e ORDER BY. Às vezes, a consulta está fazendo exatamente o que o produto pediu, mas pertence a um relatório assíncrono em vez de um caminho de solicitação.
Waiting for table metadata lock aparece frequentemente quando DDL e consultas normais colidem. Um ALTER TABLE aparentemente simples pode esperar atrás de uma transação aberta, enquanto consultas posteriores se acumulam atrás do DDL pendente. Nesse caso, encerrar o bloqueador mais antigo pode ser mais seguro do que encerrar todas as consultas em espera.
Transformando Contadores em Evidências Úteis
Como os valores de SHOW STATUS são principalmente contadores, taxas são mais úteis do que números brutos. Capture as mesmas variáveis duas vezes:
SHOW GLOBAL STATUS LIKE 'Questions';
SHOW GLOBAL STATUS LIKE 'Slow_queries';
Aguarde sessenta segundos e execute-as novamente. A diferença informa a taxa durante aquele minuto. Esta é a mesma ideia que os painéis usam, mas fazer manualmente é útil quando você só tem acesso ao terminal.
Mantenha anotações durante incidentes. "Threads_running saltou de 8 para 90, a lista de processos mostrou 70 consultas esperando por bloqueio de metadados na tabela orders, e Max_used_connections não mudou" é um diagnóstico útil. "MySQL estava lento" não é.
Quando Esses Comandos Não São Suficientes
SHOW STATUS e SHOW PROCESSLIST são ferramentas de primeira resposta. Eles não substituem o log de consultas lentas, Performance Schema, planos de consulta ou métricas de nível de host. Se o mesmo problema retornar, ative ou revise o log de consultas lentas e inspecione as piores instruções com EXPLAIN.
Para picos recorrentes de conexão, observe as configurações do pool de aplicativos e o comportamento de implantação. Aumentar max_connections pode ganhar tempo, mas também pode permitir que o servidor aceite mais trabalho do que realmente pode executar. Para esperas recorrentes por bloqueio, inspecione os limites de transação no aplicativo. Uma transação que permanece aberta enquanto o código chama uma API externa pode bloquear solicitações não relacionadas e fazer o MySQL parecer mais lento do que é.
Verifique também o host. Se a latência do disco for alta, a CPU estiver saturada, a memória estiver fazendo swap ou um vizinho barulhento estiver roubando recursos, os contadores do MySQL mostrarão sintomas, mas não a causa completa. Um bom diagnóstico combina comandos de banco de dados com métricas do sistema.
SHOW STATUS fornece contadores e contexto. SHOW FULL PROCESSLIST fornece a carga de trabalho ao vivo. Usados juntos, eles ajudam a diferenciar entre pressão de conexão, uma consulta ruim, contenção de bloqueio, trabalho temporário pesado em disco e pressão de cache do InnoDB.