Iestatām Out-Of-Memory Killer Linux vidē PostgreSQL

Iestatām Out-Of-Memory Killer Linux vidē PostgreSQL

Kad Linux datu bāzes serveris negaidīti pārstāj darboties, ir jāatrod iemesls. Iemesli var būt vairāki. Piemēram, SIGSEGV — kļūda, kas radušās dēļ defekta backend serverī. Bet tas ir reti. Visbiežāk vienkārši beidzas vieta diskā vai atmiņā. Ja beigusies vieta diskā, vienīgā izeja ir atbrīvot vietu un restartēt datu bāzi.

Out-Of-Memory Killer

Kad serveris vai procesa atmiņa beidzas, Linux piedāvā divus risinājumus: sabrukt visai sistēmai vai pabeigt procesu (lietojumprogrammu), kas patērē atmiņu. Labāk, protams, ir pabeigt procesu un saglabāt OS no avārijas. Īsumā, Out-Of-Memory Killer ir process, kas aptur lietojumprogrammu, lai glābtu kodolu no kļūmes. Viņš upurē lietojumprogrammu, lai saglabātu OS darbību. Vispirms apspriedīsim, kā darbojas OOM un kā to kontrolēt, bet pēc tam aplūkosim, kā OOM Killer nosaka, kuru lietojumprogrammu pabeigt.

Viena no galvenajām Linux uzdevumiem ir piešķirt atmiņu procesiem, kad tie to pieprasa. Parasti process vai lietojumprogramma pieprasa no OS atmiņu, bet paši to neizmanto pilnībā. Ja OS piešķirs atmiņu visiem, kas to pieprasa, bet neplāno izmantot, ļoti ātri atmiņa beigsies, un sistēma atsakās. Lai to novērstu, OS rezerves atmiņu procesam, bet faktiski to neizsniedz. Atmiņa tiek piešķirta tikai tad, kad process patiešām plāno to izmantot. Dažreiz OS nav brīvas atmiņas, bet tā rezerves atmiņu procesam, un kad atmiņa nepieciešama, OS to piešķir, ja var. Mīnuss ir tas, ka dažreiz OS rezerves atmiņu, bet nepieciešamajā brīdī brīvas atmiņas nav, un notiek sistēmas sabrukums. OOM spēlē svarīgu lomu šajā scenārijā un pabeidz procesus, lai pasargātu kodolu no panikas. Kad PostgreSQL process tiek piespiedu kārtā pabeigts, žurnālā parādās ziņojums:

Out of Memory: Killed process 12345 (postgres).

Ja sistēmā ir maz atmiņas un atbrīvot to nav iespējams, tiek izsaukta funkcija out_of_memory. Šajā posmā tai atliek tikai viens – pabeigt vienu vai vairākus procesus. Vai OOM-killeram vajadzētu uzreiz pārtraukt procesu, vai var gaidīt? Acīmredzot, kad tiek izsaukts out_of_memory, tas ir saistīts ar I/O operācijas vai lapas ielādēšanu diskā gaidīšanu. Tāpēc OOM-killeram jāveic pārbaudes un, pamatojoties uz tām, jāizlemj, kuru procesu beigt. Ja visi zemāk minētie pārbaudes rezultāti būs pozitīvi, OOM pārtrauks procesu.

Procesa izvēle

Kad beidzas atmiņa, tiek izsaukta funkcija out_of_memory(). Tajā ir funkcija select_bad_process(), kas saņem novērtējumu no funkcijas badness(). Tiks izvēlēts vissliktākais process. Funkcija badness() izvēlas procesu pēc noteiktiem kritērijiem.

  1. Kodam ir nepieciešama kāda minimāla atmiņas daļa sev.
  2. Jāatbrīvo liela daļa atmiņas.
  3. Nav jābeidz procesi, kas izmanto maz atmiņas.
  4. Nepieciešams pārtraukt vismaz dažus procesus.
  5. Sarežģīti algoritmi, kas palielina iespējas, ka tiks pārtraukti tie procesi, kurus lietotājs vēlas pārtraukt pats.

Pabeidzot visas šīs pārbaudes, OOM pārskata novērtējumu (oom_score). OOM piešķir oom_score katram procesam, un tad reizina šo vērtību ar atmiņas apjomu. Procesiem ar augstākām vērtībām ir lielākas iespējas kļūt par OOM Killer upuriem. Procesi, kas saistīti ar privileģētu lietotāju, saņem zemāku novērtējumu un mazāk iespēju tikt pārtraukti.

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

Postgres procesa identifikators ir 3813, tādēļ citā terminālī var iegūt novērtējumu, izmantojot šo kodu parametru oom_score:

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

