1. Performance Tuning
Parte do contéudo apresentado para na Pós-Grduação em
Sistemas de Informação Da FAMINAS, campus Muriaé/MG
em 28 e 29/04/2012 – www.wbconsulting.com.br
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
2. Performance Tuning
• Um dos pontos mais interessante para se pensar em
performance tuning ao ajuste de desempenho é “o que devo
otimizar”?
• O banco de dados relacional passa por um problema
atualmente pela grande demanda de armazenamento e
recuperação de informação, pouca escala;
– Mas aonde ajustar?
– Onde está o problema?
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
3. Performance Tuning
• Pontos a se considerar...
– MySQL funciona por threads;
– Cada thread é uma conexão de um usuário (com exceção da replicação
de dados que atualmente pode escalar esse número);
– O servidor de bancos de dados é alvo de várias consultas (geralmente
mal escritas);
– As tabelas possuem índices que geralmente não estão bem
posicionados;
– As tabelas são controladas pelos Storage Engines;
– Tudo isso está sobre um hardware que pode ser bom ou não – na
maioria das vezes, mal dimensionado;
O que dizer sobre o ambiente corporativo?
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
4. Performance Tuning
• O comando SHOW PROCESSLIST listará todas as threads
atualmente conectadas no MySQL que podem estar em vários
estados, observados na coluna “state”;
– max_connections: número máximo de threads, valor padrão 100;
– max_user_connections: número máximo de conexões
simultâneas de um usuário específico. Se
MAX_USER_CONNECTIONS não for utilizado para criar um usuário
específico, max_user_connections será utilizada. Se o valor
dessa variável for 0, quantidade de conexões ilimitadas para usuários
sem MAX_USER_CONNECTIONS;
• As duas variáveis apresentadas formam uma boa dinâmica na
concepção de sistemas que precisam realizar uma grande
quantidade de conexões com o MySQL;
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
5. Performance Tuning
• Uma thread no MySQL é reconhecida como uma conexão e
várias são ativadas simultaneamente, sendo este um dos
processos mais caros que existem no MySQL - não é somente
a recriação da thread, mas:
– Key_buffer_size: cache de índices para tabelas MyISAM;
– read_buffer_size: qtd de memória destinada a criação de buffers que serão
lidos de forma sequêncial pelo MySQL, evitando acesso ao disco;
– read_rnd_buffer_size: é um buffer secundário ao read_buffer_size que é
utilizado para leitura de dados em um processo intermediário de ORDER BY e para
leituras não sequências;
– sort_buffer_size: este buffer é utilizado para a ORDER BY/GROUP BY;
– join_buffer_size: buffer para auxílio à JOIN complexas e sem índices;
– net_buffer_length: tamanho incial do canal de comunicação client-server;
– max_llowed_packet: tamanho máximo do canal de comunicação client-
server;
Sort Buffer e Join Buffer são alocados somente sob demanda!
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
6. Performance Tuning
• Uma variável adicional precisará ser configurada para otimizar
cargas de dados...
– bulk_insert_buffer_size: essa variável alocará memória para
acumular dados que serão comitados de tempos em tempos quando
uma carga de dados é executada. Valor padrão 8M, máximo 4G, pode
ser configurada em nível global ou sessão.
INSERT ... SELECT
Memória RAM
INSERT ... VALUES (...), (...)
LOAD DATA INFILE ...
bulk_insert_buffer_size
Disco
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
7. Performance Tuning
• Per-client parameters iniciando threads...
max_allowed_packet
bulk_insert_buffer_size read_buffer_size
Connection Thread
join_buffer_size sort_buffer_size
net_buffer_length
thread_cache_size
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
8. Performance Tuning
• Criação ou recriação de threads é um problema grave para o
MySQL e para outros servidores de bancos de dados – com
isso, é importante dar atenção à variável thread_cache_size;
• Para monitorar a necessidade de alteração do valor dessa
variável utilizamos as variáveis de status para verificar a
necessidade atual do servidor;
mysql> SHOW STATUS LIKE 'Threads%';
+-------------------+-------+
Olhando somente para esse resultado ao lado
| Variable_name | Value | não ficamos completamente convencidos de que
+-------------------+-------+ é necessário ajustar o valor da variável! Repita a
| Threads_cached | 7 |
| Threads_connected | 20 |
consulta àquelas variáveis de status e caso
| Threads_created | 187 | Threads_created continuar crescendo e
| Threads_running | 12 | Threads_cached bater o valor máximo será
+-------------------+-------+
necessário aumentar o valor de thread_cache_size.
4 rows in set (0.00 sec)
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
9. Performance Tuning
• Tabelas temporárias são também um problema na
performance do servidor de bancos de dados MySQL- elas
podem ser criadas em certas condições:
– Consultas com ORDER BY, GROUP BY, DISTINCT + ORDER BY, ou aquelas
que tem uma coluna na cláusula GROUP BY que não é parte da primeira
tabela que aparece na lista de uma JOIN;
– Consultas que utilizem o HINT (veremos mais à frente)
SQL_SMALL_RESULT;
• São duas as variáveis para se controlar o tamanho das tabelas
temporárias no MySQL:
– tmp_table_size: tamanho de uma TEMP TABLE em K, M ou G;
– max_heap_table_size: qtd linhas que uma MEMORY TABLE pode ter;
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
10. Performance Tuning
• Podemos checar problemas com tabelas temporárias criadas
pelo servidor para resolver consultas através das variáveis de
status:
mysql> SHOW STATUS LIKE 'Created%';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Created_tmp_disk_tables | 0 | -> crítico, aumentar tmp_table_size
| Created_tmp_files | 6 | -> não crítico
| Created_tmp_tables | 0 | -> não crítico
+-------------------------+-------+
3 rows in set (0.00 sec)
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
11. Performance Tuning
• Outro ponto para máxima atenção:
– table_open_cache: mantém um descriptor no cache para cada
tabela já aberta;
– table_cache_definition: mantém a definição da tabela
(arquivo .frm) em cache;
• Mantém em cache um descriptor aberto para tabelas do
banco de dados - todas as tabelas devem “caber” neste cache;
mysql> SHOW STATUS LIKE 'Open%_tables';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Open_tables | 3903 | -> tbs abertas uma só vez e mantidas no cache
| Opened_tables | 0 | -> tbs abertas mais de uma vez, alto custo!
+---------------+-------+
2 rows in set (0.00 sec)
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
12. Performance Tuning
MyISAM Key Buffer Size
• O MyISAM armazena na memória os dados índices mantidos
nos arquivos .MYI que cada tabela tem – dados são mantidos
em uma estrutura denominada key_buffer_size;
mysql> SHOW VARIABLES LIKE 'key_%';
+--------------------------+-----------+
| Variable_name | Value |
+--------------------------+-----------+
| key_buffer_size | 268435456 | -> cache de índices
| key_cache_age_threshold | 300 | -> threshold de dados
| key_cache_block_size | 1024 | -> qtd de blocos
| key_cache_division_limit | 100 | -> limite de divisões de dados
+--------------------------+-----------+
4 rows in set (0.00 sec)
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
14. Performance Tuning
MyISAM Key Buffer Size
• Variáveis de status nos permitem verificar se o key_buffer está
ajustado de acordo com a movimentação do banco de dados;
mysql> SHOW STATUS LIKE 'Key_%';
+------------------------+--------+
| Variable_name | Value |
+------------------------+--------+
| Key_blocks_not_flushed | 0 | -> blocos sujos
| Key_blocks_unused | 231960 | -> blocos ainda não utilizados
| Key_blocks_used | 4 | -> blocos utilizados
| Key_read_requests | 19 | -> requisições de leitura do cache
| Key_reads | 4 | -> requisições de leitura do disco
| Key_write_requests | 16 | -> escritas no cache
| Key_writes | 12 | -> escritas no disco
+------------------------+--------+
7 rows in set (0.00 sec)
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
15. Performance Tuning
MySQL Query Cache
• Um dos módulos mais
interessantes quando o
assunto é performance
é o MySQL Query
Cache...
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
16. Performance Tuning
MySQL Query Cache
• Podemos configurar o MySQL Query Cache através de suas
variáveis de ambiente (algumas em tempo de
execução/standalone e outras somente no arquivo de
configuração):
– query_cache_type: o tipo de captura que será realizada para o cache;
– query_cache_size: o tamanho total de memória do cache;
– query_cache_limit: o limite máximo para cada um dos resultados;
– query_cache_res_min_unit: o limite mínimo para cada resultado;
– query_cache_wlock_invalidate: ao atualizar objetos, invalida o
cache;
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
17. Performance Tuning
MySQL Query Cache
• Variáveis de ambiente que nos possibilitam ajustar o MySQL
Query Cache:
mysql> SHOW VARIABLES LIKE 'query_cache%';
+------------------------------+-----------+
| Variable_name | Value |
+------------------------------+-----------+
| query_cache_limit | 16777216 | -> 16M
| query_cache_min_res_unit | 1024 | -> 1024K
| query_cache_size | 268435456 | -> 256M
| query_cache_type | ON | -> 0, 1 ou 2
| query_cache_wlock_invalidate | ON | -> 0 ou 1 (ON ou OFF)
+------------------------------+-----------+
5 rows in set (0.00 sec)
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
18. Performance Tuning
MySQL Query Cache
• Para medir o desempenho do MySQL Query Cache:
mysql> SHOW STATUS LIKE 'Qcache%';
+-------------------------+-----------+
| Variable_name | Value |
+-------------------------+-----------+
| Qcache_free_blocks | 34141 | -> blocos livres
| Qcache_free_memory | 135925760 | -> memória livre
| Qcache_hits | 28692504 | -> query exc do cache
| Qcache_inserts | 60734114 | -> queries inseridas no cache
| Qcache_lowmem_prunes | 5412156 | -> rodízio - LRU
| Qcache_not_cached | 5563053 | -> qtd queries não “cacheáveis”
| Qcache_queries_in_cache | 60782 | -> qtd queries em cache
| Qcache_total_blocks | 155994 | -> total de blocos utilizados
+-------------------------+-----------+
8 rows in set (0.00 sec)
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
19. Performance Tuning
MySQL Query Cache
• Para realizar a manutenção do espaço de cache do MySQL
Query Cache, podemos realizar o FLUSH do mesmo:
mysql> FLUSH QUERY CACHE;
Query OK, 0 rows affected (0.14 sec)
• Em caso de necessidade de reiniciar o cache para reparar
possíveis fragmentações dos dados (em caso de configurar o
cache muito grande):
mysql> RESET QUERY CACHE; --
Query OK, 0 rows affected (0.00 sec)
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
21. Performance Tuning
InnoDB Performance Tuning
• O InnoDB é de longe o atual Storage Engine mais utilizado
para médios e grandes ambientes por suas características que
tornam o MySQL muito parecido com o Oracle Database;
– Integridade Referencial;
– Transações;
– Níveis de Isolamento;
– MVCC;
– Tablespaces e Logs de Transação
– FullText Indexes – MySQL 5.6
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
22. Performance Tuning
InnoDB Performance Tuning
• O InnoDB foi comprado pela Oracle em 2005;
• É o Storage Engine transacional do MySQL;
• Passou a ser o motor padrão com o MySQL Oracle 5.5;
• No MySQL 5.1 foi lançado como InnoDB Plugin;
• Era difícil de instalar e manter;
• No MySQL Oracle 5.5 o Plugin já vem compilado;
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
23. Performance Tuning
InnoDB Performance Tuning
• Diferente do MyISAM, o InnoDB mantém uma estrutura de
memória denominada Buffer Pool que armazena de índices
(primários e secundários) e dados de tabelas;
• Várias são as suas variáveis de ambiente que, na maioria dos
casos, precisam ser adicionadas ao arquivo de configuração
para que possam ser colocadas em operação;
mysql> SHOW VARIABLES LIKE 'innodb%';
[...]
59 rows in set (0.00 sec)
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
24. Performance Tuning
InnoDB Buffer Pool
– Área de memória que armazena dados e índices de tabelas InnoDB;
– Trabalha com o algoritmo LRU (Least Recently Used) onde este
controla uma lista com duas sub-listas:
• Head, Young ou New – sub-lista com blocos de
dados acessados /utilizados recentemente;
• Tail ou Old – sub-lista que armazena blocos
dados que não foram acessados recentemente e
que serão despejados da memória caso
continuem não sendo utilizados;
– Utiliza um processo chamado de “eviction” para despejar páginas não
utilizadas da memória, dando lugar para novas páginas que chegam.
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
26. Performance Tuning
InnoDB Buffer Pool
– O InnoDB Buffer Pool é configurado através das seguintes
variáveis de ambiente:
• innodb_buffer_pool_size
– Poderá ser configurado com até 80% da memória disponível na
máquina servidora na qual o MySQL roda (SWAP!!!!)
• innodb_buffer_pool_size_instances
– Cada instância deverá contar com o mínimo de 1GB de espaço
para ser possível o particionamento do Buffer Pool;
– O comportamento do LRU poderá ser configurado através das
seguintes variáveis de ambiente:
• innodb_old_blocks_pct
• innodb_old_blocks_time
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
27. Performance Tuning
• innodb_buffer_pool_size=2G • innodb_buffer_pool_instances=2
BPoolInst01 BPoolInst02
EXT01 EXT01
EXT02 EXT02
EXT03 EXT03
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
28. Performance Tuning
• O InnoDB internamente
controla o acesso à novas TRX-01
transações de acordo com o TRX-02
nível de isolamento da
sessão ou global através dos TRX-03
chamados MUTEX, que
funciona como um funil;
• SHOW MUTEX STATUS
ajudará a detectar gargalos; InnoDB MUTEX
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
29. Performance Tuning
InnoDB Mutex
Nível Avançado!
• Mutex: The mutex name.
• Module: The source file where the mutex is defined.
• Count: How many times something has requested the mutex.
• Spin_waits: How many times InnoDB chose to spin-wait for the mutex to be free. Recall that
InnoDB first tries a spin wait and then falls back to an operating system wait.
• Spin_rounds: How many times InnoDB checked whether the mutex was free in a spin wait.
• OS_waits: How many times InnoDB fell back to an operating system wait for the mutex.
• OS_yields: How many times the thread waiting for the mutex yielded to the operating system so
another thread could run.
• OS_waits_time: If the timed_mutexes system
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
30. Performance Tuning
InnoDB Buffer Pool – Monitoramento
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 8791261184; in additional pool allocated 0
Buffer pool size 524288
Free buffers 0
Database pages 524203
Old database pages 193484
Modified db pages 0
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young 6878082, not young 0
0.00 youngs/s, 0.00 non-youngs/s
Pages read 7181405, created 2327676, written 2436786
0.00 reads/s, 0.00 creates/s, 0.44 writes/s
Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
LRU len: 524203, unzip_LRU len: 0
I/O sum[134]:cur[0], unzip sum[0]:cur[0]
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
31. Performance Tuning
InnoDB Buffer Pool – Monitoramento
– A cada 15 segundos um novo resultado de monitoramento do
InnoDB, de Locks e do Tablespace (compartilhado) do InnoDB
será gravado no log de erros do MySQL ou será impresso no
mysql client, caso o usuário esteja conectado;
mysql> CREATE TABLE mysql.innodb_monitor (i int) ENGINE=InnoDB;
Query OK, 0 rows affected (0.24 sec)
mysql> CREATE TABLE mysql.innodb_lock_monitor (i int) ENGINE=InnoDB;
Query OK, 0 rows affected (0.01 sec)
mysql> CREATE TABLE mysql.innodb_tablespace__monitor (i int)
ENGINE=InnoDB;
Query OK, 0 rows affected (0.00 sec)
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
32. Performance Tuning
[root@mysqlserver ~]# cat mysqld.err | less
=====================================
111129 22:45:56 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 20 seconds
-----------------
BACKGROUND THREAD
-----------------
srv_master_thread loops: 4 1_second, 4 sleeps, 0 10_second, 7 background, 7 flush
srv_master_thread log flush and writes: 4
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 4, signal count 4
Mutex spin waits 2, rounds 60, OS waits 0
RW-shared spins 5, rounds 150, OS waits 4
RW-excl spins 0, rounds 0, OS waits 0
Spin rounds per wait: 30.00 mutex, 30.00 RW-shared, 0.00 RW-excl
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
33. Performance Tuning
InnoDB - Variáveis de Ambiente
– innodb_flush_method = [ O_DIRECT | O_DSYNC ]
• O_DIRECT, estável e já disponível em MS Win e Unix Like
systems;
• O_SYNC, mais rápido, instável, problemas com double write;
– innodb_max_dirty_pages_pct = % - (default 90)
• Quantidade de páginas sujas que serão acumuladas antes do
processo de flush, que esvaziará essa área do buffer pool em
disco, aplicando as alterações de dados nos arquivos de
dados em disco;
– innodb_read_io_threads = 1 ... 64 – default 4
• Número de threads para ler blocos de dados ainda não
carregados na memória – início da estratégia de read-ahead
(leitura *sequêncial);
– innodb_write_io_threads = 1 ... 64 – default 4
• Número de threads destinadas às escritas de páginas sujas em
disco – caso o valor seja maior que 4, innodb_flush_method =
O_DIRECT;
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
34. Performance Tuning
InnoDB - Variáveis de Ambiente
– innodb_max_merge_io = 1 ... 64 – default 64
• Quantidade de requisições de recuperação de blocos
que fazem parte de uma mesma página que podem estar
separados entre memória (buffer pool) e disco –
quanto mais blocos de uma mesma extensão estiver em
buffer, melhor é para realização de sequential read-
ahead;
– innodb_flush_log_at_trx_commit = [0,1,2] – default 1
• Determina como o arquivo de log será aberto e as
páginas sujas escritas em tais arquivos, ou “a cada
COMMIT”, ou “a cada COMMIT e de tempos em tempos” ou
ainda somente de “tempos em tempos”;
– innodb_additional_mem_pool_size = 1M – default
• Interessante que o dicionário de dados ou metadados
do InnoDB permaneça em memória, facilitando as
consultas que possam ser realizadas ao mesmo;
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
35. Performance Tuning
InnoDB - Variáveis de Ambiente
– innodb_log_buffer_size = 8M – default
• Quantidade de logs que serão armazenados até que um
flush seja realizado. Para bancos que são alvos de
grandes transações, interessantes ter esta área maior
para suportar armazenar mais logs em memória,
realizar o COMMIT e então ir para o disco – o
contrário será pressão de I/O sentida pela hardware
do servidor;
– innodb_file_format = [ANTELOPE | BARRACUDA]
• Caso esteja utilizando MySQL 5.5, sem dúvida é
interessante alterar o formato de arquivo para
BARRACUDA, fast index creation, data compression...
– innodb_file_per_table = OFF – default
• Para utilizar a compressão de dados e outros recursos
do InnoDB Plugin 1.0.0 ++ com o MySQL 5.5, condição
sine-qua-non!
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
36. Performance Tuning
InnoDB – Variáveis de Status
• As variáveis de status são contadores em tempo real das
operações realizadas no MySQL;
mysql> SHOW STATUS LIKE 'innodb_buffer_pool%';
...
13 rows in set (0.08 sec)
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
39. Performance Tuning
InnoDB - Logs de Transação
– Interessante que não se trabalhe com o tamanho nem a
quantidade de logs padrão de instalação;
– A soma da quantidade de arquivos vezes o espaço que cada um
deles têm não pode ser maior ou igual à 4GB;
– Verifique a variável de status Innodb_log_waits para saber se
os logs estão pequenos para a operação atual;
mysql> SHOW STATUS LIKE 'innodb_log_waits';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| Innodb_log_waits | 21 |
+------------------+-------+
1 row in set (0.00 sec)
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011
40. Performance Tuning
InnoDB - Logs de Transação
– Para alterar os logs de transação, utilize sua janela de
manutenção e após um backup full, pare o MySQL, mova ou
remova os logs atuais e reconfigure o arquivo de configuração –
my.cnf/my.ini:
[mysqld]
# logs criados em /var/lib/mysql
innodb_log_file_size = 768M
innodb_log_files_in_group = 4
# criando logs em outro path
# innodb_log_group_home_dir = /disk2/innologs
Todos os direitos reservados à WBConsulting® – wbconsulting.com.br - 2011