Nastavení nástroje Out-Of-Memory Killer v Linuxu pro PostgreSQL

Nastavení nástroje Out-Of-Memory Killer v Linuxu pro PostgreSQL

Když se databázový server v Linuxu neočekávaně ukončí, musíte najít příčinu. Důvodů může být několik. Například, SIGSEGV — selhání kvůli chybě na backend serveru. Ale to je vzácné. Nejčastěji vám prostě dojde místo na disku nebo paměti. Pokud vám dojde místo na disku, existuje pouze jedna cesta ven – uvolnit místo a restartovat databázi.

Out-of-Memory Killer

Když serveru nebo procesu dojde paměť, Linux nabízí 2 řešení: zhroucení celého systému nebo ukončení procesu (aplikace), který zabírá paměť. Je samozřejmě lepší proces ukončit a zachránit OS před pádem. Stručně řečeno, Out-Of-Memory Killer je proces, který zabije aplikaci, aby zachránil jádro před pádem. Obětuje aplikaci, aby udržela operační systém v chodu. Nejprve si proberme, jak OOM funguje a jak jej ovládat, a pak se podívejme, jak se OOM Killer rozhoduje, kterou aplikaci ukončit.

Jedním z hlavních úkolů Linuxu je alokovat paměť procesům, když o to požádají. Proces nebo aplikace obvykle požaduje paměť od operačního systému, ale plně ji nevyužívá. Pokud OS rozdá paměť každému, kdo o ni požádá, ale nemá v plánu ji použít, velmi brzy dojde paměť a systém selže. Aby se tomu zabránilo, operační systém rezervuje paměť pro proces, ale ve skutečnosti ji neuvolňuje. Paměť je alokována pouze tehdy, když ji proces skutečně použije. Stává se, že OS nemá volnou paměť, ale přiřadí paměť procesu, a když ji proces potřebuje, OS ji přidělí, pokud může. Nevýhodou je, že někdy operační systém rezervuje paměť, ale ve správný čas není volná paměť a systém se zhroutí. OOM hraje v tomto scénáři důležitou roli a ukončuje procesy, aby nedošlo k panice jádra. Když je proces PostgreSQL nucen ukončit, v protokolu se objeví zpráva:

Out of Memory: Killed process 12345 (postgres).

Pokud je v systému málo paměti a nelze ji uvolnit, je funkce volána out_of_memory. V této fázi jí zbývá udělat jediné – dokončit jeden nebo více procesů. Měl by OOM-killer ukončit proces okamžitě nebo může počkat? Je zřejmé, že když je voláno out_of_memory, je to kvůli čekání na I/O operaci nebo stránkování na disk. OOM zabiják tedy musí nejprve provést kontroly a na jejich základě rozhodnout, že je potřeba proces ukončit. Pokud jsou všechny níže uvedené kontroly pozitivní, OOM proces ukončí.

Výběr procesu

Když dojde paměť, funkce se zavolá out_of_memory(). Má funkci select_bad_process(), který obdrží hodnocení od funkce badness(). Bude zaměřen na „nejhorší“ proces. Funkce badness() vybírá proces podle určitých pravidel.

  1. Jádro pro sebe potřebuje určitou minimální paměť.
  2. Musíte uvolnit hodně paměti.
  3. Není potřeba ukončovat procesy, které využívají málo paměti.
  4. Je třeba dokončit minimum procesů.
  5. Komplexní algoritmy, které zvyšují šance na dokončení u těch procesů, které chce dokončit sám uživatel.

Po dokončení všech těchto kontrol OOM prozkoumá skóre (oom_score). OOM přiděluje oom_score každý proces a poté tuto hodnotu vynásobí množstvím paměti. Procesy s vyššími hodnotami se s větší pravděpodobností stanou obětí OOM Killera. Procesy spojené s uživatelem root mají nižší skóre a je méně pravděpodobné, že budou nuceny ukončit.

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

ID procesu Postgres je 3813, takže v jiném shellu je možné získat skóre pomocí tohoto parametru jádra oom_score:

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

