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

Publicado por Edilson Osorio Junior em 20/02/2013

[ Hits: 7.647 ]

 


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

Corrigindo erro ao adicionar plugin AddThis no Joomla! 3.0

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

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

Backup de arquivos na Cloud com AWS Amazon S3 e PHP

Leitura recomendada

MariaDB no Debian 7

Servidores Debian - Adicionando suporte ao MS SQL no PHP 5.3

Salvando datas no MySQL pelo Gambas2

MySQL no Asterisk

SQLite Manager

  

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