Ja jūs pilnībā nevēlaties, lai OOM-Killer pārtrauktu procesu, ir vēl viens kodu parameters: oom_score_adj. Pievienojiet lielu negatīvu vērtību, lai samazinātu iespējas, ka tiks pārtraukts processes, kas jums ir dārgs.

sudo echo -100 > /proc/3813/oom_score_adj

Lai iestatītu vērtību oom_score_adj, iestatiet OOMScoreAdjust pakalpojuma blokā:

[Service]
OOMScoreAdjust=-1000

Vai izmantojiet oomprotect komandā rcctl.

rcctl set servicename oomprotect -1000

Piespiedu procesa pārtraukšana

Kad viens vai vairāki procesi jau ir izvēlēti, OOM-Killer izsauc funkciju oom_kill_task(). Šī funkcija nosūta procesam signālu par pārtraukšanu. Gadījumā, ja nav pietiekami daudz atmiņas oom_kill() izsauc šo funkciju, lai nosūtītu procesam SIGKILL signālu. Logā tiks ierakstīta ziņa.

Atmiņa beigusies: process [pid] [name] ir izdzēsts.

Kā kontrolēt OOM-Killer

Linux var aktivizēt un deaktivat OOM-Killer (lai gan pēdējais nav ieteicams). Lai aktivizētu vai deaktivat, izmantojiet parametru vm.oom-kill. Lai aktivizētu OOM-Killer izpildes vidē, izpildiet komandu sysctl.

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

Lai deaktīvēt OOM-Killer, norādiet vērtību 0 šajā pašā komandā:

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

Šīs komandas rezultāts netiks saglabāts uz visiem laikiem, bet tikai līdz pirmajai restartēšanai. Ja nepieciešama ilgstošāka saglabāšana, pievienojiet šo rindu failam /etc/sysctl.conf:

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

Vēl viens veids, kā aktivizēt un deaktivat - uzrakstīt mainīgo panic_on_oom. Vērtību vienmēr var pārbaudīt /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Ja vērtība ir 0, tad, kad beigsies atmiņa, kernel panic nenotiks.

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

Ja vērtība ir 1, tad, kad beigsies atmiņa, notiks kernel panic.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer var ne tikai aktivizēt vai deaktivat. Mēs jau runājām, ka Linux var rezervēt procesiem vairāk atmiņas, nekā ir pieejama, bet faktiski to nenodrošina, un šo uzvedību kontrolē Linux kodola parametrs. Par to atbild mainīgais vm.overcommit_memory.

Tam var norādīt sekojošas vērtības:

0: kodols pats nolēma, vai rezervēt pārāk daudz atmiņas. Šī ir noklusējuma vērtība lielākajā daļā Linux versiju.
1: kodols vienmēr rezervēs lieko atmiņu. Tas ir riskanti, jo atmiņa var beigties, jo, visticamāk, kādu brīdi procesi pieprasīs paredzēto.
2: kodols nevarēs rezervēt vairāk atmiņas, nekā norādītu parametru overcommit_ratio.

Šajā parametrā jūs norādāt atmiņas procentuālo daļu, kurai ir pieļaujama pārmērīga rezervācija. Ja tam nav vietas, atmiņa netiks nodrošināta, un rezervācijai tiks atteikts. Šis ir visdrošākais variants, kas ieteicams PostgreSQL. OOM-Killer ietekmē vēl viens elements — iespēja izmantot uzlādes atmiņu, ko kontrolē mainīgais cat /proc/sys/vm/swappiness. Šie vērtības norāda kodolam, kā apstrādāt lapu apmaiņu. Jo lielāka ir vērtība, jo mazāk ir iespējas, ka OOM izbeigs procesu, taču diskdarījumu dēļ tas negatīvi ietekmē datu bāzi. Un, otrādi — jo mazāka ir vērtība, jo lielāka varbūtība, ka ies intervention OOM-Killer, bet datu bāzes veiktspēja ir augstāka. Noklusējuma vērtība ir 60, taču, ja visa datu bāze ietilpst atmiņā, labāk iestatīt vērtību 1.

Secinājumi

Neraugieties uz «killer» OOM-Killer vārdā ar bailēm. Šajā gadījumā killer ir jūsu sistēmas glābējs. Tas «nogalina» visus nevēlamos procesus un glābj sistēmu no avārijas izbeigšanas. Lai OOM-Killer nevajadzētu izmantot PostgreSQL izbeigšanai, iestatiet vm.overcommit_memory vērtību 2. Tas negarantē, ka OOM-Killer nebūs jāiejaucas, taču samazinās varbūtību, ka PostgreSQL process tiks piespiedu kārtā izbeigts.

Avots: habr.com

Iegādājieties uzticamu tīmekļa hostingu ar DDoS aizsardzību, VPS VDS serveriem 🔥 Iegādājieties uzticamu tīmekļa hostingu ar DDoS aizsardzību, VPS VDS serveriem | ProHoster