Debug kehabisan memori dengan / var / log / messages

42

Laporan berikut dimasukkan ke dalam log pesan saya:

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

Tidak masalah jika masalah ini untuk httpd, mysqldatau postfixtetapi saya ingin tahu bagaimana saya bisa melanjutkan debug masalah.

Bagaimana saya bisa mendapatkan lebih banyak info tentang mengapa PID 9163 terbunuh dan saya tidak yakin apakah linux menyimpan sejarah untuk PID yang dihentikan di suatu tempat.

Jika ini terjadi di file log pesan Anda, bagaimana Anda akan memecahkan masalah ini langkah demi langkah?

# free -m

             total       used       free     shared    buffers     cached
Mem:          1655        934        721          0         10         52
-/+ buffers/cache:        871        784
Swap:          109          6        103`
ibedelovski
sumber
apa semua pesan tentang masalah muncul dmesg?
Stark07
Detail berguna tentang OOM - linux-mm.org/OOM_Killer .
slm

Jawaban:

57

Kernel akan mencatat banyak hal sebelum ini terjadi, tetapi sebagian besar mungkin tidak akan masuk /var/log/messages, tergantung pada bagaimana Anda (r)syslogddikonfigurasikan. Mencoba:

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

Yang pertama harus muncul beberapa kali dan yang terakhir hanya di satu atau dua tempat. Itu adalah file yang ingin Anda lihat.

Temukan baris "Kehabisan memori" asli di salah satu file yang juga berisi total_vm. Tiga puluh detik hingga satu menit (bisa lebih banyak, bisa lebih sedikit) sebelum garis itu Anda akan menemukan sesuatu seperti:

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

Anda juga harus menemukan tabel di suatu tempat antara garis itu dan garis "Kehabisan memori" dengan header seperti ini:

[ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name

Ini mungkin tidak memberi tahu Anda lebih dari yang Anda tahu, tetapi bidangnya adalah:

  • pid ID proses.
  • ID Pengguna uid .
  • ID grup Thread tgid .
  • total_vm Penggunaan memori virtual (dalam 4 kB halaman)
  • rss Penggunaan memori penduduk (dalam 4 kB halaman)
  • nr_ptes Entri tabel halaman
  • swapents Bertukar entri
  • oom_score_adj Biasanya 0; angka yang lebih rendah menunjukkan bahwa proses tersebut akan lebih kecil kemungkinannya untuk mati ketika pembunuh OOM dipanggil.

Anda sebagian besar dapat mengabaikan nr_ptesdan swapentsmeskipun saya percaya ini adalah faktor dalam menentukan siapa yang terbunuh. Ini belum tentu proses menggunakan sebagian besar memori, tetapi sangat mungkin. Untuk lebih lanjut tentang proses seleksi, lihat di sini . Pada dasarnya, proses yang berakhir dengan skor oom tertinggi terbunuh - itulah "skor" yang dilaporkan pada baris "Kehabisan memori"; sayangnya skor lainnya tidak dilaporkan tetapi tabel itu memberikan beberapa petunjuk dalam hal faktor.

Sekali lagi, ini mungkin tidak akan melakukan lebih dari menerangi yang sudah jelas: sistem kehabisan memori dan mysqlddipilih untuk mati karena membunuh itu akan melepaskan sebagian besar sumber daya . Ini tidak perlu berarti mysqldmelakukan kesalahan. Anda dapat melihat tabel untuk melihat apakah ada hal lain yang keluar dari jalur pada saat itu, tetapi mungkin tidak ada penyebab yang jelas: sistem dapat kehabisan memori hanya karena Anda salah menilai atau salah mengkonfigurasi proses yang sedang berjalan.

goldilocks
sumber
5
dmesgDi sinilah dijamin. Itu hanya akan ada /var/logjika daemon syslog membaca dari /dev/kmsg(yang biasanya memang demikian).
Patrick
2
@ Patrick Itu tergantung pada kapan Anda pergi mencari. Jika itu dicatat dalam salah satu file log normal (seharusnya, atau Anda telah melakukan sesuatu yang bodoh dengan logger Anda), itu akan ada di sana untuk waktu yang lama, sedangkan pada titik ini, jika OP ingin mendiagnosis masalah yang terjadi kemarin, atau sehari sebelumnya, dll., catatan mungkin tidak ada dmesglagi bahkan jika sistem dibiarkan berjalan.
goldilocks
6

Kunci untuk ini ada di dalam pesan itu sendiri - Kehabisan memori . Ketika kernel Linux kekurangan memori virtual (RAM fisik plus swap), kernel itu akan mulai mematikan proses dan itulah yang terjadi di sini. Sepertinya mysqldmenggunakan lebih dari 2GB memori virtual.

Berapa banyak RAM dan swap yang dimiliki sistem? Saya akan mempertimbangkan untuk menambahkan RAM ekstra atau, jika itu tidak mungkin, menambahkan swap tambahan. Sebagai perbaikan cepat untuk setidaknya mencegah proses dihentikan Anda bisa menambahkan file swap.

Pembaruan: Melihat jumlah RAM yang Anda miliki, Anda dapat langsung melihat masalahnya. Anda memiliki ~ 1,6GB RAM dan 100MB swap namun MySQL menggunakan lebih banyak RAM daripada itu. Itu menjelaskan mengapa Anda melihat proses dihentikan.

mjturner
sumber
total used free shared buffers cached Mem: 1655 934 721 0 10 52 -/+ buffers/cache: 871 784 Swap: 109 6 103 ini adalah output memori pada saat yang sama ketika proses itu dibunuh
ibedelovski
Bisakah Anda menempelkannya di pesan asli, dengan format dipertahankan? Akan membuatnya lebih mudah dibaca.
mjturner
Saya tidak terlalu bagus dalam memformat ... tapi sudah menempelkannya di pesan asli
ibedelovski