Pag-set up ng Out-Of-Memory Killer sa Linux para sa PostgreSQL

Pag-set up ng Out-Of-Memory Killer sa Linux para sa PostgreSQL

Kapag ang isang database server ay huminto nang hindi inaasahan sa Linux, kailangan mong hanapin ang dahilan. Maaaring may ilang dahilan. Halimbawa, 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 naubusan ng memory ang isang server o proseso, nag-aalok ang Linux ng 2 solusyon: i-crash ang buong system o wakasan ang proseso (application) na kumakain ng memorya. Ito ay mas mahusay, siyempre, upang wakasan ang proseso at i-save ang OS mula sa pag-crash. Sa madaling sabi, ang Out-Of-Memory Killer ay isang proseso na pumapatay ng isang application upang i-save ang kernel mula sa pag-crash. Sinasakripisyo nito ang application para mapanatiling tumatakbo ang OS. Talakayin muna natin kung paano gumagana ang OOM at kung paano ito kontrolin, at pagkatapos ay tingnan kung paano nagpapasya ang OOM Killer kung aling aplikasyon ang wawakasan.

Ang isa sa mga pangunahing gawain ng Linux ay ang paglalaan ng memorya sa mga proseso kapag hiniling nila ito. Karaniwan, ang isang proseso o application ay humihiling ng memorya mula sa OS, ngunit hindi ito ganap na ginagamit. Kung ang OS ay nagbibigay ng memorya sa lahat ng humihingi nito ngunit walang planong gamitin ito, sa lalong madaling panahon ay maubusan ang memorya at ang sistema ay mabibigo. Upang maiwasan ito, inilalaan ng OS ang memorya para sa proseso, ngunit hindi ito aktwal na ilalabas. Ang memorya ay inilalaan lamang kapag ang isang proseso ay aktwal na gagamitin ito. Ito ay nangyayari na ang OS ay walang libreng memorya, ngunit ito ay nagtatalaga ng memorya sa isang proseso, at kapag ang isang proseso ay nangangailangan nito, ang OS ay inilalaan ito kung maaari. Ang downside ay kung minsan ang OS ay naglalaan ng memorya, ngunit sa tamang oras ay walang libreng memorya, at ang system ay nag-crash. Ang OOM ay gumaganap ng isang mahalagang papel sa sitwasyong ito at tinatapos ang mga proseso upang maiwasan ang pag-panic ng kernel. Kapag ang isang proseso ng PostgreSQL ay pinilit na wakasan, isang mensahe ang lalabas sa log:

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.

  1. Ang kernel ay nangangailangan ng ilang minimum na memorya para sa sarili nito.
  2. Kailangan mong magbakante ng maraming memorya.
  3. Hindi na kailangang wakasan ang mga proseso na gumagamit ng maliit na memorya.
  4. Kailangang makumpleto ang pinakamababang proseso.
  5. 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
2

Kung 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_adj

Upang magtakda ng halaga oom_score_adj, itakda ang OOMScoreAdjust sa block ng serbisyo:

[Service]
OOMScoreAdjust=-1000

O gamitin oomprotect sa isang team rcctl.

rcctl set <i>servicename</i> oomprotect -1000

Sapilitang 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

Sa Linux, maaari mong paganahin o huwag paganahin ang OOM-Killer (bagaman ang huli ay hindi inirerekomenda). Upang paganahin o huwag paganahin gamitin ang parameter vm.oom-kill. Upang paganahin ang OOM-Killer sa runtime, patakbuhin ang command sysctl.

sudo -s sysctl -w vm.oom-kill = 1

Upang hindi paganahin ang OOM-Killer, tukuyin ang value 0 sa parehong command:

sudo -s sysctl -w vm.oom-kill = 0

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

Ang 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
0

Kung itinakda mo ang halaga sa 0, pagkatapos ay kapag naubos ang memorya, walang kernel panic.

$ echo 0 > /proc/sys/vm/panic_on_oom

Kung itinakda mo ang halaga sa 1, pagkatapos ay kapag naubos ang memorya, isang kernel panic ang magaganap.

echo 1 > /proc/sys/vm/panic_on_oom

Ang OOM-Killer ay hindi lamang maaaring i-on at i-off. Nasabi na namin na ang Linux ay maaaring magreserba ng mas maraming memorya para sa mga proseso kaysa sa magagamit nang hindi aktwal na inilalaan ito, at ang gawi na ito ay kinokontrol ng isang parameter ng kernel ng Linux. Ang variable ay responsable para dito vm.overcommit_memory.

Maaari mong tukuyin ang mga sumusunod na halaga para dito:

0: Ang kernel mismo ang nagpapasya kung magreserba ng masyadong maraming memorya. Ito ang default sa karamihan ng mga bersyon ng 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

Magdagdag ng komento