Konfigurowanie funkcji Out-Of-Memory Killer w Linux dla PostgreSQL

Konfigurowanie funkcji Out-Of-Memory Killer w Linux dla PostgreSQL

Kiedy jest Linux Serwer bazy danych nieoczekiwanie się wyłącza i należy ustalić przyczynę. Przyczyn może być kilka. Na przykład: SIGSEGV — awaria spowodowana błędem na serwerze zaplecza. Ale to jest rzadkie. Najczęściej po prostu brakuje Ci miejsca na dysku lub pamięci. Jeśli zabraknie Ci miejsca na dysku, jest tylko jedno wyjście - zwolnij miejsce i zrestartuj bazę danych.

Zabójca bez pamięci

Gdy serwer lub procesowi zabraknie pamięci, Linux Zabójca pamięci (Out-Of-Memory Killer) oferuje dwa rozwiązania: awarię całego systemu lub zamknięcie procesu (aplikacji) zużywającego pamięć. Oczywiście lepiej jest zakończyć proces i uchronić system operacyjny przed awarią. Krótko mówiąc, zabójca pamięci (Out-Of-Memory Killer) to proces, który kończy działanie aplikacji, aby uchronić jądro przed awarią. Poświęca on działanie aplikacji, aby utrzymać system operacyjny w działaniu. Najpierw omówmy, jak działa zabójca pamięci (OOM) i jak go kontrolować, a następnie przyjrzyjmy się, jak zabójca pamięci (OOM Killer) decyduje, które aplikacje mają zostać zakończone.

Jedno z głównych zadań Linux — Przydzielaj pamięć procesom, gdy o nią proszą. Zazwyczaj proces lub aplikacja żąda pamięci od systemu operacyjnego, ale nie wykorzystuje jej w pełni. Jeśli system operacyjny przydzieli pamięć każdemu, kto jej zażąda, ale nie planuje jej wykorzystać, system szybko się zapełni i ulegnie awarii. Aby temu zapobiec, system operacyjny rezerwuje pamięć dla procesu, ale jej faktycznie nie przydziela. Pamięć jest przydzielana tylko wtedy, gdy proces faktycznie zamierza jej użyć. Czasami system operacyjny nie ma wolnej pamięci, ale przydziela ją procesowi, a gdy proces jej potrzebuje, system operacyjny ją przydziela, jeśli może. Wadą jest to, że czasami system operacyjny rezerwuje pamięć, ale gdy jest potrzebna, brakuje wolnej pamięci, co powoduje awarię systemu. Brak pamięci (OOM) odgrywa kluczową rolę w tym scenariuszu, kończąc procesy, aby zapobiec panice jądra. Gdy proces PostgreSQL zostanie wymuszony, w dzienniku pojawia się następujący komunikat:

Out of Memory: Killed process 12345 (postgres).

Jeżeli w systemie brakuje pamięci i nie można jej zwolnić, funkcja jest wywoływana out_of_memory. Na tym etapie pozostaje jej już tylko jedno – ukończyć jeden lub więcej procesów. Czy OOM-killer powinien natychmiast zakończyć proces, czy może poczekać? Oczywiście wywołanie out_of_memory wynika z oczekiwania na operację we/wy lub stronicowanie na dysk. Dlatego też zabójca OOM musi najpierw przeprowadzić kontrole i na ich podstawie podjąć decyzję o konieczności zakończenia procesu. Jeśli wszystkie poniższe kontrole wypadną pozytywnie, OOM zakończy proces.

Wybór procesu

Gdy skończy się pamięć, funkcja zostanie wywołana out_of_memory(). Ma funkcję select_bad_process(), który otrzymuje ocenę od funkcji badness(). Celem będzie „najgorszy” proces. Funkcjonować badness() wybiera proces według określonych reguł.

  1. Jądro potrzebuje dla siebie minimalnej ilości pamięci.
  2. Musisz zwolnić dużo pamięci.
  3. Nie ma potrzeby kończenia procesów, które zużywają mało pamięci.
  4. Należy ukończyć minimalne procesy.
  5. Złożone algorytmy zwiększające szanse na realizację procesów, które sam użytkownik chce zakończyć.

Po zakończeniu wszystkich tych kontroli OOM sprawdza wynik (oom_score). OOM przydziela oom_score każdego procesu, a następnie mnoży tę wartość przez ilość pamięci. Procesy o większych wartościach częściej padają ofiarą OOM Killera. Procesy powiązane z użytkownikiem root mają niższy wynik i jest mniej prawdopodobne, że zostaną zmuszone do zakończenia.

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

Identyfikator procesu Postgres to 3813, więc w innej powłoce można uzyskać wynik za pomocą tego parametru jądra oom_score:

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

