Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

O que verificar se a utilização da memória MySQL é alta

Um dos principais fatores de um servidor de banco de dados MySQL com bom desempenho é ter boa alocação e utilização de memória, especialmente ao executá-lo em um ambiente de produção. Mas como você pode determinar se a utilização do MySQL está otimizada? É razoável ter alta utilização de memória ou requer ajuste fino? E se eu me deparar com um vazamento de memória?

Vamos cobrir esses tópicos e mostrar o que você pode verificar no MySQL para determinar traços de alta utilização de memória.

Alocação de memória no MySQL

Antes de nos aprofundarmos no título do assunto específico, darei apenas uma breve informação sobre como o MySQL usa a memória. A memória desempenha um recurso significativo para velocidade e eficiência ao lidar com transações simultâneas e executar grandes consultas. Cada thread no MySQL exige memória que é usada para gerenciar conexões de clientes, e essas threads compartilham a mesma memória base. Variáveis ​​como thread_stack (pilha para threads), net_buffer_length (para buffer de conexão e buffer de resultado) ou com max_allowed_packet onde conexão e resultado aumentarão dinamicamente até esse valor quando necessário, são variáveis ​​que afetam a utilização da memória. Quando um encadeamento não é mais necessário, a memória alocada para ele é liberada e retornada ao sistema, a menos que o encadeamento volte para o cache de encadeamentos. Nesse caso, a memória permanece alocada. Junções de consulta, caches de consulta, classificação, cache de tabela, definições de tabela exigem memória no MySQL, mas são atribuídas a variáveis ​​de sistema que você pode configurar e definir.

Na maioria dos casos, as variáveis ​​específicas de memória definidas para uma configuração são direcionadas a uma configuração específica baseada em armazenamento, como MyISAM ou InnoDB. Quando uma instância do mysqld é gerada no sistema host, o MySQL aloca buffers e caches para melhorar o desempenho das operações do banco de dados com base nos valores definidos em uma configuração específica. Por exemplo, as variáveis ​​mais comuns que todo DBA definirá no InnoDB são as variáveis ​​innodb_buffer_pool_size e innodb_buffer_pool_instances, ambas relacionadas à alocação de memória do buffer pool que contém dados em cache para tabelas InnoDB. É desejável se você tiver muita memória e espera manipular grandes transações configurando innodb_buffer_pool_instances para melhorar a simultaneidade dividindo o pool de buffers em várias instâncias do pool de buffers.

Enquanto para MyISAM, você tem que lidar com key_buffer_size para lidar com a quantidade de memória que o buffer de chave irá manipular. MyISAM também aloca buffer para cada thread concorrente que contém uma estrutura de tabela, estruturas de coluna para cada coluna e um buffer de tamanho 3 * N são alocados (onde N é o comprimento máximo da linha, sem contar as colunas BLOB). MyISAM também mantém um buffer de linha extra para uso interno.

O MySQL também aloca memória para tabelas temporárias, a menos que fique muito grande (determinado por tmp_table_size e max_heap_table_size). Se você estiver usando tabelas MEMORY e a variável max_heap_table_size estiver configurada muito alta, isso também pode ocupar uma grande memória, pois a variável de sistema max_heap_table_size determina o tamanho que uma tabela pode crescer e não há conversão para o formato em disco.

O MySQL também possui um Esquema de Desempenho que é um recurso para monitorar as atividades do MySQL em um nível baixo. Uma vez ativado, ele aloca memória dinamicamente de forma incremental, dimensionando seu uso de memória para a carga real do servidor, em vez de alocar a memória necessária durante a inicialização do servidor. Depois que a memória é alocada, ela não é liberada até que o servidor seja reiniciado.

O MySQL também pode ser configurado para alocar grandes áreas de memória para seu buffer pool se estiver usando Linux e se o kernel estiver habilitado para suporte a páginas grandes, ou seja, usando HugePages.

O que verificar quando a memória do MySQL estiver alta

Verificar consultas em execução

É muito comum para os DBAs MySQL tocarem primeiro no que está acontecendo com o servidor MySQL em execução. Os procedimentos mais básicos são verificar a lista de processos, verificar o status do servidor e verificar o status do mecanismo de armazenamento. Para fazer essas coisas, basicamente, você só precisa executar a série de consultas fazendo login no MySQL. Ver abaixo:

Para visualizar as consultas em execução,

mysql> SHOW [FULL] PROCESSLIST;

A visualização da lista de processos atual revela consultas que estão sendo executadas ativamente ou até mesmo processos inativos ou inativos. É muito importante e uma rotina significativa ter um registro das consultas que estão em execução. Conforme observado em como o MySQL aloca memória, as consultas em execução utilizarão alocação de memória e podem causar problemas de desempenho drasticamente se não forem monitoradas.

Visualize as variáveis ​​de status do servidor MySQL,

mysql> SHOW SERVER STATUS\G

ou filtre variáveis ​​específicas como

mysql> SHOW SERVER STATUS WHERE variable_name IN ('<var1>', 'var2'...);

