OOM meskipun tersedia memori (cache)

12

Kami telah mengalami pembunuh OOM meskipun hampir setengah dari memori kami digunakan untuk cache FS. Kami telah mencatat statistik memori satu kali per menit (seperti dilaporkan oleh top), tetapi tampaknya ada banyak ketersediaan.

...

Mem:  15339640k total, 15268304k used,    71336k free,     3152k buffers
Swap:        0k total,        0k used,        0k free,  6608384k cached

Mem:  15339640k total, 14855280k used,   484360k free,    13748k buffers
Swap:        0k total,        0k used,        0k free,  6481852k cached

[OOM killer: postgres killed]

Mem:  15339640k total,  8212200k used,  7127440k free,    32776k buffers
Swap:        0k total,        0k used,        0k free,  2394444k cached

...

Rincian OOM dari syslog:

...
Jun 10 05:45:25 db kernel: [11209156.840462] wal-e invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
Jun 10 05:45:25 db kernel: [11209156.840469] wal-e cpuset=/ mems_allowed=0
Jun 10 05:45:25 db kernel: [11209156.840474] Pid: 7963, comm: wal-e Not tainted 3.2.0-43-virtual #68-Ubuntu
Jun 10 05:45:25 db kernel: [11209156.840477] Call Trace:
Jun 10 05:45:25 db kernel: [11209156.840498]  [<ffffffff81119711>] dump_header+0x91/0xe0
Jun 10 05:45:25 db kernel: [11209156.840502]  [<ffffffff81119a95>] oom_kill_process+0x85/0xb0
Jun 10 05:45:25 db kernel: [11209156.840506]  [<ffffffff81119e3a>] out_of_memory+0xfa/0x220
Jun 10 05:45:25 db kernel: [11209156.840511]  [<ffffffff8111f823>] __alloc_pages_nodemask+0x8c3/0x8e0
Jun 10 05:45:25 db kernel: [11209156.840520]  [<ffffffff81216e00>] ? noalloc_get_block_write+0x30/0x30
Jun 10 05:45:25 db kernel: [11209156.840528]  [<ffffffff811566c6>] alloc_pages_current+0xb6/0x120
Jun 10 05:45:25 db kernel: [11209156.840534]  [<ffffffff81116637>] __page_cache_alloc+0xb7/0xd0
Jun 10 05:45:25 db kernel: [11209156.840539]  [<ffffffff81118602>] filemap_fault+0x212/0x3c0
Jun 10 05:45:25 db kernel: [11209156.840553]  [<ffffffff81138c32>] __do_fault+0x72/0x550
Jun 10 05:45:25 db kernel: [11209156.840557]  [<ffffffff8113c2ea>] handle_pte_fault+0xfa/0x200
Jun 10 05:45:25 db kernel: [11209156.840562]  [<ffffffff8100638e>] ? xen_pmd_val+0xe/0x10
Jun 10 05:45:25 db kernel: [11209156.840567]  [<ffffffff81005309>] ? __raw_callee_save_xen_pmd_val+0x11/0x1e
Jun 10 05:45:25 db kernel: [11209156.840571]  [<ffffffff8113d559>] handle_mm_fault+0x269/0x370
Jun 10 05:45:25 db kernel: [11209156.840576]  [<ffffffff8100a56d>] ? xen_force_evtchn_callback+0xd/0x10
Jun 10 05:45:25 db kernel: [11209156.840581]  [<ffffffff8100ad42>] ? check_events+0x12/0x20
Jun 10 05:45:25 db kernel: [11209156.840589]  [<ffffffff8165b3cb>] do_page_fault+0x14b/0x520
Jun 10 05:45:25 db kernel: [11209156.840594]  [<ffffffff81160d64>] ? kmem_cache_free+0x104/0x110
Jun 10 05:45:25 db kernel: [11209156.840600]  [<ffffffff811ba2c8>] ? ep_remove+0xa8/0xc0
Jun 10 05:45:25 db kernel: [11209156.840604]  [<ffffffff811bb133>] ? sys_epoll_ctl+0xb3/0x3d0
Jun 10 05:45:25 db kernel: [11209156.840614]  [<ffffffff81658035>] page_fault+0x25/0x30
Jun 10 05:45:25 db kernel: [11209156.840617] Mem-Info:
Jun 10 05:45:25 db kernel: [11209156.840618] Node 0 DMA per-cpu:
Jun 10 05:45:25 db kernel: [11209156.840622] CPU    0: hi:    0, btch:   1 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840624] CPU    1: hi:    0, btch:   1 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840627] CPU    2: hi:    0, btch:   1 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840629] CPU    3: hi:    0, btch:   1 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840631] Node 0 DMA32 per-cpu:
Jun 10 05:45:25 db kernel: [11209156.840634] CPU    0: hi:  186, btch:  31 usd:  30
Jun 10 05:45:25 db kernel: [11209156.840637] CPU    1: hi:  186, btch:  31 usd:  47
Jun 10 05:45:25 db kernel: [11209156.840639] CPU    2: hi:  186, btch:  31 usd:  15
Jun 10 05:45:25 db kernel: [11209156.840641] CPU    3: hi:  186, btch:  31 usd:   2
Jun 10 05:45:25 db kernel: [11209156.840643] Node 0 Normal per-cpu:
Jun 10 05:45:25 db kernel: [11209156.840646] CPU    0: hi:  186, btch:  31 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840648] CPU    1: hi:  186, btch:  31 usd:  14
Jun 10 05:45:25 db kernel: [11209156.840650] CPU    2: hi:  186, btch:  31 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840653] CPU    3: hi:  186, btch:  31 usd:   1
Jun 10 05:45:25 db kernel: [11209156.840658] active_anon:3616567 inactive_anon:4798 isolated_anon:0
Jun 10 05:45:25 db kernel: [11209156.840660]  active_file:98 inactive_file:168 isolated_file:20
Jun 10 05:45:25 db kernel: [11209156.840661]  unevictable:1597 dirty:73 writeback:0 unstable:0
Jun 10 05:45:25 db kernel: [11209156.840662]  free:16921 slab_reclaimable:17631 slab_unreclaimable:7534
Jun 10 05:45:25 db kernel: [11209156.840663]  mapped:1614529 shmem:1613928 pagetables:124012 bounce:0
Jun 10 05:45:25 db kernel: [11209156.840666] Node 0 DMA free:7888kB min:4kB low:4kB high:4kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:7632kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:0kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes
Jun 10 05:45:25 db kernel: [11209156.840681] lowmem_reserve[]: 0 4016 15112 15112
Jun 10 05:45:25 db kernel: [11209156.840686] Node 0 DMA32 free:48368kB min:4176kB low:5220kB high:6264kB active_anon:3776804kB inactive_anon:28kB active_file:0kB inactive_file:20kB unevictable:932kB isolated(anon):0kB isolated(file):0kB present:4112640kB mlocked:932kB dirty:0kB writeback:0kB mapped:1458536kB shmem:1458632kB slab_reclaimable:17604kB slab_unreclaimable:8088kB kernel_stack:1872kB pagetables:190616kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:437 all_unreclaimable? yes
Jun 10 05:45:25 db kernel: [11209156.840698] lowmem_reserve[]: 0 0 11095 11095
Jun 10 05:45:25 db kernel: [11209156.840703] Node 0 Normal free:11428kB min:11548kB low:14432kB high:17320kB active_anon:10689464kB inactive_anon:19164kB active_file:528kB inactive_file:652kB unevictable:5456kB isolated(anon):0kB isolated(file):80kB present:11362176kB mlocked:5456kB dirty:292kB writeback:0kB mapped:4999580kB shmem:4997080kB slab_reclaimable:52920kB slab_unreclaimable:22048kB kernel_stack:2584kB pagetables:305432kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:1974 all_unreclaimable? yes
Jun 10 05:45:25 db kernel: [11209156.840715] lowmem_reserve[]: 0 0 0 0
Jun 10 05:45:25 db kernel: [11209156.840720] Node 0 DMA: 2*4kB 3*8kB 1*16kB 3*32kB 3*64kB 3*128kB 2*256kB 1*512kB 2*1024kB 2*2048kB 0*4096kB = 7888kB
Jun 10 05:45:25 db kernel: [11209156.840752] Node 0 DMA32: 5813*4kB 2636*8kB 114*16kB 15*32kB 5*64kB 1*128kB 1*256kB 0*512kB 1*1024kB 0*2048kB 0*4096kB = 48372kB
Jun 10 05:45:25 db kernel: [11209156.840776] Node 0 Normal: 1888*4kB 10*8kB 46*16kB 4*32kB 3*64kB 2*128kB 1*256kB 1*512kB 0*1024kB 1*2048kB 0*4096kB = 11760kB
Jun 10 05:45:25 db kernel: [11209156.840788] 1615243 total pagecache pages
Jun 10 05:45:25 db kernel: [11209156.840790] 0 pages in swap cache
Jun 10 05:45:25 db kernel: [11209156.840801] Swap cache stats: add 0, delete 0, find 0/0
Jun 10 05:45:25 db kernel: [11209156.840803] Free swap  = 0kB
Jun 10 05:45:25 db kernel: [11209156.840805] Total swap = 0kB
Jun 10 05:45:25 db kernel: [11209156.909794] 3934192 pages RAM
Jun 10 05:45:25 db kernel: [11209156.909804] 99282 pages reserved
Jun 10 05:45:25 db kernel: [11209156.909809] 18899146 pages shared
Jun 10 05:45:25 db kernel: [11209156.909811] 2198511 pages non-shared
Jun 10 05:45:25 db kernel: [11209156.909817] [ pid ]   uid  tgid total_vm      rss cpu oom_adj oom_score_adj name
Jun 10 05:45:25 db kernel: [11209156.909835] [  332]     0   332     4308      109   1       0             0 upstart-udev-br
Jun 10 05:45:25 db kernel: [11209156.909845] [  346]     0   346     5384      271   2     -17         -1000 udevd
Jun 10 05:45:25 db kernel: [11209156.909851] [  408]     0   408     5364      174   2     -17         -1000 udevd
...
Jun 10 05:45:25 db kernel: [11209156.910703] [ 7963]   111  7963    17456     2966   0       0             0 wal-e
Jun 10 05:45:25 db kernel: [11209156.910707] [ 7968]   111  7968  1639372     2351   3       0             0 postgres
Jun 10 05:45:25 db kernel: [11209156.910711] [ 7969]   111  7969  1639371     1934   2       0             0 postgres
Jun 10 05:45:25 db kernel: [11209156.910716] Out of memory: Kill process 12443 (postgres) score 418 or sacrifice child
Jun 10 05:45:25 db kernel: [11209156.910733] Killed process 12443 (postgres) total-vm:6555152kB, anon-rss:4600kB, file-rss:6396572kB
Jun 10 05:45:30 db kernel: [11209159.293083] postgres invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
Jun 10 05:45:31 db kernel: [11209159.293091] postgres cpuset=/ mems_allowed=0
Jun 10 05:45:31 db kernel: [11209159.293095] Pid: 6508, comm: postgres Not tainted 3.2.0-43-virtual #68-Ubuntu
Jun 10 05:45:31 db kernel: [11209159.293098] Call Trace:
Jun 10 05:45:31 db kernel: [11209159.293111]  [<ffffffff81119711>] dump_header+0x91/0xe0
Jun 10 05:45:31 db kernel: [11209159.293115]  [<ffffffff81119a95>] oom_kill_process+0x85/0xb0
Jun 10 05:45:31 db kernel: [11209159.293119]  [<ffffffff81119e3a>] out_of_memory+0xfa/0x220
...

