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?


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.


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

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

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


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.


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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.