Optimizar a performance do MySQL em Linux

Uma das componentes mais importantes na optimização do desempenho de um ambiente LAMP (Linux, Apache, MySQL, PHP/Perl) é definitivamente a componente base de dados, ou seja, o MySQL. É o componente onde a sua correcta configuração pode fazer a maior diferença entre um servidor que fica de rastos com um pequeno pico no tráfego ou um que aguenta incólume.

É possível tornar o MySQL mais rápido de 3 formas:

  1. Hardware mais potente.Aumentar a capacidade do hardware é a mais fácil de todas, mas também a mais dispendiosa e menos eficiente.
  2. Correcta afinação dos parâmetros do MySQL (my.cnf). A correcta definição dos parâmetros permite que a memória disponível no servidor seja distribuída da melhor forma, tentamos pois minimizar que o processo mysqld tenha aceda ao disco. Também informamos a base de dados acerca do tipo de carga a esperar para que o MySQLprepare os seus recursos da forma mais eficiente.
  3. Optimização das consultas SQL. É de extrema importância que as tabelas tenham os índices bem definidos, entre outros aspectos.

Neste artigo mostro uma forma simples e expedita de saber quais os parâmetros e que valores aplicar no my.cnf (ficheiro de configuração do MySQL).

 

Aplicar o my.cnf mais apropriado ao sistema

Juntamente com todas as instalações do MySQL, vem um conjunto de ficheiros modelo de configuração para vários tipos de servidor. Devemos escolher aquele que é mais indicado para o nosso caso específico.

Os ficheiros modelo são os seguintes:

  • my-huge.cnf (enorme capacidade)
  • my-large.cnf (grande capacidade)
  • my-medium.cnf (média capacidade)
  • my-small.cnf (pequena capacidade)

As definições que vêm por defeito no my.cnf são para um servidor com capacidades muito reduzidas, isto para que, por defeito, o MySQL possa correr em qualquer servidor. Devemos por isso substituir esses parâmetros pelos encontrados num dos ficheiros modelo mais adequado ao nosso tipo de sistema.

Caso não saiba onde se encontram esses ficheiros no sistema pode aplicar o seguinte comando para descobrir a sua localização.

find / -name my-*.cnf

Depois de feitas as alterações deve reiniciar o MySQL e esperar até que ele tenha pelo menos 48 horas de carga.

 

Instalar e correr o MySQL Performance Tuning Primer Script

Fazer o download do scrip

wget http://day32.com/MySQL/tuning-primer.sh

Tornar o script executável

chmod +x ./tuning-primer.sh

Correr o script

./tuning-primer.sh

 

Exemplo do relatório para um caso real


-- MYSQL PERFORMANCE TUNING PRIMER -- 
- By: Matthew Montgomery -
MySQL Version 4.1.22-standard-log i686
Uptime = 2 days 7 hrs 2 min 31 sec 
Avg. qps = 332
Total Questions = 65843202
Threads Connected = 44
Server has been running for over 48hrs. 
It should be safe to follow these recommendations
To find out more information on how each of these 
runtime variables effects performance visit:
http://dev.mysql.com/doc/refman/4.1/en/server-sys
tem-variables.html

Visit http://www.mysql.com/products/enterprise/a
dvisors.html

for info about MySQL's Enterprise Monitoring and
Advisory Service
SLOW QUERIES 
Current long_query_time = 5 sec.
You have 1942348 out of 65843325 that take longer
than 5 sec. to complete
The slow query log is enabled. Your long_query_time seems to be fine
WORKER THREADS 
Current thread_cache_size = 8
Current threads_cached = 7
Current threads_per_sec = 0
Historic threads_per_sec = 0
Your thread_cache_size is fine
MAX CONNECTIONS 
Current max_connections = 100
Current threads_connected = 47
Historic max_used_connections = 101
The number of used connections is 101% of the
configured maximum.
You should raise max_connections
MEMORY USAGE 
Max Memory Ever Allocated : 1 G
Configured Max Per-thread Buffers : 1 G
Configured Max Global Buffers : 426 M
Configured Max Memory Limit : 1 G
Physical Memory : 5.94 G
Max memory limit seem to be within
acceptable norms
KEY BUFFER 
Current MyISAM index space = 179 M
Current key_buffer_size = 384 M
Key cache miss rate is 1 : 62678
Key buffer fill ratio = 23.00 % Your key_buffer_size seems to be too high.
Perhaps you can use these resources elsewhere
QUERY CACHE 
Query cache is enabled
Current query_cache_size = 32 M
Current query_cache_used = 14 M
Current query_cache_limit = 1 M
Current Query cache Memory fill ratio = 44.98 %
Current query_cache_min_res_unit = 4 K
MySQL won't cache query results that are larger
than query_cache_limit in size
SORT OPERATIONS
Current sort_buffer_size = 2 M
Current record/read_rnd_buffer_size = 7 M
Sort buffer seems to be fine
JOINS 
Current join_buffer_size = 132.00 K
You have had 766426 queries where a join could
not use an index properly
You have had 501 joins without keys that check
for key usage after each row

