OOM несмотря на доступную память (кеш)

12

Мы столкнулись с убийцей OOM, несмотря на то, что почти половина нашей памяти была использована для кэша FS. Мы регистрировали статистику памяти один раз в минуту (как сообщалось сверху), но, похоже, их было много.

...

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

...

Детали OOM из системного журнала:

...
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
...

Мы можем попытаться увеличить разрешение примерно до одного раза в секунду, но будет ли здесь какая-то причина для OOM? (Мы видели http://bl0rg.krunch.be/oom-frag.html, но мы работаем с гораздо большими абсолютными объемами памяти, большая часть которой занята кэшем FS ядра.)

Также включая соответствующие части нашего postgresql.confниже:

shared_buffers = 6GB
effective_cache_size = 8GB
Ян
источник
Хм ... 3.2.0-43? Время обновления. Убийца OOM претерпел много (слишком много) изменений с течением времени. Некоторые версии были совершенно безрассудны в отношении учета использования общей памяти ... как PostgreSQL 9.2 и более ранние версии shared_buffers.
Крейг Рингер
@CraigRinger К сожалению, есть и другие соображения, в том числе работа с ядром в дистрибутиве Ubuntu 12.04 для LTS, совместимость, обновления безопасности и т. Д. Нам просто интересно, если кто-то знает, как объяснить, что здесь происходит - если это поможет, притвориться, что мы не заинтересованы в изменении статус-кво / устранении проблемы. Кстати shared_buffers, все еще в PG9.3.
Ян
Да shared_buffersвсе еще в 9.3, но больше не POSIX разделяемая память в 9.3. Это было заменено анонимным mmap()edрегионом. Это позволяет обойти некоторые проблемы с конфигурацией ядра и проблемы с закреплением, хотя я сомневаюсь, что убийца OOM станет менее запутанным.
Крейг Рингер,
1
Возможно, дубликат serverfault.com/questions/288319/… , который может дать ответ.
richvdh

Ответы:

4

Похоже, у вас (и у меня в случае с очень похожими симптомами) действительно закончилась память, и число было смущено cached.

По-видимому, бывают случаи, когда Linux не освобождает большой дисковый кеш при увеличении спроса на память.

В частности (я не очень понимаю, почему), postgres ' shared_buffersможет сообщаться в разделе "Cached" (кеш страниц). В вашем случае 6481852k cachedin topсоответствует этой строке в журнале OOM-killer:

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

(1615243 * 4KB ~ = 6481852k) - это означает, что кеш страниц действительно не был удален до вызова OOM-killer.

Тем не менее, есть немного страниц с файловой поддержкой (я полагаю, что active_file:98 inactive_file:168это похоже на / proc / meminfo Active (файл) / Inactive (файл) ), так что это не те страницы, которые мы знаем и любим.

Пост по адресу https://www.depesz.com/2012/06/09/how-much-ram-is-postgresql-using/ демонстрирует пример сеанса, в котором завершение работы postgres приводит к уменьшению «кэшированного» на размер shared_buffers(прокрутите до пункта «И большая часть из этого вышла из дискового кэша - как и ожидалось, потому что он использовался для shared_buffers.» ) - к сожалению, он не указывает ни версию postgres, ни ядро, которое использовалось для эксперимента.

Я использую 3.13.0-67 x86_64 с PG 9.3. В 9.3 они переключились с использования разделяемой памяти Sys V ( shmget) на анонимнуюmmap(...R+W, MAP_SHARED|MAP_ANONYMOUS|MAP_HASSEMAPHORE...)+fork() (в 9.4 это стало настраиваться с помощью dynamic_shared_memory_type ). Но я не смог найти никаких объяснений относительно того, почему эти mmap () должны отображаться в «кэшированном» и почему только https://access.redhat.com/solutions/406773 с надписью «Кэшированный: память в pagecache (Diskcache и Shared Memory) "

Учитывая, что существует много видов общей памяти, я и просвещен, и сбит с толку ...

Nickolay
источник
Спустя несколько лет, это гораздо лучший ответ, спасибо. До сих пор остается вопрос, почему это считается кэшированным, но я отмечаю это как принятое.
Ян
8
  1. Ради всего хорошего в мире настройте пространство подкачки на своих серверах .
    Вам действительно нужно пространство подкачки . Я не единственный, кто так говорит , это в значительной степени универсальная правда здесь . (<- это три ссылки).
    Конечно, у вас должно быть достаточно ОЗУ, чтобы ваш сервер баз данных не менялся регулярно - если вы этого не сделаете, то деньги - это деньги (которые вы забираете у своего поставщика и используете для приобретения большего объема ОЗУ) ,

  2. Так как теперь у вас есть достаточное количество ОЗУ и возможность замены, если что-то пойдет не так, вы можете отключить OOM killer (отключив чрезмерную загрузку памяти), как вам говорят сотрудники Postgres .
    (Вы также можете применить их альтернативное решение и сказать OOM-Killer никогда не убивать Postgres - но тогда вы просто играете в русскую рулетку с остальными процессами вашей системы ...)

  3. (необязательно) Напишите ответ о сбое сервера, в котором подробно описано, почему поведение по умолчанию в большинстве дистрибутивов Linux является плохим, неправильным и нарушает спецификацию POSIX о том, как malloc () должна себя вести . Повторяйте это, пока всем не надоест слышать об этом.


Также обратите внимание, что кэшированная память ядра доступна для использования postgres (или любым другим приложением) - вы должны учитывать это как свободную / доступную память в своих вычислениях.

Если бы мне пришлось рисковать предположением о том, что здесь происходит, я бы сказал, что у вас сложный запрос, Postgres запрашивает ОЗУ для его выполнения и вместо того, чтобы сказать «У меня нет этой ОЗУ», Linux сообщает Postgres «Конечно ты можешь иметь это."
Тогда , когда Postgres на самом деле пытается использовать оперативную память это было (предположительно) данный Linux понимает , что это не ИМЕТЬ оперативную память он обещал Postgres (потому что она перегружена) - ОЫЙ убийца сказал , чтобы освободить оперативную память, и послушно убивает программу , используя больше всего памяти - ваш сервер базы данных.

Postgres - это хорошо продуманная программа. Если ему говорят, что он не может иметь ОЗУ, он запрашивает, он будет обрабатывать это изящно (либо обходясь безрезультатно, либо прерывая работу с сообщением пользователю).

voretaq7
источник
4
Спасибо за разработку свопа, но это не отвечает на мой вопрос, почему это происходит в первую очередь . Да, я понимаю основную предпосылку, что Linux по умолчанию перегружается и что OOM - это когда у нас не хватает ОЗУ - я мог бы сказать об этом много в своем первоначальном вопросе. Но вопрос в том, почему он включается, когда у меня все еще есть много оперативной памяти (большая ее часть просто находится в кэше FS)? Предположим, что я даже не заинтересован в том, чтобы что-то менять - что убийца OOM в порядке, пока я понимаю, почему он запускается.
Ян
2
После просмотра ссылок, к сожалению, есть ряд утверждений без подкрепления доказательствами или конкретными техническими объяснениями. Конечно, существует много сред Linux, где подкачка даже не вариант (пример: посмотрите не на Live CD, где еще нет локального раздела подкачки для повторного использования). Кроме того, мы не заинтересованы в том, чтобы обеспечить обмен, основанный на нашем собственном опыте и окружающей среде - мы бы предпочли иметь OOM. Ответ на оригинальный вопрос будет принята с благодарностью.
Ян
1
@Yang Я предполагаю, что если вы создаете сервер для Postgres, вы бы хотели следовать рекомендациям проекта Postgres. Мой ответ: делай то, что тебе говорят (отключи убийцу ООМ). Если вы хотите подождать и посмотреть, предложит ли кто-то другой ответ, вы, безусловно, можете это сделать, но мне не удобно предлагать какое-либо другое решение. По моему мнению, убийца OOM - Плохой, Неправильный и нарушающий POSIX. Это может быть приемлемо для настольного компьютера или камвольной станции, но отключение его на серверах - это, IMO, то, что нужно сделать.
voretaq7
2
Я столкнулся с этой ситуацией на сервере, на котором действительно есть своп, и после насыщения доступной памяти + свопа вместо ядра, возвращающего «кешированную» память, использовался киллер OOM, который, очевидно, был как-то заблокирован. Я никогда не решал проблему, но оригинальный вопрос @ Ян не ответил здесь.
Патрик
2
Обмен не является ответом, он только заставляет проблему появляться позже. Вам нужно поменяться, когда ОЗУ заполнено, и вам нужен OOM Killer, когда ОЗУ + своп заполнится. Если сумма свопа равна нулю, вам нужен OOM Killer раньше, но вы не можете избежать OOM Killer с помощью свопа.
Микко Ранталайнен