MySQL em Produção
Aula 6 de 6
Monitoramento
-- Conexões ativas
SHOW FULL PROCESSLIST;
SELECT * FROM performance_schema.threads WHERE PROCESSLIST_STATE IS NOT NULL;
-- Tamanho das tabelas
SELECT
table_name,
ROUND((data_length + index_length) / 1024 / 1024, 2) AS size_mb
FROM information_schema.tables
WHERE table_schema = 'meu_banco'
ORDER BY size_mb DESC;
-- Locks
SELECT * FROM performance_schema.metadata_locks;
SELECT * FROM performance_schema.data_locks;
-- Table status
SHOW TABLE STATUS LIKE 'pedidos'\G
Ferramentas de Monitoramento
# MySQLTuner — análise e recomendações
wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl
perl mysqltuner.pl --user root --pass xxx
# Percona Monitoring and Management (PMM)
docker run -d -p 80:80 --name pmm percona/pmm-server:2
# pt-mysql-summary (Percona Toolkit)
pt-mysql-summary --user root --password xxx
Alta Disponibilidade
InnoDB Cluster (MySQL 8+)
# MySQL Shell
mysqlsh
# Criar cluster
dba.createCluster('meuCluster')
cluster.addInstance('root@node2:3306')
cluster.addInstance('root@node3:3306')
# Verificar
cluster.status()
ProxySQL — Load Balancer
# /etc/proxysql.cnf
mysql_servers =
(
{ address = "10.0.1.10", port = 3306, hostgroup = 0 },
{ address = "10.0.1.20", port = 3306, hostgroup = 0 },
{ address = "10.0.1.30", port = 3306, hostgroup = 0 }
)
mysql_query_rules =
(
# SELECTs vão para replicas
{ rule_id = 1, match_pattern = "^SELECT", destination_hostgroup = 1 },
# O resto vai para writer
{ rule_id = 2, match_pattern = ".*", destination_hostgroup = 0 }
)
# Admin
mysql -u admin -p -h 127.0.0.1 -P 6032
ProxySQL> SELECT * FROM stats_mysql_connection_pool;
Troubleshooting
-- Consultas bloqueadas
SELECT
r.trx_id AS waiting_trx_id,
r.trx_mysql_thread_id AS waiting_thread,
TIMESTAMPDIFF(SECOND, r.trx_started, NOW()) AS wait_age,
b.trx_id AS blocking_trx_id
FROM performance_schema.data_lock_waits w
JOIN information_schema.innodb_trx r ON w.requesting_trx_id = r.trx_id
JOIN information_schema.innodb_trx b ON w.blocking_trx_id = b.trx_id;
-- Matar conexão
KILL CONNECTION 1234;
-- Tamanho do binlog
SHOW BINARY LOGS;
PURGE BINARY LOGS BEFORE '2024-06-01 00:00:00';
-- Erro de "too many connections"
SHOW VARIABLES LIKE 'max_connections';
SET GLOBAL max_connections = 500;
-- Solução permanente: /etc/mysql/mysql.conf.d/mysqld.cnf
Production Checklist
- InnoDB (nunca MyISAM)
- buffer pool 70-80% RAM
- slow_query_log ativo
- Backup automático configurado
- Replicação ou cluster para HA
- max_connections adequado
- utf8mb4 character set
- Monitoramento (PMM ou similar)
- Sistema de arquivos: XFS ou ext4
- Kernel: swappiness baixo (vm.swappiness=1)
- IO scheduler: deadline/none (SSD)
- ProxySQL ou HAProxy para distribuir carga
- SSL/TLS para conexões
- Audit log (MySQL Enterprise / Percona Audit)
- Limite de memória por query (tmp_table_size)
- Connection pooling (ProxySQL, HikariCP)
- Alertas: conexões, espaço, replicação lag
- Manutenção periódica: OPTIMIZE TABLE, ANALYZE TABLE
# Verificar integridade
mysqlcheck -u root -p --all-databases --check
# Otimizar tabelas (InnoDB: ALTER TABLE ... ENGINE=InnoDB)
mysqlcheck -u root -p --optimize meu_banco
# Atualizar estatísticas
mysqlcheck -u root -p --analyze meu_banco
Produção: InnoDB, backup, replicação + ProxySQL, monitoramento. InnoDB Cluster para HA automático. Sempre teste restores — backup que não é testado não é backup.