You should enable "log-queries-not-using-indexes"
Then look for non indexed joins in the slow query
log.
If you are unable to optimize your queries you
may want to increase your
join_buffer_size to accommodate larger joins
in one pass.
Note! This script will still suggest raising
the join_buffer_size when

ANY joins not using indexes are found.
OPEN FILES LIMIT 
Current open_files_limit = 4166 files
The open_files_limit should typically be set
to at least 2x-3x

that of table_cache if you have heavy MyISAM usage.
You currently have open more than 75% of your
open_files_limit

You should set a higher value for open_files_limit
in my.cnf
TABLE CACHE 
Current table_cache value = 2028 tables
You have a total of 1652 tables
You have 2028 open tables.
Current table_cache hit rate is 14%, while 100%
of your table cache is in use
You should probably increase your table_cache
TEMP TABLES 
Current max_heap_table_size = 16 M
Current tmp_table_size = 32 M
Of 793662 temp tables, 17% were created on disk
Effective in-memory tmp_table_size is limited to
max_heap_table_size.

Created disk tmp tables ratio seems fine
TABLE SCANS 
Current read_buffer_size = 1 M Current table scan ratio = 69 : 1
read_buffer_size seems to be fine
TABLE LOCKING 
Current Lock Wait ratio = 1 : 44
You may benefit from selective use of InnoDB.
If you have long running SELECT's against
MyISAM tables and perform
frequent updates consider setting
'low_priority_updates=1'

 

O relatório está dividido em várias secções. No final de cada secção é feita a sugestão se algo deve ser alterado ou se os parâmetros definidos estão correctos.

Finalmente devemos aplicar as sugestões e analisar o comportamento do sistema. Este script poupa muito tempo de análise e interpretação dos imensos parâmetros passíveis de optimização. Este processo deve ser revisto regularmente, principalmente se acontecerem mudanças na quantidade de tráfego a chegar ao sistema.

 

Alternativa mais demorada

Também é possível fazer este trabalho de optimização de uma forma não automática. Para este efeito recomendo a instalação do mysqlreport e leitura do manual de interpretação do relatório.

Happy tuning!

Tópicos: 

Comentários

Olá,

Executei o MySQL Performance Tuning Primer Script conforme você orientou (MySQL Version 5.0.32-Debian_7etch5 i486), porém ocorreram vários erros de command not found, integer expression expected e not a valid identifier. Com isso os testes de MEMORY USAGE, KEY BUFFER, QUERY CACHE, SORT OPERATIONS e JOINS não foram executados. Tem idéia do que pode ser? Usei o tuning-primer.sh de 2008-02-21.

Olá Eduardo,

Deve estar a faltar-lhe algum componente no sistema, como por exemplo o utilitário bc.
http://linux.about.com/od/commands/l/blcmdl1_bc.htm

Abraços,
José Fernandes

Fala cara. Gostei muito deste Post... faz tempo que eu me intersso sobre otmização de banco e este post veio a calhar =)

O foda é acertar esse captcha aqui viu... =(

Abraço

Será que não teum um desse para windows servers? Como fazer esse tipo de analise em um Mysql no Windows??

muito bom esse artigo mais oque eu fiquei mesmo interresado foi no gráfico, como eu faço pra gerar um desse, se for um plugin (código fonte) você pode passar pra mim?

Olá Paulo,

Esse gráficos são gerados automaticamente com o Munin

http://munin.projects.linpro.no/

Abraços,
José Fernandes

Qual a quantidade de Usuários e a quantidade de consultas simultaneas aproximadamente.

Viva,
Excelente artigo.
Aqui fica um bom complemento a este artigo que fala sobre optimização das consultas. http://log.pt/blog/2011/11/melhorar-o-desempenho-do-mysql-sem-aborrecer-...

Adicionar novo comentário