Настройване на „Убиец при липса на памет“ в Linux за PostgreSQL

Настройване на „Убиец при липса на памет“ в Linux за PostgreSQL

Когато е в Linux Сървърът на базата данни се прекратява неочаквано и трябва да се определи причината. Може да има няколко причини. Например, SIGSEGV — повреда поради грешка в бекенд сървъра. Но това е рядкост. Най-често просто ви липсва дисково пространство или памет. Ако ви свърши дисковото пространство, има само един изход - освободете място и рестартирайте базата данни.

Убиец на липса на памет

Когато ти сървър или процесът изчерпва паметта, Linux „Убиецът на неуспех при липса на памет“ (Out-Of-Memory Killer) предлага две решения: срив на цялата система или прекратяване на процеса (приложението), който изразходва памет. Разбира се, по-добре е да се прекрати процесът и да се спаси операционната система от срив. Накратко, „Убиецът на неуспех при липса на памет“ е процес, който прекратява приложение, за да спаси ядрото от срив. Той жертва приложението, за да поддържа операционната система да работи. Нека първо обсъдим как работи OOM и как да го контролираме, а след това да разгледаме как „Убиецът на неуспех при липса на памет“ решава кои приложения да прекрати.

Една от основните задачи Linux — Разпределяне на памет на процеси, когато те я поискат. Обикновено процес или приложение изисква памет от операционната система, но не я използва напълно. Ако операционната система разпредели памет на всеки, който я поиска, но не планира да я използва, системата бързо ще изчерпи паметта и системата ще се срине. За да предотврати това, операционната система резервира памет за даден процес, но всъщност не я разпределя. Паметта се разпределя само когато даден процес действително възнамерява да я използва. Понякога операционната система няма свободна памет, но разпределя памет на даден процес и когато процесът се нуждае от нея, операционната система я разпределя, ако може. Недостатъкът е, че понякога операционната система резервира памет, но когато е необходима, няма свободна памет, което води до срив на системата. OOM играе ключова роля в този сценарий, като прекратява процесите, за да предотврати паниката на ядрото. Когато процесът на PostgreSQL бъде принудително прекратен, в лога се появява следното съобщение:

Out of Memory: Killed process 12345 (postgres).

Ако на системата липсва памет и тя не може да бъде освободена, функцията се извиква out_of_memory. На този етап й остава само едно нещо - да завърши един или повече процеси. Трябва ли OOM-killer да прекрати процеса веднага или може да изчака? Очевидно, когато се извиква out_of_memory, това се дължи на изчакване на I/O операция или пейджинг на диск. Следователно убиецът на OOM трябва първо да извърши проверки и въз основа на тях да реши, че процесът трябва да бъде прекратен. Ако всички проверки по-долу са положителни, OOM ще прекрати процеса.

Избор на процес

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

  1. Ядрото се нуждае от минимална памет за себе си.
  2. Трябва да освободите много памет.
  3. Няма нужда да прекратявате процеси, които използват малко памет.
  4. Трябва да бъдат завършени минимални процеси.
  5. Комплексни алгоритми, които увеличават шансовете за завършване на тези процеси, които самият потребител иска да завърши.

След като завърши всички тези проверки, OOM проверява резултата (oom_score). ООМ назначава oom_score всеки процес и след това умножава тази стойност по количеството памет. Процесите с по-големи стойности е по-вероятно да станат жертва на OOM Killer. Процесите, свързани с 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