Танзими Killer аз хотира дар Linux барои PostgreSQL

Танзими Killer аз хотира дар Linux барои PostgreSQL

Вақте ки сервери пойгоҳи додаҳо дар Linux ногаҳон қатъ мешавад, шумо бояд сабаби онро пайдо кунед. Якчанд сабабҳо вуҷуд дошта метавонанд. Барои намуна, СИГСЕГВ — нокомӣ аз сабаби хато дар сервери пуштибонӣ. Аммо ин кам аст. Аксар вақт, шумо танҳо фазои диск ё хотира тамом мешавад. Агар шумо фазои дискро тамом кунед, танҳо як роҳи халосӣ вуҷуд дорад - ҷой холӣ кунед ва пойгоҳи додаҳоро аз нав оғоз кунед.

Қотил аз хотира

Вақте ки сервер ё раванд аз хотира тамом мешавад, Linux ду ҳалли худро пешниҳод мекунад: тамоми системаро вайрон кунед ё равандро (барнома), ки хотираро мехӯрад, қатъ кунед. Албатта, беҳтар аст, ки равандро қатъ кунед ва ОС-ро аз садама наҷот диҳед. Хулоса, Killer Out-Of-Memory равандест, ки барномаро барои наҷот додани ядро ​​аз садама мекушад. Он барномаро қурбон мекунад, то OS кор кунад. Биёед аввал муҳокима кунем, ки OOM чӣ гуна кор мекунад ва чӣ гуна онро идора кардан мумкин аст ва сипас бубинем, ки чӣ тавр OOM Killer кадом барномаро қатъ мекунад.

Яке аз вазифаҳои асосии Linux ҷудо кардани хотира ба равандҳо ҳангоми дархост кардани он мебошад. Одатан, раванд ё барнома хотираро аз ОС дархост мекунад, аммо онро пурра истифода намебарад. Агар ОС ба ҳар касе, ки онро талаб мекунад, вале нақшаи истифодаи онро надорад, хотира диҳад, ба зудӣ хотира тамом мешавад ва система аз кор мебарояд. Барои пешгирӣ кардани ин, OS хотираро барои раванд захира мекунад, аммо воқеан онро озод намекунад. Хотира танҳо вақте ҷудо карда мешавад, ки раванд воқеан онро истифода мебарад. Чунин ҳодиса рӯй медиҳад, ки ОС хотираи холӣ надорад, аммо он хотираро ба раванд таъин мекунад ва вақте ки раванд ба он ниёз дорад, ОС агар имконпазир бошад, онро ҷудо мекунад. Камбудии он дар он аст, ки баъзан OS хотираро захира мекунад, аммо дар вақти лозима хотираи холӣ нест ва система аз кор мебарояд. OOM дар ин сенария нақши муҳим мебозад ва равандҳоро қатъ мекунад, то ядро ​​​​аз воҳима пешгирӣ кунад. Вақте ки раванди PostgreSQL маҷбур аст қатъ карда шавад, дар гузориш паём пайдо мешавад:

Out of Memory: Killed process 12345 (postgres).

Агар система хотираи кам дошта бошад ва он озод карда нашавад, функсия даъват карда мешавад out_of_memory. Дар ин марҳила, вай танҳо як кор дорад - як ё якчанд равандро анҷом диҳад. Оё OOM-қотил бояд равандро фавран қатъ кунад ё метавонад интизор шавад? Аён аст, вақте ки out_of_memory даъват карда мешавад, ин бо сабаби интизории амалиёти воридот/баҳо ё пейджинг ба диск аст. Аз ин рӯ, қотили OOM бояд аввал санҷишҳоро анҷом диҳад ва дар асоси онҳо қарор кунад, ки ин раванд бояд қатъ карда шавад. Агар ҳамаи санҷишҳои дар поён овардашуда мусбат бошанд, OOM равандро қатъ мекунад.

Интихоби раванд

Вақте ки хотира тамом мешавад, функсия даъват карда мешавад out_of_memory(). Он функсия дорад select_bad_process(), ки аз функсия баҳогузорӣ мегирад badness(). Процесси «бадтарин» максаднок карда мешавад. Функсия badness() аз руи коидахои муайян процессеро интихоб мекунад.

  1. Ядро барои худ каме хотираи ҳадди ақалро талаб мекунад.
  2. Шумо бояд хотираи зиёдеро холӣ кунед.
  3. Барои қатъ кардани равандҳое, ки хотираи камро истифода мебаранд, лозим нест.
  4. Процессҳои ҳадди аққал бояд анҷом дода шаванд.
  5. Алгоритмҳои мураккабе, ки имконияти анҷом додани он равандҳоеро, ки худи корбар мехоҳад анҷом диҳад, зиёд мекунад.

Пас аз анҷом додани ҳамаи ин санҷишҳо, OOM холҳоро тафтиш мекунад (oom_score). ООМ таъин мекунад oom_score ҳар як раванд, ва он гоҳ зарб ин арзиш бо ҳаҷми хотира. Равандҳои дорои арзишҳои калонтар эҳтимоли қурбонии OOM Killer мешаванд. Равандҳое, ки бо корбари реша алоқаманданд, холҳои камтар доранд ва эҳтимоли камтар маҷбуран қатъ карда мешаванд.

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

ID-и раванди 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 равандро қатъ кунад, аммо аз сабаби амалиёти воридотӣ / баромад он ба пойгоҳи додаҳо таъсири манфӣ мерасонад. Ва баръакс - чӣ қадаре ки арзиш паст бошад, эҳтимолияти дахолати OOM-Killer ҳамон қадар баландтар аст, аммо иҷрои пойгоҳи додаҳо низ баландтар аст. Қимати пешфарз 60 аст, аммо агар тамоми пойгоҳи додаҳо ба хотира мувофиқат кунад, беҳтар аст, ки арзишро ба 1 муқаррар кунед.

Натиҷаҳо

Нагузоред, ки "қотил" дар OOM-Killer шуморо тарсонад. Дар ин ҳолат, қотил наҷотдиҳандаи системаи шумо хоҳад буд. Вай процессдои бедтаринро «мекушад» ва системаро аз садама начот медихад. Барои пешгирӣ кардани истифодаи OOM-Killer барои қатъ кардани PostgreSQL, танзим кунед vm.overcommit_memory арзиш 2. Ин кафолат намедиҳад, ки OOM-Killer набояд дахолат кунад, аммо он эҳтимолияти маҷбур кардани раванди PostgreSQL-ро барои қатъ кардан коҳиш медиҳад.

Манбаъ: will.com

Илова Эзоҳ