Uso máximo de memória MySQL

111

Gostaria de saber como é possível definir um limite superior para a quantidade de memória que o MySQL usa em um servidor Linux.

No momento, o MySQL continuará ocupando memória a cada nova consulta solicitada, de forma que eventualmente fique sem memória. Existe uma maneira de colocar um limite para que não mais do que essa quantidade seja usada pelo MySQL?

Shilovk
fonte
4
O MySQL não "ocupa memória para cada nova consulta e eventualmente acaba". O uso de memória é muito mais complexo do que isso.
Rick James

Respostas:

183

O uso máximo de memória do MySQL depende muito do hardware, de suas configurações e do próprio banco de dados.

Hardware

O hardware é a parte óbvia. Quanto mais RAM, melhores e mais rápidos discos ftw . Porém, não acredite nessas cartas de notícias mensais ou semanais. O MySQL não escala linear - nem mesmo em hardware Oracle. É um pouco mais complicado do que isso.

O ponto principal é: não existe uma regra geral para o que é recomendado para sua configuração do MySQL. Tudo depende do uso atual ou das projeções.

Configurações e banco de dados

O MySQL oferece inúmeras variáveis ​​e opções para otimizar seu comportamento. Se você tiver problemas, realmente precisa se sentar e ler o manual (f'ing).

Quanto ao banco de dados - algumas restrições importantes:

  • motor de mesa ( InnoDB, MyISAM...)
  • Tamanho
  • índices
  • uso

A maioria das dicas do MySQL sobre stackoverflow informará sobre 5-8 as chamadas configurações importantes. Em primeiro lugar, nem todos eles importam - por exemplo, alocar muitos recursos para o InnoDB e não usar o InnoDB não faz muito sentido porque esses recursos são desperdiçados.

Ou - muitas pessoas sugerem aumentar a max_connectionvariável - bem, eles mal sabem que isso também implica que o MySQL alocará mais recursos para atendê-los max_connections- se necessário. A solução mais óbvia pode ser fechar a conexão do banco de dados em seu DBAL ou diminuir o wait_timeoutpara liberar esses threads.

Se você me entende - há muito, muito para ler e aprender.

Motores

Os mecanismos de mesa são uma decisão muito importante, muitas pessoas se esquecem deles logo no início e de repente se vêem lutando com uma MyISAMmesa de 30 GB que trava e bloqueia todo o seu aplicativo.

Não quero dizer que MyISAM é uma merda , mas InnoDBpode ser ajustado para responder quase ou quase tão rápido quanto MyISAMe oferece algo como travamento de linha, UPDATEenquantoMyISAM trava a tabela inteira quando é escrito.

Se você tem liberdade para executar o MySQL em sua própria infraestrutura, também pode verificar o servidor percona, porque inclui muitas contribuições de empresas como Facebook e Google (eles sabem rápido), também inclui o próprio em substituição de InnoDB, chamado XtraDB.

Veja minha essência para configuração de percona-server (e -client) (no Ubuntu): http://gist.github.com/637669

Tamanho

O tamanho do banco de dados é muito, muito importante - acredite ou não, a maioria das pessoas no Intarwebs nunca lidou com uma configuração grande e intensa do MySQL, mas ela realmente existe. Algumas pessoas vão trollar e dizer algo como, "Use PostgreSQL !!! 111", mas vamos ignorá-los por enquanto.

O resultado final é: a julgar pelo tamanho, a decisão sobre o hardware deve ser feita. Você realmente não pode fazer um banco de dados de 80 GB rodar rapidamente em 1 GB de RAM.

Índices

Não é: quanto mais, melhor. Apenas os índices necessários devem ser definidos e o uso deve ser verificado com EXPLAIN. Adicione a isso que o MySQL EXPLAINé realmente limitado, mas é um começo.

Configurações sugeridas

Sobre esses my-large.cnfe os my-medium.cnfarquivos - nem sei para quem foram escritos. Faça o seu próprio.

Cartilha de ajuste

Um ótimo começo é a cartilha de ajuste . É um script bash (dica: você vai precisar do linux) que pega a saída de SHOW VARIABLESeSHOW STATUS e envolve em uma recomendação útil. Se o seu servidor já rodou há algum tempo, a recomendação será melhor, pois haverá dados para se basear.

O tuning primer não é um molho mágico. Você ainda deve ler sobre todas as variáveis ​​que ele sugere que mudem.

Lendo

Eu realmente gosto de recomendar o mysqlperformanceblog . É um ótimo recurso para todos os tipos de dicas relacionadas ao MySQL. E não é apenas o MySQL, eles também sabem muito sobre o hardware certo ou recomendam configurações para AWS, etc. Esses caras têm anos e anos de experiência.

Outro grande recurso é o planet-mysql , é claro.

Até
fonte
Eu não sei sobre tuning primer, como isso se compara mysqltuner?
greg0ire 01 de
38

Usamos estas configurações:

etc/my.cnf
innodb_buffer_pool_size = 384M
key_buffer = 256M
query_cache_size = 1M
query_cache_limit = 128M
thread_cache_size = 8
max_connections = 400
innodb_lock_wait_timeout = 100

para um servidor com as seguintes especificações:

Dell Server
CPU cores: Two
Processor(s): 1x Dual Xeon
Clock Speed: >= 2.33GHz
RAM: 2 GBytes
Disks: 1×250 GB SATA
Ignacio Pascual
fonte
16
Eu acho que você (e o autor ao qual você faz o link) tem query_cache_size e query_cache_limit da maneira errada. Você está dizendo ao MySQL: aloque um cache de 1 MB, mas não coloque nenhuma consulta com mais de 128 MB. dev.mysql.com/doc/refman/5.0/en/query-cache-configuration.html
agtb
Eu diminuiria max_connections. Decidiria qual mecanismo usar e não alocaria muito espaço para ambos.
Rick James
19

O uso da memória do banco de dados é um tópico complexo. The MySQL Performance Blog faz um bom trabalho ao cobrir sua pergunta e lista muitos motivos pelos quais é extremamente impraticável "reservar" memória.

Se você realmente quiser impor um limite rígido, poderá fazê-lo, mas terá que fazê-lo no nível do sistema operacional, pois não há configuração embutida. No Linux, você pode utilizar o ulimit , mas provavelmente terá que modificar a maneira como o MySQL inicia para impor isso.


A melhor solução é ajustar o seu servidor, de forma que uma combinação das configurações de memória do MySQL usuais resulte em um uso de memória geralmente menor pela instalação do MySQL. É claro que isso terá um impacto negativo no desempenho do seu banco de dados, mas algumas das configurações que você pode ajustar my.inisão:

key_buffer_size
query_cache_size
query_cache_limit
table_cache
max_connections
tmp_table_size
innodb_buffer_pool_size

Eu começaria lá e veria se você consegue os resultados que deseja. Existem muitos artigos por aí sobre como ajustar as configurações de memória do MySQL.


Editar:

Observe que alguns nomes de variáveis mudaram nas versões 5.1.x mais recentes do MySQL .

Por exemplo:

table_cache

É agora:

table_open_cache
zumbat
fonte
2
Oi! Obrigado pela sua resposta. Percebi que a equação que as pessoas citam é a seguinte: key_buffer_size + (read_buffer_size + sort_buffer_size) * max_connections = Total Memory. Eu defini o seguinte: key_buffer_size = 128M, read_buffer_size = 1M, sort_buffer_size = 2M, max_connections = 120 e a memória total no servidor é 512M. No entanto, depois de muitas consultas, a memória livre caiu para menos de 12 milhões e provavelmente continuaria a cair com o uso posterior. Existe uma razão para isso e pode ser evitado? Obrigado!
Ou talvez eu precise levar em consideração não a memória total no servidor (512M), mas a memória livre (ou seja, memória disponível após carregar todos os programas relacionados ao sistema operacional e outros)?
1
Se você for modificar tmp_table_size com a intenção de aumentar o tamanho das tabelas temporárias que podem ser armazenadas na RAM, lembre-se de aumentar também o max_heap_table_size - já que o MySQL usa o mínimo dos dois ...
Dave Rix
1
@TimothyMilsud - Nenhuma fórmula como essa realmente funciona. E a maioria dos servidores funciona bem quando uma fórmula afirma que muita RAM está sendo usada.
Rick James
19

mysqld.exe estava usando 480 MB de RAM. Descobri que adicionei este parâmetro ao my.ini

table_definition_cache = 400

que reduziu o uso de memória de mais de 400.000 kb para 105.000 kb

Sarvar Nishonboev
fonte
Em que seção isso vai? Eu adicionei ao meu e o serviço recusou-se a iniciar.
Erro de sintaxe
Esqueça, mudei para [wampmysqld] e funcionou muito bem e reduziu significativamente a memória que estava usando. Acho que também pode ter acelerado os carregamentos de página do meu host local, eles parecem mais rápidos agora.
Erro de sintaxe
Embora o padrão e o mínimo sejam 400, o que o elevou a mais de 400 no seu caso?
Wadih M.
5

em /etc/my.cnf:

[mysqld]
...

performance_schema = 0

table_cache = 0
table_definition_cache = 0
max-connect-errors = 10000

query_cache_size = 0
query_cache_limit = 0

...

Bom trabalho no servidor com 256 MB de memória.

Shilovk
fonte
Por que é table_definition_cache= 0? Alguma explicação seria bom. E você basicamente não está armazenando consultas em cache ... mesmo efeito se você query_cache_type = 0:)
Khom Nazid 01 de
0

Se você está procurando otimizar seu contêiner docker mysql, o comando abaixo pode ajudar. Consegui executar o mysql docker container de 480 MB a meros 100 MB

docker run -d -p 3306: 3306 -e MYSQL_DATABASE = teste -e MYSQL_ROOT_PASSWORD = tooor -e MYSQL_USER = teste -e MYSQL_PASSWORD = teste -v / mysql: / var / lib / mysql --name mysqldb --table_definition_cache = mysql --table_definition_cache --performance_schema = 0 --default-authentication-plugin = mysql_native_password

Rohit Salecha
fonte