As variáveis ​​de status do MySQL servem como suas informações estatísticas para obter dados métricos para determinar o desempenho do MySQL observando os contadores fornecidos pelos valores de status. Existem certos valores aqui que dão uma visão geral do impacto na utilização da memória. Por exemplo, verificando o número de encadeamentos, o número de caches de tabela ou o uso do buffer pool,

...

| Created_tmp_disk_tables                 | 24240 |

| Created_tmp_tables                      | 334999 |

…

| Innodb_buffer_pool_pages_data           | 754         |

| Innodb_buffer_pool_bytes_data           | 12353536         |

...

| Innodb_buffer_pool_pages_dirty          | 6         |

| Innodb_buffer_pool_bytes_dirty          | 98304         |

| Innodb_buffer_pool_pages_flushed        | 30383         |

| Innodb_buffer_pool_pages_free           | 130289         |

…

| Open_table_definitions                  | 540 |

| Open_tables                             | 1024 |

| Opened_table_definitions                | 540 |

| Opened_tables                           | 700887 |

...

| Threads_connected                             | 5 |

...

| Threads_cached    | 2 |

| Threads_connected | 5     |

| Threads_created   | 7 |

| Threads_running   | 1 |

Visualize o status do monitor do mecanismo, por exemplo, status do InnoDB

mysql> SHOW ENGINE INNODB STATUS\G

O status do InnoDB também revela o status atual das transações que o mecanismo de armazenamento está processando. Ele fornece o tamanho do heap de uma transação, índices de hash adaptativos que revelam seu uso de buffer ou mostra as informações do pool de buffer innodb como no exemplo abaixo:

---TRANSACTION 10798819, ACTIVE 0 sec inserting, thread declared inside InnoDB 1201

mysql tables in use 1, locked 1

1 lock struct(s), heap size 1136, 0 row lock(s), undo log entries 8801

MySQL thread id 68481, OS thread handle 139953970235136, query id 681821 localhost root copy to tmp table

ALTER TABLE NewAddressCode2_2 ENGINE=INNODB



…

-------------------------------------

INSERT BUFFER AND ADAPTIVE HASH INDEX

-------------------------------------

Ibuf: size 528, free list len 43894, seg size 44423, 1773 merges

merged operations:

 insert 63140, delete mark 0, delete 0

discarded operations:

 insert 0, delete mark 0, delete 0

Hash table size 553193, node heap has 1 buffer(s)

Hash table size 553193, node heap has 637 buffer(s)

Hash table size 553193, node heap has 772 buffer(s)

Hash table size 553193, node heap has 1239 buffer(s)

Hash table size 553193, node heap has 2 buffer(s)

Hash table size 553193, node heap has 0 buffer(s)

Hash table size 553193, node heap has 1 buffer(s)

Hash table size 553193, node heap has 1 buffer(s)

115320.41 hash searches/s, 10292.51 non-hash searches/s

...

----------------------

BUFFER POOL AND MEMORY

----------------------

Total large memory allocated 2235564032

Dictionary memory allocated 3227698

Internal hash tables (constant factor + variable factor)

    Adaptive hash index 78904768        (35404352 + 43500416)

    Page hash           277384 (buffer pool 0 only)

    Dictionary cache    12078786 (8851088 + 3227698)

    File system         1091824 (812272 + 279552)

    Lock system         5322504 (5313416 + 9088)

    Recovery system     0 (0 + 0)

Buffer pool size   131056

Buffer pool size, bytes 2147221504

Free buffers       8303

Database pages     120100

Old database pages 44172

Modified db pages  108784

Pending reads      0

Pending writes: LRU 2, flush list 342, single page 0

Pages made young 533709, not young 181962

3823.06 youngs/s, 1706.01 non-youngs/s

Pages read 4104, created 236572, written 441223

38.09 reads/s, 339.46 creates/s, 1805.87 writes/s

Buffer pool hit rate 1000 / 1000, young-making rate 12 / 1000 not 5 / 1000

Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s

LRU len: 120100, unzip_LRU len: 0

I/O sum[754560]:cur[8096], unzip sum[0]:cur[0]

…

Outra coisa a acrescentar, você também pode usar o Esquema de Desempenho e o esquema sys para monitorar o consumo e a utilização de memória pelo seu servidor MySQL. Por padrão, a maioria das instrumentações está desabilitada por padrão, portanto, há ações manuais a serem feitas para usar isso.

Verificar trocas 

De qualquer forma, é provável que o MySQL esteja trocando sua memória para o disco. Esta é muitas vezes uma situação muito comum, especialmente quando o servidor MySQL e o hardware subjacente não estão configurados de forma otimizada em paralelo com os requisitos esperados. Há certos casos em que a demanda de tráfego não foi antecipada, a memória pode crescer cada vez mais, especialmente se consultas incorretas forem executadas, consumindo ou utilizando muito espaço de memória, causando degradação do desempenho, pois os dados são coletados no disco em vez do buffer. Para verificar a troca, basta executar o comando freemem ou vmstat como abaixo,

