Depurar falta de memória com / var / log / messages

42

O seguinte relatório é lançado no meu log de mensagens:

kernel: Out of memory: Kill process 9163 (mysqld) score 511 or sacrifice child
kernel: Killed process 9163, UID 27, (mysqld) total-vm:2457368kB, anon-rss:816780kB, file-rss:4kB

Não importa se esse problema é para httpd, mysqldou postfixestou curioso para saber como posso continuar depurando o problema.

Como posso obter mais informações sobre por que o PID 9163 foi morto e não tenho certeza se o linux mantém o histórico dos PIDs terminados em algum lugar.

Se isso ocorrer no seu arquivo de log de mensagens, como você solucionará esse problema passo a passo?

# free -m

             total       used       free     shared    buffers     cached
Mem:          1655        934        721          0         10         52
-/+ buffers/cache:        871        784
Swap:          109          6        103`
ibedelovski
fonte
em que todas as mensagens sobre o problema aparecem dmesg?
Stark07
Detalhes úteis sobre o OOM - linux-mm.org/OOM_Killer .
slm

Respostas:

57

O kernel já registrou várias coisas antes que isso acontecesse, mas a maioria provavelmente não estará presente /var/log/messages, dependendo de como o seu (r)syslogdestá configurado. Experimentar:

grep oom /var/log/*
grep total_vm /var/log/*

O primeiro deve aparecer várias vezes e o último em apenas um ou dois lugares. Esse é o arquivo que você deseja examinar.

Encontre a linha "Sem memória" original em um dos arquivos que também contém total_vm. Trinta segundos a um minuto (poderia ser mais, poderia ser menos) antes dessa linha, você encontrará algo como:

kernel: foobar invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0

Você também deve encontrar uma tabela em algum lugar entre essa linha e a linha "Memória insuficiente" com cabeçalhos como este:

[ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name

Isso pode não lhe dizer muito mais do que você já sabe, mas os campos são:

  • pid O ID do processo.
  • ID do usuário uid .
  • tgid ID do grupo de encadeamentos .
  • total_vm Uso de memória virtual (em páginas de 4 kB)
  • rss Uso de memória residente (em páginas de 4 kB)
  • nr_ptes Entradas da tabela de páginas
  • swapents Entradas de swap
  • oom_score_adj Normalmente 0; um número menor indica que o processo terá menos probabilidade de morrer quando o assassino do OOM for invocado.

Você pode ignorar nr_ptese, swapentsapesar de acreditar que esses são fatores para determinar quem é morto. Este não é necessariamente o processo que utiliza mais memória, mas é muito provável que seja. Para mais informações sobre o processo de seleção, clique aqui . Basicamente, o processo que termina com a maior pontuação final é eliminado - essa é a "pontuação" relatada na linha "Memória insuficiente"; infelizmente, as outras pontuações não são relatadas, mas essa tabela fornece algumas dicas em termos de fatores.

Novamente, isso provavelmente não fará muito mais do que esclarecer o óbvio: o sistema ficou sem memória e mysqldfoi escolhido para morrer porque matá-lo liberaria mais recursos . Isso não significa necessário mysqldestá fazendo algo errado. Você pode olhar para a tabela para ver se havia algo errado na época, mas pode não haver nenhum culpado: o sistema pode ficar sem memória simplesmente porque você julgou mal ou configurou incorretamente os processos em execução.

Cachinhos Dourados
fonte
5
dmesgé onde isso é garantido. Ele estará disponível apenas /var/logse o daemon syslog ler /dev/kmsg(o que normalmente acontece).
9103 Patrick
2
@ Patrick Isso depende de quando você vai procurar. Se ele estiver gravado em um dos logs de arquivo normais (deveria ser, ou você fez algo estúpido com o seu logger), ele estará lá por um longo tempo, enquanto que, a essa altura, se o OP quiser diagnosticar um problema que ocorreu ontem, ou no dia anterior, etc., o registro pode não estar dmesgmais, mesmo que o sistema tenha sido deixado em execução.
goldilocks
6

A chave para isso está na própria mensagem - Memória insuficiente . Quando o kernel do Linux está sem memória virtual (RAM física mais swap), ele começa a matar processos e foi exatamente isso que aconteceu aqui. Parece que mysqldestava usando mais de 2 GB de memória virtual.

Quanta RAM e troca o sistema possui? Eu consideraria adicionar RAM extra ou, se isso não for possível, adicionar troca extra. Como uma solução rápida para, pelo menos, impedir que os processos sejam encerrados, você pode adicionar um arquivo de troca.

Atualização: olhando a quantidade de RAM que você possui, você pode ver imediatamente o problema. Você tem ~ 1.6GB de RAM e 100MB de swap, mas o MySQL está usando muito mais RAM que isso. Isso explica por que você está vendo processos sendo encerrados.

mjturner
fonte
total used free shared buffers cached Mem: 1655 934 721 0 10 52 -/+ buffers/cache: 871 784 Swap: 109 6 103 esta é a saída de memória ao mesmo tempo quando o processo foi morto
ibedelovski
Você pode colar isso na mensagem original com a formatação retida? Facilitaria a leitura.
Mjturner # 9/14
Eu não sou realmente bom na formatação ... mas já colá-lo na mensagem original
ibedelovski