Подешавање убице ван меморије у Линук-у за ПостгреСКЛ

Подешавање убице ван меморије у Линук-у за ПостгреСКЛ

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

Убица без памћења

Када серверу или процесу понестане меморије, Линук нуди 2 решења: срушити цео систем или прекинути процес (апликацију) који једе меморију. Боље је, наравно, прекинути процес и спасити ОС од пада. Укратко, Оут-Оф-Мемори Киллер је процес који убија апликацију да би сачувао кернел од пада. Он жртвује апликацију да би ОС наставио да ради. Хајде да прво разговарамо о томе како ООМ функционише и како да га контролишемо, а затим да видимо како ООМ Киллер одлучује коју апликацију да прекине.

Један од главних задатака Линук-а је да додели меморију процесима када то затраже. Обично процес или апликација захтева меморију од ОС-а, али је не користи у потпуности. Ако ОС изда меморију свима који је траже, али не планирају да је користе, врло брзо ће меморија понестати и систем ће отказати. Да би то избегао, ОС резервише меморију за процес, али је заправо не ослобађа. Меморија се додељује само када ће је процес заиста користити. Дешава се да ОС нема слободну меморију, али додељује меморију процесу, а када је неком процесу потребна, ОС је додели ако може. Лоша страна је што понекад ОС резервише меморију, али у правом тренутку нема слободне меморије и систем се руши. ООМ игра важну улогу у овом сценарију и прекида процесе како би спречио језгро од панике. Када је ПостгреСКЛ процес присиљен да се прекине, у евиденцији се појављује порука:

Out of Memory: Killed process 12345 (postgres).

Ако систем има мало меморије и не може се ослободити, функција се позива out_of_memory. У овој фази, преостаје јој само једна ствар - завршити један или више процеса. Да ли ООМ-киллер треба одмах да прекине процес или може да сачека? Очигледно, када се позове оут_оф_мемори, то је због чекања на И/О операцију или страница на диск. Стога, ООМ убица мора прво да изврши провере и на основу њих одлучи да процес треба прекинути. Ако су све доње провере позитивне, ООМ ће прекинути процес.

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

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

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

Након што је завршио све ове провере, ООМ испитује резултат (oom_score). ООМ додељује oom_score сваки процес, а затим множи ову вредност са количином меморије. Већа је вероватноћа да ће процеси са већим вредностима постати жртва ООМ Киллера. Процеси повезани са роот корисником имају нижи резултат и мања је вероватноћа да ће бити приморани да се прекину.

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

ИД Постгрес процеса је 3813, тако да је у другој љусци могуће добити резултат користећи овај параметар кернела oom_score:

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

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

sudo echo -100 > /proc/3813/oom_score_adj

Да бисте поставили вредност oom_score_adj, подесите ООМСцореАдјуст у сервисном блоку:

[Service]
OOMScoreAdjust=-1000

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

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

Присилно окончање процеса

Када је један или више процеса већ изабрано, ООМ-Киллер позива функцију oom_kill_task(). Ова функција шаље сигнал завршетка процесу. У случају недостатка меморије oom_kill() Позива ову функцију да пошаље СИГКИЛЛ сигнал процесу. Порука се уписује у дневник кернела.

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

Како контролисати ООМ-Киллер

На Линук-у можете омогућити или онемогућити ООМ-Киллер (иако се ово друго не препоручује). Да бисте омогућили или онемогућили, користите параметар vm.oom-kill. Да бисте омогућили ООМ-Киллер током извршавања, покрените команду sysctl.

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

Да бисте онемогућили ООМ-Киллер, наведите вредност 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

ООМ-Киллер се не може само укључити и искључити. Већ смо рекли да Линук може да резервише више меморије за процесе него што је доступно, а да је не додели, а ово понашање контролише параметар Линук кернела. За ово је одговорна варијабла vm.overcommit_memory.

За њега можете одредити следеће вредности:

0: Кернел сам одлучује да ли ће резервисати превише меморије. Ово је подразумевано у већини верзија Линук-а.
1: Кернел ће увек резервисати додатну меморију. Ово је ризично, јер меморија може понестати, јер ће, највероватније, једног дана процеси то захтевати.
2: кернел неће резервисати више меморије него што је наведено у параметру overcommit_ratio.

Овим параметром одређујете проценат меморије којој је дозвољено да буде прекомерно резервисана. Ако за то нема места, меморија се не додељује, а резервација ће бити одбијена. Ово је најсигурнија опција која се препоручује за ПостгреСКЛ. ООМ-Киллер је под утицајем другог елемента - могућности замене, која се контролише променљивом cat /proc/sys/vm/swappiness. Ове вредности говоре кернелу како да рукује страницама. Што је већа вредност, мања је вероватноћа да ће ООМ прекинути процес, али због И/О операција то има негативан утицај на базу података. И обрнуто – што је нижа вредност, већа је вероватноћа интервенције ООМ-Киллер-а, али је и перформанса базе података већа. Подразумевана вредност је 60, али ако цела база података стане у меморију, боље је поставити вредност на 1.

Резултати

Не дозволите да вас "убица" у ООМ-Киллеру уплаши. У овом случају, убица ће бити спасилац вашег система. Он „убија“ најгоре процесе и спасава систем од пада. Да бисте избегли коришћење ООМ-Киллер-а за укидање ПостгреСКЛ-а, подесите на vm.overcommit_memory вредност 2. Ово не гарантује да ООМ-Киллер неће морати да интервенише, али ће смањити вероватноћу присиљавања ПостгреСКЛ процеса да се прекине.

Извор: ввв.хабр.цом

Додај коментар