MySQL, Amazon Web Services (AWS) EC2 e Out of Memory (OOM)

Publicado por Edilson Osorio Junior em 20/02/2013

[ Hits: 7.496 ]

 


MySQL, Amazon Web Services (AWS) EC2 e Out of Memory (OOM)



Administro um site rodando em uma instância t1-micro no Amazon Web Services (AWS) e na última semana, tenho tido muitos problemas de queda do MySQL.

Analisando o syslog, encontrei diversas vezes a mesma informação:
Feb 12 06:27:55 ip-xx.xx.xx.xx kernel: [8495594.190585] Out of memory: Kill process 746 (mysqld) score 143 or sacrifice child
Feb 12 06:27:55 ip-xx.xx.xx.xx kernel: [8495594.190600] Killed process 746 (mysqld) total-vm:886216kB, anon-rss:86132kB, file-rss:0kB


Eu já havia colocado uma linha na crontab para iniciar o MySQL, caso ele estivesse fora da memória, mas o caso, é que ele continuava caindo e eu não conseguia entender o por quê.

Na verdade, o por quê está claro no syslog: OOM ou Out Of Memory

Isto significa que, em algum momento, a memória se esgotou e então o sistema ativa um processo para lidar com esta situação.

O kernel do GNU/Linux utiliza uma implementação chamada "Optimistic Memory Allocation", que permite que as aplicações solicitem memória e recebam "mais" do que poderia ser ofertado.

O sistema assume (e espera) que todas aplicações rodando não utilizem toda a memória requerida de uma vez. Dessa forma, as aplicações acham que tem disponível uma determinada quantidade de memória, mas na realidade não tem.

Então, quando a memória do sistema chega no seu limite, o OOM Killer (Out Of Memory Killer) entra em ação. Ele é responsável por lidar com os processos em memória quando não há mais espaço para trabalhar, evitando que todo o sistema fique travado.

O OOM Killer procura por um processo que ele possa liquidar e então executa-o, retirando-o da memória. Ele utiliza um sistema heurístico para escolher quais processos devem ser encerrados e é baseado em um score associado à cada processo, que é calculado pelo oom_badness(), também conhecido como badness(), dentro do kernel.

O algoritmo é relativamente simples e basicamente funciona da seguinte maneira: Quanto mais memória um processo usa, mais pontos ele acumula no seu score.

Outros fatores que ele considera:
  • Consumo de memória;
  • Ownership do processo;
  • Idade do processo;
  • CPU time;
  • Valor de nice do processo;
  • Flags do processo;
  • Configuração do "oom_adj/oom_score_adj".

É nessa hora que o MySQL pode se dar mal. Simplesmente porque ele será o processo que consumirá mais memória no seu sistema.

Como resolver esse problema, então?

No meu caso, resolvi adicionando uma partição de SWAP à minha instância. Verifiquei que instâncias no AWS em princípio não possuem uma partição de SWAP, e, em casos onde a instância possui pouca memória, isso pode ser primordial para o bom funcionamento do sistema.

O processo é simples e vou exemplificar como pode ser executado em duas etapas, a primeira no console do AWS e a segunda em um shell para a instância:

1. Abra o Console AWS (http://console.aws.amazon.com) e vá para: EC2 → Volumes

2. Clique em: "Create Volume". Selecione o tipo (Standard), o tamanho e a zona;

3. Clique com o botão direito em cima do volume e selecione "Attach Volume", para associá-lo à instância que está rodando;

4. Abra um shell para a sua instância:

ssh -i <arq.pem> <usuario>@<IP_da_instancia>

Obs.: Vamos exemplificar utilizando /dev/xvdf, para o novo volume anexado.

5. Execute o fdisk:

sudo fdisk /dev/xvdf

E utilize a sequência:

1. n		   Cria uma nova partição;
2. p		   Primária;
3. Enter	   Seleciona o número 1;
4. Enter	   Seleciona o primeiro setor;
5. Enter	   Seleciona o último setor;
6. t		   Para selecionar o tipo de partição;
7. 82		   Linux swap;
8. w		   Salva e sai.


Depois ative a SWAP:

sudo mkswap /dev/xvdf1
$ sudo swapon /dev/xvdf1


Pronto, criamos um novo volume, anexamos à instância rodando, particionamos como SWAP e o ativamos.

Mas existem outras maneiras de resolver o problema, como:

1. Ajustando adequadamente as configurações e buffers do MySQL. Ex.: key_buffer_size, innodb_buffer_pool;

2. Ajustando o OOM score do seu sistema, por exemplo:

# cat /proc/$(pidof mysqld)/oom_score_adj
# echo '-20' > /proc/$(pidof mysqld)/oom_score_adj
# cat /proc/$(pidof mysqld)/oom_score


O range do OOM Score vai de -1000 a 1000 (ou -17 até 15 em sistemas mais antigos). Lembrando que, utilizando o valor mínimo, não desabilita o OOM Score, somente reduz suas chances de ser convidado a se retirar da memória.

Dados adicionais

Informações mais detalhadas podem ser encontradas no artigo (em inglês):
Dados do AWS:
  • Amazon AWS Micro Instance:
  • 613 MiB memory
  • Up to 2 EC2 Compute Units (for short periodic bursts)
  • EBS storage only
  • 32-bit or 64-bit platform
  • I/O Performance: Low
  • EBS-Optimized Available: No
  • API name: t1.micro

Outras dicas deste autor

Problemas com driver Wi-Fi Broadcom b43 em netbook HP [Resolvido] - Fedora 17

Backup de arquivos na Cloud com AWS Amazon S3 e PHP

Erro ao instalar Fedora 17 usando Kickstart por PXE e com IP fixo [Resolvido]

Corrigindo erro ao adicionar plugin AddThis no Joomla! 3.0

Leitura recomendada

Instalando MariaDB no CentOS 6.5

Alterando senha de usuário no MySQL

Recuperar senha de root do MySQL

MariaDB no Debian 7

MongoDB no Python 3

  

Comentários
[1] Comentário enviado por ruancabral em 01/03/2016 - 23:17h

puts me ajudou muito cara tutorial perfeito!

[2] Comentário enviado por osoriojr em 02/03/2016 - 11:24h

Obrigado!

[3] Comentário enviado por ruancabral em 05/03/2016 - 23:26h

ola gostaria de fazer uma pergunta, como eu gravo para que toda vez que eu reiniciar a máquina ele reconheça no ato invés de eu dar o comando "sudo swapon /dev/xvdf1" depois do reboot



Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts