Поставување на Out-Of-Memory Killer во Linux за PostgreSQL

Поставување на Out-Of-Memory Killer во Linux за PostgreSQL

Кога во Linux Серверот на базата на податоци неочекувано се исклучува и причината треба да се утврди. Може да има неколку причини. На пример, СИГСЕГВ — неуспех поради грешка во заднинскиот сервер. Но, ова е ретко. Најчесто, едноставно останувате без простор на дискот или меморија. Ако ви снема простор на дискот, има само еден излез - ослободи простор и рестартирајте ја базата на податоци.

Убиец без меморија

Кога ти сервер или процесот снемува меморија, Linux „Out-Of-Memory Killer“ нуди две решенија: да се сруши целиот систем или да се прекине процесот (апликацијата) што ја троши меморијата. Подобро е, се разбира, да се прекине процесот и да се спаси оперативниот систем од пад. Накратко, „Out-Of-Memory Killer“ е процес што ја прекинува апликацијата за да го спаси јадрото од пад. Ја жртвува апликацијата за да го одржи оперативниот систем во функција. Прво да разговараме за тоа како функционира OOM и како да се контролира, а потоа да видиме како OOM Killer одлучува кои апликации да ги прекине.

Една од главните задачи Linux — Доделување меморија на процеси кога тие ќе ја побараат. Типично, процес или апликација бара меморија од оперативниот систем, но не ја користи целосно. Ако оперативниот систем додели меморија на секој што ја бара, но не планира да ја користи, системот брзо ќе остане без меморија и системот ќе се сруши. За да се спречи ова, оперативниот систем резервира меморија за процес, но всушност не ја доделува. Меморијата се доделува само кога процесот всушност има намера да ја користи. Понекогаш оперативниот систем нема слободна меморија, но доделува меморија на процес, и кога на процесот му е потребна, оперативниот систем ја доделува ако може. Недостатокот е што понекогаш оперативниот систем резервира меморија, но кога е потребна, нема слободна меморија, што предизвикува пад на системот. OOM игра клучна улога во ова сценарио, прекинувајќи ги процесите за да се спречи паниката на јадрото. Кога процесот PostgreSQL е насилно прекинат, во дневникот се појавува следната порака:

Out of Memory: Killed process 12345 (postgres).

Ако меморијата на системот е слаба и не може да се ослободи, се повикува функцијата out_of_memory. Во оваа фаза, ѝ останува само една работа - да заврши еден или повеќе процеси. Дали OOM-убиецот треба веднаш да го прекине процесот или може да почека? Очигледно, кога се повикува out_of_memory, тоа се должи на чекање за I/O операција или страничење на дискот. Затоа, убиецот на ООМ мора прво да изврши проверки и врз основа на нив да одлучи дека процесот треба да се прекине. Ако сите проверки подолу се позитивни, OOM ќе го прекине процесот.

Процес на избор

Кога меморијата ќе истече, функцијата се повикува out_of_memory(). Има функција select_bad_process(), кој добива оценка од функцијата badness(). „Најлошиот“ процес ќе биде насочен. Функција badness() избира процес според одредени правила.

  1. На кернелот му треба минимална меморија за себе.
  2. Треба да ослободите многу меморија.
  3. Нема потреба да се прекинуваат процесите што користат мала меморија.
  4. Треба да се завршат минимум процеси.
  5. Комплексни алгоритми кои ги зголемуваат шансите за завршување за оние процеси кои самиот корисник сака да ги заврши.

Откако ги заврши сите овие проверки, ООМ го испитува резултатот (oom_score). ООМ назначува oom_score секој процес, а потоа ја множи оваа вредност со количината на меморија. Поверојатно е дека процесите со поголеми вредности ќе станат жртви на убиецот на ООМ. Процесите поврзани со корисникот на root имаат помал резултат и помала е веројатноста да бидат принудени да прекинат.

postgres=# SELECT pg_backend_pid();
pg_backend_pid 
----------------
    3813
(1 row)

ИД на процесот на Postgres е 3813, така што во друга школка е можно да се добие резултатот користејќи го овој параметар на јадрото oom_score:

vagrant@vagrant:~$ sudo cat /proc/3813/oom_score
2

Ако воопшто не сакате OOM-Killer да го убие процесот, постои друга опција за јадрото: oom_score_adj. Додадете голема негативна вредност за да ги намалите шансите да го завршите процесот што го цените.

sudo echo -100 > /proc/3813/oom_score_adj

За да поставите вредност oom_score_adj, поставете OOMScoreAdjust во сервисниот блок:

[Service]
OOMScoreAdjust=-1000

Или користете oomprotect во тим rcctl.

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

Присилно завршување на процес

Кога еден или повеќе процеси се веќе избрани, OOM-Killer ја повикува функцијата oom_kill_task(). Оваа функција испраќа сигнал за завршување на процесот. Во случај на недостаток на меморија oom_kill() Ја повикува оваа функција за да испрати сигнал SIGKILL до процесот. Во дневникот на јадрото се пишува порака.

Out of Memory: Killed process [pid] [name].

Како да се контролира OOM-Killer

В Linux Можете да го овозможите или оневозможите OOM-Killer (иако второто не се препорачува). За да го овозможите или оневозможите, користете го параметарот vm.oom-kill. За да овозможите OOM-Killer при извршување, извршете ја командата sysctl.

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

За да го исклучите OOM-Killer, наведете ја вредноста 0 во истата команда:

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

Резултатот од оваа команда нема да се зачува засекогаш, туку само до првото рестартирање. Ако ви треба повеќе упорност, додајте ја оваа линија во датотеката /etc/sysctl.conf:

echo vm.oom-kill = 1 >>/etc/sysctl.conf

Друг начин да се овозможи и оневозможи е да се напише променлива panic_on_oom. Вредноста секогаш може да се провери /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Ако ја поставите вредноста на 0, тогаш кога меморијата ќе истече, нема да има паника во јадрото.

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

Ако ја поставите вредноста на 1, тогаш кога меморијата ќе истече, ќе се појави паника во јадрото.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer може да се вклучува и исклучува, како што веќе споменавме. Linux може да резервира повеќе меморија за процеси отколку што е достапно, но всушност да не ја алоцира, а ова однесување е контролирано од параметар на јадрото LinuxПроменливата е одговорна за ова. vm.overcommit_memory.

Можете да ги наведете следните вредности за него:

0: Самото јадро одлучува дали да резервира премногу меморија. Ова е стандардната вредност во повеќето верзии. Linux.
1: Јадрото секогаш ќе резервира дополнителна меморија. Ова е ризично, бидејќи меморијата може да истече, бидејќи, најверојатно, еден ден процесите ќе го бараат тоа.
2: кернелот нема да резервира повеќе меморија отколку што е наведено во параметарот overcommit_ratio.

Со овој параметар, го одредувате процентот на меморија што е дозволено да биде пререзервирана. Ако нема место за тоа, не се доделува меморија, а резервацијата ќе биде одбиена. Ова е најбезбедната опција препорачана за PostgreSQL. OOM-Killer е под влијание на друг елемент - способноста за замена, која е контролирана од променливата cat /proc/sys/vm/swappiness. Овие вредности му кажуваат на кернелот како да се справи со страничење. Колку е поголема вредноста, толку е помала веројатноста дека OOM ќе го прекине процесот, но поради I/O операциите тоа навистина има негативно влијание врз базата на податоци. И обратно - колку е помала вредноста, толку е поголема веројатноста за интервенција на OOM-Killer, но перформансите на базата на податоци се исто така повисоки. Стандардната вредност е 60, но ако целата база на податоци се вклопува во меморијата, подобро е да ја поставите вредноста на 1.

Резултатите од

Не дозволувајте „убиецот“ во OOM-Killer да ве плаши. Во овој случај, убиецот ќе биде спасител на вашиот систем. Ги „убива“ најлошите процеси и го спасува системот од паѓање. За да не мора да користите OOM-Killer за да го прекинете PostgreSQL, поставете го на vm.overcommit_memory вредност 2. Ова не гарантира дека OOM-Killer нема да мора да интервенира, но ќе ја намали веројатноста да се принуди процесот на PostgreSQL да прекине.

Извор: www.habr.com

Купете доверлив хостинг за сајтови со DDoS заштита, VPS VDS сервери 🔥 Купете сигурен веб-хостинг со DDoS заштита, VPS VDS сервери | ProHoster