Jeśli nie chcesz, aby OOM-Killer w ogóle zakończył proces, istnieje inna opcja jądra: oom_score_adj. Dodaj dużą wartość ujemną, aby zmniejszyć szanse na zakończenie cenionego procesu.

sudo echo -100 > /proc/3813/oom_score_adj

Aby ustawić wartość oom_score_adj, ustaw OOMScoreAdjust w bloku serwisowym:

[Service]
OOMScoreAdjust=-1000

Albo użyj oomprotect w zespole rcctl.

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

Wymuś zakończenie procesu

Gdy jeden lub więcej procesów jest już wybranych, OOM-Killer wywołuje tę funkcję oom_kill_task(). Funkcja ta wysyła do procesu sygnał zakończenia. W przypadku braku pamięci oom_kill() Wywołuje tę funkcję, aby wysłać do procesu sygnał SIGKILL. Komunikat jest zapisywany w dzienniku jądra.

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

Jak kontrolować OOM-Killer

В Linux Możesz włączyć lub wyłączyć OOM-Killera (choć to drugie nie jest zalecane). Aby go włączyć lub wyłączyć, użyj parametru vm.oom-kill. Aby włączyć OOM-Killer w czasie wykonywania, uruchom polecenie sysctl.

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

Aby wyłączyć OOM-Killer, w tym samym poleceniu podaj wartość 0:

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

Wynik tego polecenia nie zostanie zapisany na zawsze, ale tylko do pierwszego ponownego uruchomienia. Jeśli potrzebujesz większej trwałości, dodaj tę linię do pliku /etc/sysctl.conf:

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

Innym sposobem włączania i wyłączania jest napisanie zmiennej panic_on_oom. Wartość zawsze można sprawdzić /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Jeśli ustawisz wartość na 0, to gdy skończy się pamięć, nie będzie paniki jądra.

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

Jeśli ustawisz wartość na 1, gdy skończy się pamięć, nastąpi panika jądra.

echo 1 > /proc/sys/vm/panic_on_oom

Jak już wspomnieliśmy, OOM-Killera można włączać i wyłączać. Linux może zarezerwować dla procesów więcej pamięci, niż jest dostępne, ale nie może jej faktycznie przydzielić, a to zachowanie jest kontrolowane przez parametr jądra LinuxZa to odpowiada zmienna. vm.overcommit_memory.

Możesz określić dla niego następujące wartości:

0: Jądro samo decyduje, czy zarezerwować zbyt dużo pamięci. Jest to wartość domyślna w większości wersji. Linux.
1: Jądro zawsze rezerwuje dodatkową pamięć. Jest to ryzykowne, ponieważ może zabraknąć pamięci, bo najprawdopodobniej pewnego dnia procesy będą jej potrzebować.
2: jądro nie zarezerwuje więcej pamięci niż określono w parametrze overcommit_ratio.

Za pomocą tego parametru określa się procent pamięci, która może zostać nadmiernie zarezerwowana. Jeśli nie będzie na to miejsca, pamięć nie zostanie przydzielona, ​​a rezerwacja zostanie odrzucona. Jest to najbezpieczniejsza opcja zalecana dla PostgreSQL. Na OOM-Killer wpływa jeszcze jeden element – ​​możliwość zamiany, która jest kontrolowana przez zmienną cat /proc/sys/vm/swappiness. Wartości te mówią jądru, jak obsługiwać stronicowanie. Im wyższa wartość, tym mniejsze prawdopodobieństwo, że OOM zakończy proces, ale ze względu na operacje we/wy ma to negatywny wpływ na bazę danych. I odwrotnie – im niższa wartość, tym większe prawdopodobieństwo interwencji OOM-Killer, ale wydajność bazy danych też jest wyższa. Wartość domyślna to 60, ale jeśli cała baza danych mieści się w pamięci, lepiej ustawić wartość na 1.

Wyniki

Nie pozwól, aby „zabójca” w OOM-Killer Cię przestraszył. W tym przypadku zabójca będzie zbawicielem Twojego systemu. „Zabija” najgorsze procesy i chroni system przed awarią. Aby uniknąć konieczności używania OOM-Killer do zakończenia PostgreSQL, ustaw na vm.overcommit_memory wartość 2. Nie gwarantuje to, że OOM-Killer nie będzie musiał interweniować, ale zmniejszy prawdopodobieństwo wymuszenia zakończenia procesu PostgreSQL.

Źródło: www.habr.com

Kup niezawodny hosting dla stron z ochroną DDoS, serwery VPS VDS 🔥 Kup niezawodny hosting stron internetowych z ochroną DDoS, serwery VPS VDS | ProHoster