
Када у Linux Сервер базе података се неочекивано прекида и потребно је утврдити узрок. Може постојати неколико разлога. На пример, СИГСЕГВ — грешка због грешке на позадинском серверу. Али ово је ретко. Најчешће вам једноставно понестане простора на диску или меморије. Ако вам понестане простора на диску, постоји само један излаз - ослободите простор и поново покрените базу података.
Убица без памћења
Када сервер или процесу понестане меморије, Linux „Убица несташице меморије“ нуди два решења: рушење целог система или прекид процеса (апликације) који троши меморију. Наравно, боље је прекинути процес и спасити оперативни систем од пада. Укратко, „Убица несташице меморије“ је процес који прекида рад апликације како би спасао језгро од пада. Жртвује апликацију да би оперативни систем наставио да ради. Прво ћемо разговарати о томе како „Убица несташице меморије“ функционише и како га контролисати, а затим погледати како „Убица несташице меморије“ одлучује које апликације да прекине.
Један од главних задатака Linux — Доделите меморију процесима када је затраже. Типично, процес или апликација захтева меморију од оперативног система, али је не користи у потпуности. Ако оперативни систем додели меморију свима који је затраже, али не планирају да је користе, систем ће брзо остати без меморије и систем ће се срушити. Да би се ово спречило, оперативни систем резервише меморију за процес, али је заправо не додељује. Меморија се додељује само када процес заправо намерава да је користи. Понекад оперативни систем нема слободне меморије, али је додељује процесу, а када је процесу потребна, оперативни систем је додељује ако може. Мана је што оперативни систем понекад резервише меморију, али када је потребна, нема слободне меморије, што узрокује пад система. OOM игра кључну улогу у овом сценарију, прекидајући процесе како би се спречило да језгро паничи. Када се PostgreSQL процес присилно прекине, у логу се појављује следећа порука:
Out of Memory: Killed process 12345 (postgres).Ако систем има мало меморије и не може се ослободити, функција се позива out_of_memory. У овој фази, преостаје јој само једна ствар - завршити један или више процеса. Да ли ООМ-киллер треба одмах да прекине процес или може да сачека? Очигледно, када се позове оут_оф_мемори, то је због чекања на И/О операцију или страница на диск. Стога, ООМ убица мора прво да изврши провере и на основу њих одлучи да процес треба прекинути. Ако су све доње провере позитивне, ООМ ће прекинути процес.
Избор процеса
Када меморија понестане, функција се позива out_of_memory(). Има функцију select_bad_process(), који добија оцену од функције badness(). „Најгори“ процес ће бити циљани. Функција badness() бира процес према одређеним правилима.
- Кернелу је потребан минимум меморије за себе.
- Морате ослободити много меморије.
- Нема потребе за прекидом процеса који користе мало меморије.
- Минимални процеси морају бити завршени.
- Сложени алгоритми који повећавају шансе за завршетак за оне процесе које сам корисник жели да заврши.
Након што је завршио све ове провере, ООМ испитује резултат (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].Како контролисати ООМ-Киллер
В Linux Можете омогућити или онемогућити OOM-Killer (мада се ово друго не препоручује). Да бисте га омогућили или онемогућили, користите параметар 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_oomOOM-Killer се може укључити и искључити, као што смо већ поменули. Linux може резервисати више меморије за процесе него што је доступно, али је заправо неће доделити, а ово понашање контролише параметр језгра LinuxПроменљива је одговорна за ово. vm.overcommit_memory.
За њега можете одредити следеће вредности:
0: Само језгро одлучује да ли да резервише превише меморије. Ово је подразумевана вредност у већини верзија. Linux.
1: Кернел ће увек резервисати додатну меморију. Ово је ризично, јер меморија може понестати, јер ће, највероватније, једног дана процеси то захтевати.
2: кернел неће резервисати више меморије него што је наведено у параметру overcommit_ratio.
Овим параметром одређујете проценат меморије којој је дозвољено да буде прекомерно резервисана. Ако за то нема места, меморија се не додељује, а резервација ће бити одбијена. Ово је најсигурнија опција која се препоручује за ПостгреСКЛ. ООМ-Киллер је под утицајем другог елемента - могућности замене, која се контролише променљивом cat /proc/sys/vm/swappiness. Ове вредности говоре кернелу како да рукује страницама. Што је већа вредност, мања је вероватноћа да ће ООМ прекинути процес, али због И/О операција то има негативан утицај на базу података. И обрнуто – што је нижа вредност, већа је вероватноћа интервенције ООМ-Киллер-а, али је и перформанса базе података већа. Подразумевана вредност је 60, али ако цела база података стане у меморију, боље је поставити вредност на 1.
Резултати
Не дозволите да вас "убица" у ООМ-Киллеру уплаши. У овом случају, убица ће бити спасилац вашег система. Он „убија“ најгоре процесе и спасава систем од пада. Да бисте избегли коришћење ООМ-Киллер-а за укидање ПостгреСКЛ-а, подесите на vm.overcommit_memory вредност 2. Ово не гарантује да ООМ-Киллер неће морати да интервенише, али ће смањити вероватноћу присиљавања ПостгреСКЛ процеса да се прекине.
Извор: ввв.хабр.цом