[[email protected] ~]# free -m

              total        used free      shared buff/cache available

Mem:           3790 2754         121 202 915         584

Swap:          1535 39        1496

[[email protected] ~]# vmstat 5 5

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----

 r  b swpd   free buff  cache si so    bi bo in cs us sy id wa st

 2  0 40232 124100      0 937072 2 3 194  1029 477 313 7 2 91 1  0

 0  0 40232 123912      0 937228 0 0   0 49 1247 704 13 3 84  0 0

 1  0 40232 124184      0 937212 0 0   0 35 751 478 6 1 93  0 0

 0  0 40232 123688      0 937228 0 0   0 15 736 487 5 1 94  0 0

 0  0 40232 123912      0 937220 0 0   3 74 1065 729 8 2 89  0 0

Você também pode verificar usando procfs e coletar informações como ir para /proc/vmstat ou /proc/meminfo.

Usando Perf, gdb e Valgrind com Massif

Usar ferramentas como perf, gdb e valgrind ajuda você a se aprofundar em um método mais avançado de determinar a utilização de memória do MySQL. Há momentos em que um resultado interessante se torna um mistério de resolver o consumo de memória que leva à sua perplexidade no MySQL. Isso torna necessário ter mais ceticismo e usar essas ferramentas ajuda a investigar como o MySQL está usando o manuseio de memória, desde a alocação até a utilização para processamento de transações ou processos. Isso é útil, por exemplo, se você estiver observando que o MySQL está se comportando de maneira anormal, o que pode causar uma configuração incorreta ou levar a descobertas de vazamentos de memória.

Por exemplo, usar perf no MySQL revela mais informações em um relatório de nível de sistema:

[[email protected] ~]# perf report --input perf.data --stdio

# To display the perf.data header info, please use --header/--header-only options.

#

#

# Total Lost Samples: 0

#

# Samples: 54K of event 'cpu-clock'

# Event count (approx.): 13702000000

#

# Overhead  Command Shared Object        Symbol                                                                                                                                                                                             

# ........  ....... ...................  ...................................................................................................................................................................................................

#

    60.66%  mysqld [kernel.kallsyms]    [k] _raw_spin_unlock_irqrestore

     2.79%  mysqld   libc-2.17.so         [.] __memcpy_ssse3

     2.54%  mysqld   mysqld             [.] ha_key_cmp

     1.89%  mysqld   [vdso]             [.] __vdso_clock_gettime

     1.05%  mysqld   mysqld             [.] rec_get_offsets_func

     1.03%  mysqld   mysqld             [.] row_sel_field_store_in_mysql_format_func

     0.92%  mysqld   mysqld             [.] _mi_rec_pack

     0.91%  mysqld   [kernel.kallsyms]    [k] finish_task_switch

     0.90%  mysqld   mysqld             [.] row_search_mvcc

     0.86%  mysqld   mysqld             [.] decimal2bin

     0.83%  mysqld   mysqld             [.] _mi_rec_check

….

Como este pode ser um tópico especial para se aprofundar, sugerimos que você examine esses blogs externos realmente bons como suas referências, Perf Basics for MySQL Profiling, Finding MySQL Scaling Problems Using perf, ou aprenda como depurar usando valgrind com massif.

Maneira eficiente de verificar a utilização da memória MySQL

O uso do ClusterControl alivia qualquer rotina complicada, como revisar seus runbooks ou até mesmo criar seus próprios playbooks que forneceriam relatórios para você. No ClusterControl, você tem Dashboards (usando SCUMM) onde você pode ter uma visão geral rápida de seu(s) nó(s) MySQL. Por exemplo, visualizando o painel geral do MySQL,

você pode determinar o desempenho do nó MySQL,

Você vê que as imagens acima revelam variáveis ​​que afetam a utilização da memória do MySQL. Você pode verificar como as métricas para caches de classificação, tabelas temporárias, threads conectados, cache de consulta ou mecanismos de armazenamento innodb buffer pool ou buffer de chave do MyISAM.

O uso do ClusterControl oferece uma ferramenta de utilidade completa onde você também pode verificar as consultas em execução para determinar os processos (consultas) que podem afetar a alta utilização da memória. Veja abaixo um exemplo,

Visualizar as variáveis ​​de status do MySQL é muito fácil,

Você também pode ir para Performance -> Innodb Status para revelar o status atual do InnoDB de seus nós de banco de dados. Além disso, no ClusterControl, um incidente é detectado, ele tentará coletar o incidente e mostrará o histórico como um relatório que fornece o status do InnoDB, conforme mostrado em nosso blog anterior sobre o MySQL Freeze Frame.

Resumo


Solucionar problemas e diagnosticar seu banco de dados MySQL ao suspeitar de alta utilização de memória não é tão difícil, desde que você conheça os procedimentos e ferramentas a serem usados. Usar a ferramenta certa oferece mais flexibilidade e produtividade mais rápida para fornecer correções ou soluções com chance de maior resultado.