
Kapag nasa Linux сервер базы данных непредвиденно завершает работу, нужно найти причину. Причин может быть несколько. Например, SIGSEGV — pagkabigo dahil sa isang bug sa backend server. Ngunit ito ay bihira. Kadalasan, nauubusan ka lang ng puwang sa disk o memorya. Kung naubusan ka ng puwang sa disk, mayroon lamang isang paraan palabas - magbakante ng espasyo at i-restart ang database.
Out-Of-Memory Killer
Kapag ikaw server или процесса заканчивается память, Linux предлагает 2 пути решения: обрушить всю систему или завершить процесс (приложение), который съедает память. Лучше, конечно, завершить процесс и спасти ОС от аварийного завершения. В двух словах, Out-Of-Memory Killer — это процесс, который завершает приложение, чтобы спасти ядро от сбоя. Он жертвует приложением, чтобы сохранить работу ОС. Давайте сначала обсудим, как работает OOM и как его контролировать, а потом посмотрим, как OOM Killer решает, какое приложение завершить.
Одна из главных задач Linux — выделять память процессам, когда они ее просят. Обычно процесс или приложение запрашивают у ОС память, а сами используют ее не полностью. Если ОС будет выдавать память всем, кто ее просит, но не планирует использовать, очень скоро память закончится, и система откажет. Чтобы этого избежать, ОС резервирует память за процессом, но фактически не выдает ее. Память выделяется, только когда процесс действительно собирается ее использовать. Случается, что у ОС нет свободной памяти, но она закрепляет память за процессом, и когда процессу она нужна, ОС выделяет ее, если может. Минус в том, что иногда ОС резервирует память, но в нужный момент свободной памяти нет, и происходит сбой системы. OOM играет важную роль в этом сценарии и завершает процессы, чтобы уберечь ядро от паники. Когда принудительно завершается процесс PostgreSQL, в логе появляется сообщение:
Out of Memory: Killed process 12345 (postgres).Kung ang system ay mababa sa memorya at hindi ito mapalaya, ang function ay tinatawag out_of_memory. Sa yugtong ito, isa na lang ang kailangan niyang gawin - kumpletuhin ang isa o higit pang mga proseso. Dapat bang tapusin kaagad ng OOM-killer ang proseso o maaari ba itong maghintay? Malinaw, kapag out_of_memory ay tinawag, ito ay dahil sa paghihintay para sa isang I/O operation o paging sa disk. Samakatuwid, ang OOM killer ay dapat munang magsagawa ng mga pagsusuri at, batay sa mga ito, magpasya na ang proseso ay kailangang wakasan. Kung positibo ang lahat ng pagsusuri sa ibaba, wawakasan ng OOM ang proseso.
Pagpili ng proseso
Kapag naubos ang memorya, tinatawag ang function out_of_memory(). May function ito select_bad_process(), na tumatanggap ng pagsusuri mula sa function badness(). Ang "pinakamasama" na proseso ay ita-target. Function badness() pumipili ng isang proseso ayon sa ilang mga patakaran.
- Ang kernel ay nangangailangan ng ilang minimum na memorya para sa sarili nito.
- Kailangan mong magbakante ng maraming memorya.
- Hindi na kailangang wakasan ang mga proseso na gumagamit ng maliit na memorya.
- Kailangang makumpleto ang pinakamababang proseso.
- Mga kumplikadong algorithm na nagpapataas ng mga pagkakataong makumpleto para sa mga prosesong iyon na mismong gumagamit ang gustong kumpletuhin.
Matapos makumpleto ang lahat ng mga pagsusuring ito, sinusuri ng OOM ang marka (oom_score). Nagtatalaga ang OOM oom_score bawat proseso, at pagkatapos ay i-multiply ang halagang ito sa dami ng memorya. Ang mga prosesong may mas malalaking halaga ay mas malamang na maging biktima ng OOM Killer. Ang mga prosesong nauugnay sa root user ay may mas mababang marka at mas malamang na mapipilitang wakasan.
postgres=# SELECT pg_backend_pid();
pg_backend_pid
----------------
3813
(1 row)Ang Postgres process ID ay 3813, kaya sa isa pang shell posibleng makuha ang score gamit ang kernel parameter na ito oom_score:
vagrant@vagrant:~$ sudo cat /proc/3813/oom_score
2Kung hindi mo nais na patayin ng OOM-Killer ang proseso, mayroong isa pang pagpipilian sa kernel: oom_score_adj. Magdagdag ng malaking negatibong halaga upang mabawasan ang mga pagkakataong makumpleto ang isang proseso na iyong pinahahalagahan.
sudo echo -100 > /proc/3813/oom_score_adjUpang magtakda ng halaga oom_score_adj, itakda ang OOMScoreAdjust sa block ng serbisyo:
[Service]
OOMScoreAdjust=-1000O gamitin oomprotect sa isang team rcctl.
rcctl set <i>servicename</i> oomprotect -1000Sapilitang pagwawakas ng isang proseso
Kapag napili na ang isa o higit pang mga proseso, tatawagin ng OOM-Killer ang function oom_kill_task(). Ang function na ito ay nagpapadala ng signal ng pagwawakas sa proseso. Sa kaso ng kakulangan ng memorya oom_kill() Tinatawagan ang function na ito upang magpadala ng signal ng SIGKILL sa proseso. Ang isang mensahe ay nakasulat sa kernel log.
Out of Memory: Killed process [pid] [name].Paano kontrolin ang OOM-Killer
В Linux можно включать и отключать OOM-Killer (хотя последнее не рекомендуется). Для включения и отключения используйте параметр vm.oom-kill. Upang paganahin ang OOM-Killer sa runtime, patakbuhin ang command sysctl.
sudo -s sysctl -w vm.oom-kill = 1Upang hindi paganahin ang OOM-Killer, tukuyin ang value 0 sa parehong command:
sudo -s sysctl -w vm.oom-kill = 0Ang resulta ng utos na ito ay hindi mai-save magpakailanman, ngunit hanggang sa unang pag-reboot lamang. Kung kailangan mo ng higit pang pagtitiyaga, idagdag ang linyang ito sa file /etc/sysctl.conf:
echo vm.oom-kill = 1 >>/etc/sysctl.confAng isa pang paraan upang paganahin at huwag paganahin ay ang pagsulat ng isang variable panic_on_oom. Maaaring palaging naka-check in ang halaga /proc.
$ cat /proc/sys/vm/panic_on_oom
0Kung itinakda mo ang halaga sa 0, pagkatapos ay kapag naubos ang memorya, walang kernel panic.
$ echo 0 > /proc/sys/vm/panic_on_oomKung itinakda mo ang halaga sa 1, pagkatapos ay kapag naubos ang memorya, isang kernel panic ang magaganap.
echo 1 > /proc/sys/vm/panic_on_oomOOM-Killer можно не только включать и выключать. Мы уже говорили, что Linux может зарезервировать для процессов больше памяти, чем есть, но не выделять ее по факту, и этим поведением управляет параметр ядра Linux. За это отвечает переменная vm.overcommit_memory.
Maaari mong tukuyin ang mga sumusunod na halaga para dito:
0: ядро само решает, стоит ли резервировать слишком много памяти. Это значение по умолчанию в большинстве версий Linux.
1: Ang kernel ay palaging magrereserba ng dagdag na memorya. Ito ay mapanganib, dahil ang memorya ay maaaring maubusan, dahil, malamang, isang araw ay kakailanganin ito ng mga proseso.
2: ang kernel ay hindi magrereserba ng mas maraming memorya kaysa sa tinukoy sa parameter overcommit_ratio.
Sa parameter na ito, tinukoy mo ang porsyento ng memorya na pinapayagang ma-over-reserve. Kung walang puwang para dito, walang memorya na inilalaan, at ang reserbasyon ay tatanggihan. Ito ang pinakaligtas na opsyon na inirerekomenda para sa PostgreSQL. Ang OOM-Killer ay apektado ng isa pang elemento - ang kakayahan sa pagpapalit, na kinokontrol ng variable cat /proc/sys/vm/swappiness. Ang mga halagang ito ay nagsasabi sa kernel kung paano pangasiwaan ang paging. Kung mas mataas ang halaga, mas maliit ang posibilidad na wakasan ng OOM ang proseso, ngunit dahil sa mga operasyon ng I/O, mayroon itong negatibong epekto sa database. At kabaliktaran - mas mababa ang halaga, mas mataas ang posibilidad ng interbensyon ng OOM-Killer, ngunit mas mataas din ang pagganap ng database. Ang default na halaga ay 60, ngunit kung ang buong database ay umaangkop sa memorya, mas mahusay na itakda ang halaga sa 1.
Mga resulta ng
Huwag hayaang takutin ka ng "killer" sa OOM-Killer. Sa kasong ito, ang mamamatay ay ang tagapagligtas ng iyong sistema. "Pinapatay" nito ang pinakamasamang proseso at inililigtas ang system mula sa pag-crash. Para maiwasan ang paggamit ng OOM-Killer para wakasan ang PostgreSQL, itakda sa vm.overcommit_memory value 2. Hindi nito ginagarantiya na hindi na kailangang makialam ang OOM-Killer, ngunit babawasan nito ang posibilidad na pilitin ang proseso ng PostgreSQL na wakasan.
Pinagmulan: www.habr.com
