
As yn Linux сервер базы данных непредвиденно завершает работу, нужно найти причину. Причин может быть несколько. Например, SIGSEGV - mislearring fanwege in brek yn 'e backend-tsjinner. Mar dit is seldsum. Meastentiids rinne jo gewoan út skiifromte of ûnthâld. As jo gjin skiifromte hawwe, is d'r mar ien útwei - romte frijmeitsje en de databank opnij starte.
Out-Of-Memory Killer
Wannear't jo server или процесса заканчивается память, Linux предлагает 2 пути решения: обрушить всю систему или завершить процесс (приложение), который съедает память. Лучше, конечно, завершить процесс и спасти ОС от аварийного завершения. В двух словах, Out-Of-Memory Killer — это процесс, который завершает приложение, чтобы спасти ядро от сбоя. Он жертвует приложением, чтобы сохранить работу ОС. Давайте сначала обсудим, как работает OOM и как его контролировать, а потом посмотрим, как OOM Killer решает, какое приложение завершить.
Одна из главных задач Linux — выделять память процессам, когда они ее просят. Обычно процесс или приложение запрашивают у ОС память, а сами используют ее не полностью. Если ОС будет выдавать память всем, кто ее просит, но не планирует использовать, очень скоро память закончится, и система откажет. Чтобы этого избежать, ОС резервирует память за процессом, но фактически не выдает ее. Память выделяется, только когда процесс действительно собирается ее использовать. Случается, что у ОС нет свободной памяти, но она закрепляет память за процессом, и когда процессу она нужна, ОС выделяет ее, если может. Минус в том, что иногда ОС резервирует память, но в нужный момент свободной памяти нет, и происходит сбой системы. OOM играет важную роль в этом сценарии и завершает процессы, чтобы уберечь ядро от паники. Когда принудительно завершается процесс PostgreSQL, в логе появляется сообщение:
Out of Memory: Killed process 12345 (postgres).As it systeem leech is op ûnthâld en it kin net befrijd wurde, wurdt de funksje neamd out_of_memory. Op dit stadium hat se mar ien ding te dwaan - ien of mear prosessen foltôgje. Moat OOM-killer it proses fuortendaliks beëinigje of kin it wachtsje? Fansels, as out_of_memory wurdt neamd, komt it troch it wachtsjen op in I / O-operaasje of paging nei skiif. Dêrom moat de OOM-moardner earst kontrôles útfiere en op grûn dêrfan beslute dat it proses beëinige wurde moat. As alle kontrôles hjirûnder posityf binne, sil OOM it proses beëinigje.
Proses seleksje
As ûnthâld rint út, de funksje neamd out_of_memory(). It hat in funksje select_bad_process(), dy't in evaluaasje krijt fan 'e funksje badness(). It "slimste" proses sil rjochte wurde. Funksje badness() kiest in proses neffens bepaalde regels.
- De kernel hat wat minimum ûnthâld foar himsels nedich.
- Jo moatte in protte ûnthâld frijmeitsje.
- D'r is gjin ferlet om prosessen te beëinigjen dy't lyts ûnthâld brûke.
- Minimum prosessen moatte wurde foltôge.
- Komplekse algoritmen dy't de kâns op foltôging fergrutsje foar dy prosessen dy't de brûker sels foltôgje wol.
Nei it foltôgjen fan al dizze kontrôles ûndersiket OOM de skoare (oom_score). OOM jout oom_score elk proses, en dan fermannichfâldigje dizze wearde mei it bedrach fan ûnthâld. Prosessen mei gruttere wearden binne wierskynliker slachtoffer fan 'e OOM Killer. Prosessen dy't ferbûn binne mei de root-brûker hawwe in legere skoare en wurde minder wierskynlik twongen om te beëinigjen.
postgres=# SELECT pg_backend_pid();
pg_backend_pid
----------------
3813
(1 row)De Postgres proses ID is 3813, dus yn in oare shell is it mooglik om de skoare te krijen mei dizze kernelparameter oom_score:
vagrant@vagrant:~$ sudo cat /proc/3813/oom_score
2As jo net wolle dat OOM-Killer it proses hielendal deadzje, is d'r in oare kearnopsje: oom_score_adj. Foegje in grutte negative wearde ta te ferminderjen de kânsen fan in foltôgjen fan in proses jo wearde.
sudo echo -100 > /proc/3813/oom_score_adjOm in wearde yn te stellen oom_score_adj, set OOMScoreAdjust yn it tsjinstblok yn:
[Service]
OOMScoreAdjust=-1000Of brûke oomprotect yn in team rcctl.
rcctl set <i>servicename</i> oomprotect -1000Force beëiniging fan in proses
As ien of mear prosessen al selektearre binne, ropt OOM-Killer de funksje op oom_kill_task(). Dizze funksje stjoert in beëinigingsinjaal nei it proses. Yn gefal fan ûnthâld tekoart oom_kill() Roept dizze funksje op om in SIGKILL-sinjaal nei it proses te stjoeren. In berjocht wurdt skreaun nei it kernel log.
Out of Memory: Killed process [pid] [name].Hoe kinne jo OOM-Killer kontrolearje
В Linux можно включать и отключать OOM-Killer (хотя последнее не рекомендуется). Для включения и отключения используйте параметр vm.oom-kill. Om OOM-Killer by runtime yn te skeakeljen, útfiere it kommando sysctl.
sudo -s sysctl -w vm.oom-kill = 1Om OOM-Killer út te skeakeljen, spesifisearje de wearde 0 yn itselde kommando:
sudo -s sysctl -w vm.oom-kill = 0It resultaat fan dit kommando sil net foar altyd bewarre wurde, mar allinich oant de earste herstart. As jo mear persistinsje nedich binne, foegje dan dizze rigel ta oan it bestân /etc/sysctl.conf:
echo vm.oom-kill = 1 >>/etc/sysctl.confIn oare manier om yn- en út te skeakeljen is in fariabele te skriuwen panic_on_oom. De wearde kin altyd yncheckt wurde /proc.
$ cat /proc/sys/vm/panic_on_oom
0As jo de wearde ynstelle op 0, dan sil d'r gjin kernel panyk wêze as it ûnthâld op is.
$ echo 0 > /proc/sys/vm/panic_on_oomAs jo de wearde ynstelle op 1, dan sil in kernel panyk foarkomme as it ûnthâld op is.
echo 1 > /proc/sys/vm/panic_on_oomOOM-Killer можно не только включать и выключать. Мы уже говорили, что Linux может зарезервировать для процессов больше памяти, чем есть, но не выделять ее по факту, и этим поведением управляет параметр ядра Linux. За это отвечает переменная vm.overcommit_memory.
Jo kinne de folgjende wearden dêrfoar opjaan:
0: ядро само решает, стоит ли резервировать слишком много памяти. Это значение по умолчанию в большинстве версий Linux.
1: De kearn sil altyd ekstra ûnthâld reservearje. Dit is risikofolle, om't it ûnthâld kin oprinne, om't, nei alle gedachten, ien dei de prosessen sille fereaskje.
2: de kearn sil net reservearje mear ûnthâld as oantsjutte yn de parameter overcommit_ratio.
Mei dizze parameter spesifisearje jo it persintaazje ûnthâld dat tastien is om te reservearjen. As der gjin romte foar it, gjin ûnthâld wurdt tawiisd, en it reservaat wurdt wegere. Dit is de feilichste opsje oanrikkemandearre foar PostgreSQL. OOM-Killer wurdt beynfloede troch in oar elemint - de wikselfermogen, dat wurdt regele troch de fariabele cat /proc/sys/vm/swappiness. Dizze wearden fertelle de kernel hoe't it paging kin omgean. Hoe heger de wearde, hoe minder kâns it is dat OOM it proses sil beëinigje, mar troch I/O-operaasjes hat it in negative ynfloed op de databank. En oarsom - hoe leger de wearde, hoe heger de kâns op OOM-Killer-yntervinsje, mar de databankprestaasje is ek heger. De standertwearde is 60, mar as de folsleine databank yn it ûnthâld past, is it better om de wearde op 1 yn te stellen.
Resultaten
Lit de "moardner" yn OOM-Killer jo net bang meitsje. Yn dit gefal sil de moardner de rêder fan jo systeem wêze. It "deadet" de minste prosessen en besparret it systeem fan crashing. Om foar te kommen dat jo OOM-Killer moatte brûke om PostgreSQL te beëinigjen, set op vm.overcommit_memory wearde 2. Dit garandearret net dat OOM-Killer net hoecht yn te gripen, mar it sil de kâns ferminderje om it PostgreSQL-proses te twingen om te beëinigjen.
Boarne: www.habr.com