Pokud nechcete, aby OOM-Killer vůbec zabil proces, existuje další možnost jádra: oom_score_adj. Přidejte velkou zápornou hodnotu, abyste snížili šance na dokončení procesu, který si ceníte.

sudo echo -100 > /proc/3813/oom_score_adj

Chcete-li nastavit hodnotu oom_score_adj, nastavte OOMScoreAdjust v servisním bloku:

[Service]
OOMScoreAdjust=-1000

Nebo použít oomprotect v týmu rcctl.

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

Vynutit ukončení procesu

Když je již vybrán jeden nebo více procesů, OOM-Killer zavolá funkci oom_kill_task(). Tato funkce vyšle do procesu ukončovací signál. V případě nedostatku paměti oom_kill() Volá tuto funkci pro odeslání signálu SIGKILL do procesu. Zpráva se zapíše do protokolu jádra.

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

Jak ovládat OOM-Killer

V Linuxu můžete povolit nebo zakázat OOM-Killer (ačkoli druhý se nedoporučuje). Chcete-li povolit nebo zakázat, použijte parametr vm.oom-kill. Chcete-li povolit OOM-Killer za běhu, spusťte příkaz sysctl.

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

Chcete-li zakázat OOM-Killer, zadejte ve stejném příkazu hodnotu 0:

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

Výsledek tohoto příkazu nebude uložen navždy, ale pouze do prvního restartu. Pokud potřebujete větší vytrvalost, přidejte tento řádek do souboru /etc/sysctl.conf:

echo vm.oom-kill = 1 >>/etc/sysctl.conf

Dalším způsobem, jak povolit a zakázat, je napsat proměnnou panic_on_oom. Hodnotu lze vždy zkontrolovat /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Pokud nastavíte hodnotu na 0, pak při vyčerpání paměti nedojde k panice jádra.

$ echo 0 > /proc/sys/vm/panic_on_oom

Pokud nastavíte hodnotu na 1, pak když dojde paměť, dojde k panice jádra.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer lze nejen zapnout a vypnout. Již jsme řekli, že Linux může vyhradit více paměti pro procesy, než je k dispozici, aniž by ji skutečně alokoval, a toto chování je řízeno parametrem linuxového jádra. Za to může proměnná vm.overcommit_memory.

Můžete pro něj zadat následující hodnoty:

0: Samotné jádro se rozhodne, zda si vyhradí příliš mnoho paměti. Toto je výchozí nastavení ve většině verzí Linuxu.
1: Jádro si vždy vyhradí paměť navíc. To je riskantní, protože paměť může dojít, protože to s největší pravděpodobností jednoho dne procesy budou vyžadovat.
2: jádro si nevyhradí více paměti, než je uvedeno v parametru overcommit_ratio.

Pomocí tohoto parametru určíte procento paměti, které je povoleno přerezervovat. Pokud pro něj není místo, není přidělena žádná paměť a rezervace bude zamítnuta. Toto je nejbezpečnější možnost doporučená pro PostgreSQL. OOM-Killer je ovlivněn dalším prvkem – schopností swapování, která je řízena proměnnou cat /proc/sys/vm/swappiness. Tyto hodnoty říkají jádru, jak zacházet se stránkováním. Čím vyšší hodnota, tím menší je pravděpodobnost, že OOM ukončí proces, ale kvůli I/O operacím to má negativní dopad na databázi. A naopak – čím nižší hodnota, tím vyšší je pravděpodobnost zásahu OOM-Killer, ale také vyšší je výkon databáze. Výchozí hodnota je 60, ale pokud se celá databáze vejde do paměti, je lepší nastavit hodnotu na 1.

Výsledky

Nenechte se „zabijákem“ v OOM-Killer vyděsit. V tomto případě bude vrah zachráncem vašeho systému. „Zabije“ nejhorší procesy a zachrání systém před zhroucením. Abyste nemuseli k ukončení PostgreSQL používat OOM-Killer, nastavte na vm.overcommit_memory hodnota 2. To nezaručuje, že OOM-Killer nebude muset zasahovat, ale sníží se tím pravděpodobnost vynucení ukončení procesu PostgreSQL.

Zdroj: www.habr.com

Přidat komentář