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';