[RESOLVIDO] MySql com 100% de CPU

[RESOLVIDO] MySql com 100% de CPU

MySQL chegando a 100% de CPU geralmente indica que há queries pesadas, travamentos por locks, falta de índices, buffers mal configurados ou consumo anormal por threads.

Vamos por partes 👇


🧩 1. Diagnóstico inicial

Primeiro, identifique o que está consumindo CPU:

🔍 a) Ver processos ativos

mysqladmin processlist -uroot -p

ou dentro do MySQL:

SHOW FULL PROCESSLIST;

Procure por queries com:

  • State = “Sending data”, “Copying to tmp table”, “Locked”

  • Time muito alto (execução longa)

👉 Essas queries geralmente são as culpadas.


🔍 b) Top ou htop

No servidor Linux:

top -c

ou

htop

Procure o(s) processo(s) mysqld com alto uso. Pressione Shift + P para ordenar por CPU.

Veja também quantas threads estão ativas.


🧠 2. Analisar queries lentas

Habilite o slow query log se ainda não estiver:

SET GLOBAL slow_query_log = 1; SET GLOBAL long_query_time = 1; -- Loga queries acima de 1s SET GLOBAL slow_query_log_file = '/var/log/mysql/slow.log';

Depois veja:

mysqldumpslow -s t /var/log/mysql/slow.log | head

 


🧾 3. Ver status e métricas internas

Verifique o status geral:

SHOW GLOBAL STATUS LIKE 'Threads%'; SHOW GLOBAL STATUS LIKE 'Queries%'; SHOW GLOBAL STATUS LIKE 'Handler%'; SHOW ENGINE INNODB STATUS\G

Isso ajuda a identificar:

  • alto número de threads simultâneos

  • filas de I/O

  • bloqueios InnoDB (LATEST DETECTED DEADLOCK)


🧩 4. Checar configuração do MySQL (tuning)

Execute o MySQLTuner:

wget http://mysqltuner.pl -O mysqltuner.pl perl mysqltuner.pl

Ele mostra gargalos típicos, como:

  • query_cache_size pequeno

  • innodb_buffer_pool_size muito baixo (deve ser ~70% da RAM total)

  • tmp_table_size pequeno (causando escrita em disco)

  • max_connections muito alto (causando saturação por threads)


📊 5. Monitoramento em tempo real

Ferramentas úteis:

  • mysqltop → mostra queries em tempo real.

  • Percona PMM → monitora métricas de CPU, queries e locks graficamente.

  • Grafana + Prometheus + mysqld_exporter → ideal para histórico.


✅ Solução

Defina para cerca de 70–80% da RAM total se o servidor for dedicado ao MySQL.
Exemplo (para um servidor com 8 GB de RAM):

sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
# Buffers de join (usados por thread)
join_buffer_size = 4M
# Tabelas temporárias em memória (usadas por thread)
tmp_table_size = 64M max_heap_table_size = 64M
# Pool principal do InnoDB (~65% da RAM total)
innodb_buffer_pool_size = 5G innodb_buffer_pool_instances = 5
# Log buffer (melhora desempenho de escrita)
innodb_log_buffer_size = 256M

Reinicie o serviço:

sudo systemctl restart mysql

 


🧾 Resumo do impacto esperado

Área Ganho esperado
Consultas repetidas ⚡ 20–40% mais rápidas
JOINs grandes ⚡ Menos CPU
Writes InnoDB ⚡ Menos fsync / I/O
Tabelas temporárias ⚡ Evita gravações no disco
Concorrência ⚡ Menos contenção entre threads

Verifique:

mysql -uroot -p

SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW VARIABLES LIKE 'innodb_buffer_pool_instances';
SHOW VARIABLES LIKE 'join_buffer_size';

 

Sobre o Autor

Diego Elcain administrator