Kita dapat mencoba meningkatkan resolusi ini menjadi kira-kira sekali per detik, tetapi apakah akan ada alasan untuk OOM di sini? (Kami telah melihat http://bl0rg.krunch.be/oom-frag.html tetapi kami bekerja dengan jumlah absolut yang jauh lebih besar, yang sebagian besar diambil oleh cache FS kernel.)

Juga termasuk bagian yang relevan dari kami di postgresql.confbawah ini:

shared_buffers = 6GB
effective_cache_size = 8GB
Yang
sumber
Um ... 3.2.0-43? Perbarui waktu. Pembunuh OOM telah melalui banyak (terlalu banyak) perubahan dari waktu ke waktu. Beberapa versi benar-benar sangat bodoh tentang akuntansi untuk penggunaan memori bersama ... seperti PostgreSQL 9.2 dan yang lebih lama shared_buffers.
Craig Ringer
@CraigRinger Sayangnya ada pertimbangan lain termasuk tetap menggunakan kernel di distro Ubuntu 12.04 untuk LTS, kompatibilitas, pembaruan keamanan, dll. Kami hanya tertarik jika seseorang tahu bagaimana menjelaskan apa yang terjadi di sini - jika itu membantu, berpura-pura kami tidak tertarik mengubah status quo / membuat masalah hilang. BTW shared_buffersmasih dalam PG9.3.
Yang
Ya shared_buffersmasih dalam 9,3, tapi itu tidak lagi memori bersama POSIX dalam 9,3. Itu telah diganti dengan mmap()edwilayah anonim . Itu mengatasi beberapa masalah konfigurasi kernel icky dan menyematkan masalah, meskipun saya ragu itu akan membuat pembunuh OOM menjadi kurang bingung.
Craig Ringer
1
Kemungkinan merupakan duplikat dari serverfault.com/questions/288319/… , yang memiliki jawaban potensial.
richvdh

Jawaban:

4

Tampaknya Anda (dan saya dalam kasus dengan gejala yang sangat mirip) benar-benar kehabisan memori dan telah bingung dengan cachedjumlahnya.

Rupanya ada kasus di mana Linux tidak membebaskan cache disk besar ketika permintaan memori naik

Khususnya (saya tidak benar-benar mengerti mengapa), postgres ' shared_buffersdapat dilaporkan di bawah "Cached" (halaman cache). Dalam kasus Anda, 6481852k cachedin topcocok dengan baris ini dalam log pembunuh-OOM:

Jun 10 05:45:25 db kernel: [11209156.840788] 1615243 total pagecache pages

(1615243 * 4KB ~ = 6481852k) - artinya cache halaman memang tidak dijatuhkan sebelum memanggil pembunuh-OOM.

Namun ada beberapa halaman yang didukung file (saya anggap active_file:98 inactive_file:168mirip dengan / proc / meminfo's Active (file) / Inactive (file) ), jadi itu bukan halaman yang bisa dibuang yang kita kenal dan sukai.

Posting di https://www.depesz.com/2012/06/09/how-much-ram-is-postgresql-using/ menunjukkan contoh sesi di mana mematikan postgres mengarah pada pengurangan "cached" dengan ukuran shared_buffers(gulir ke "Dan sebagian besar berasal dari cache disk - seperti yang diharapkan, karena itu digunakan untuk shared_buffers." ) - sayangnya itu tidak menunjukkan versi postgres atau kernel yang digunakan untuk percobaan.

Saya menggunakan 3.13.0-67 x86_64 dengan PG 9.3. Di 9.3 mereka beralih dari menggunakan memori bersama Sys V ( shmget) ke anonimmmap(...R+W, MAP_SHARED|MAP_ANONYMOUS|MAP_HASSEMAPHORE...)+fork() (dalam 9.4 ini menjadi dapat dikonfigurasi melalui dynamic_shared_memory_type ). Tapi saya tidak bisa menemukan penjelasan mengapa mmap () ini seharusnya muncul di "cache" dan mengapa, hanya https://access.redhat.com/solutions/406773 yang mengatakan "Cached: Memory in the pagecache (Diskcache dan Memori Bersama) "

Mengingat ada banyak jenis memori bersama, saya berdua tercerahkan dan bingung ...

Nickolay
sumber
Setelah beberapa tahun, ini adalah jawaban yang jauh lebih baik, terima kasih. Masih ada pertanyaan mengapa ini dianggap sebagai cache, tetapi saya menandai ini diterima untuk saat ini.
Yang
8
  1. Demi semua yang baik di dunia, konfigurasikan ruang swap di server Anda .
    Anda benar-benar membutuhkan ruang swap . Saya bukan satu-satunya yang mengatakan demikian , itu cukup banyak kebenaran universal di sekitar sini . (<- Itu adalah tiga tautan)
    Anda tentu saja harus memiliki cukup RAM sehingga server database Anda tidak bertukar secara teratur - jika Anda tidak solusinya adalah uang (yang Anda bawa vendor Anda dan gunakan untuk mendapatkan lebih banyak RAM) .

  2. Karena Anda sekarang memiliki RAM yang memadai, dan bertukar untuk digunakan jika terjadi kesalahan, Anda dapat menonaktifkan pembunuh OOM (dengan menonaktifkan memori terlalu banyak), seperti yang orang Postgres suruh .
    (Anda juga dapat menerapkan solusi alternatif mereka dan memberi tahu OOM-Killer untuk tidak pernah membunuh Postgres - tetapi kemudian Anda hanya memainkan Roulette Rusia dengan seluruh proses sistem Anda ...)

  3. (opsional) Tulis jawaban pada Kesalahan Server yang merinci mengapa perilaku default di sebagian besar distribusi Linux adalah Buruk, Salah, dan melanggar spesifikasi POSIX untuk bagaimana malloc () seharusnya berperilaku . Ulangi sampai semua orang bosan mendengarnya.


Perhatikan juga bahwa memori cache kernel tersedia untuk postgres (atau aplikasi lain) untuk digunakan - Anda harus memperhitungkannya sebagai memori bebas / tersedia dalam perhitungan Anda.

Jika saya harus menebak apa yang terjadi di sini saya akan mengatakan Anda memiliki pertanyaan yang kompleks, Postgres meminta RAM untuk mengeksekusinya, dan daripada mengatakan "Saya tidak memiliki RAM", Linux memberi tahu Postgres "Tentu, Kau bisa memilikinya."
Kemudian ketika Postgres benar-benar mencoba menggunakan RAM itu (diduga) diberikan Linux menyadari itu tidak MEMILIKI RAM yang dijanjikan Postgres (karena itu overcommitted) - pembunuh OOM diminta untuk membebaskan RAM, dan dengan patuh membunuh program menggunakan memori terbanyak - server basis data Anda.

Postgres adalah program yang dirancang dengan baik. Jika diberi tahu itu tidak dapat memiliki RAM itu meminta itu akan menangani itu dengan anggun (baik dengan melakukan lebih sedikit, atau membatalkan dengan pesan kepada pengguna).

voretaq7
sumber
4
Terima kasih atas elaborasi swap, tetapi ini tidak menjawab pertanyaan saya mengapa ini terjadi . Ya, saya mengerti premis dasar bahwa Linux overcommits secara default dan bahwa OOM adalah ketika kita kehabisan RAM - saya bisa menyatakan hal ini dalam pertanyaan awal saya. Tetapi pertanyaannya adalah mengapa itu menendang ketika saya masih memiliki banyak RAM (kebanyakan hanya duduk di cache FS)? Asumsikan saya bahkan tidak tertarik untuk mengubah apa pun - bahwa pembunuh OOM baik-baik saja, selama saya mengerti mengapa itu dipicu.
Yang
2
Setelah meninjau tautan, sayangnya ada sejumlah pernyataan tanpa mendukung bukti atau penjelasan teknis yang konkret. Tentu saja ada banyak lingkungan Linux di mana swap bahkan bukan opsi (contoh: tidak terlihat lagi dari Live CD di mana belum ada partisi swap lokal yang ada untuk digunakan kembali). Kami juga tidak tertarik untuk mengaktifkan swappiness berdasarkan pengalaman dan lingkungan kami sendiri - kami lebih suka memiliki OOM. Jawaban atas pertanyaan awal akan dihargai.
Yang
1
@Yang saya berasumsi bahwa jika Anda sedang membangun server untuk Postgres Anda ingin mengikuti rekomendasi proyek Postgres. Jawaban saya adalah melakukan apa yang mereka katakan (matikan pembunuh OOM). Jika Anda ingin menunggu dan melihat apakah seseorang menawarkan jawaban yang berbeda, Anda tentu bebas melakukannya, tetapi saya tidak nyaman menawarkan solusi lain - Menurut saya pembunuh OOM itu Buruk, Salah, dan melanggar POSIX. Mungkin dapat diterima di desktop / terburuk, tetapi menonaktifkannya di server adalah, IMO, Hal yang Benar untuk Dilakukan.
voretaq7
2
Saya telah menjalankan situasi ini pada server yang memang memiliki swap, dan setelah menjenuhkan memori yang tersedia + swap pembunuh OOM digunakan alih-alih kernel reclaiming "cache" memori, yang jelas entah bagaimana terkunci. Saya tidak pernah menyelesaikan masalah ini, tetapi pertanyaan awal @ Yang tidak dijawab di sini.
Patrick
2
Swap bukan jawabannya, itu hanya membuat masalah muncul nanti. Anda perlu swap ketika RAM penuh dan Anda membutuhkan OOM Killer ketika RAM + swap penuh. Jika jumlah swap adalah nol, Anda perlu OOM Killer lebih cepat tetapi Anda tidak dapat menghindari OOM Killer dengan swap.
Mikko Rantalainen