Konfigurimi i vrasës jashtë memorjes në Linux për PostgreSQL

Konfigurimi i vrasës jashtë memorjes në Linux për PostgreSQL

Kur një server i bazës së të dhënave mbyllet papritur në Linux, ju duhet të gjeni arsyen. Mund të ketë disa arsye. Për shembull, SIGSEGV — dështimi për shkak të një gabimi në serverin mbështetës. Por kjo është e rrallë. Më shpesh, thjesht ju mbaron hapësira në disk ose memorie. Nëse ju mbaron hapësira në disk, ka vetëm një rrugëdalje - lironi hapësirën dhe rinisni bazën e të dhënave.

Vrasës jashtë kujtesës

Kur një server ose procesi i mbaron memoria, Linux ofron 2 zgjidhje: prishjen e të gjithë sistemit ose ndërprerjen e procesit (aplikacionit) që po ha memorie. Është më mirë, natyrisht, të përfundoni procesin dhe të ruani OS nga përplasja. Me pak fjalë, Out-Of-Memory Killer është një proces që vret një aplikacion për të shpëtuar kernelin nga përplasja. Ai sakrifikon aplikacionin për të mbajtur funksionimin e sistemit operativ. Le të diskutojmë fillimisht se si funksionon OOM dhe si ta kontrollojmë atë, dhe më pas të shohim se si OOM Killer vendos se cilin aplikacion të përfundojë.

Një nga detyrat kryesore të Linux-it është të ndajë memorie për proceset kur ata e kërkojnë atë. Në mënyrë tipike, një proces ose aplikacion kërkon memorie nga OS, por nuk e përdor plotësisht atë. Nëse sistemi operativ i jep memorie kujtdo që e kërkon por nuk ka plane ta përdorë, shumë shpejt memoria do të mbarojë dhe sistemi do të dështojë. Për të shmangur këtë, OS rezervon memorie për procesin, por në fakt nuk e lëshon atë. Kujtesa shpërndahet vetëm kur një proces do ta përdorë atë. Ndodh që OS nuk ka memorie të lirë, por i cakton memorie një procesi dhe kur një procesi i nevojitet, OS e shpërndan nëse mundet. E keqja është se ndonjëherë OS rezervon memorie, por në kohën e duhur nuk ka memorie të lirë dhe sistemi rrëzohet. OOM luan një rol të rëndësishëm në këtë skenar dhe përfundon proceset për të parandaluar panikimin e kernelit. Kur një proces PostgreSQL detyrohet të përfundojë, një mesazh shfaqet në regjistër:

Out of Memory: Killed process 12345 (postgres).

Nëse sistemi ka memorie të ulët dhe nuk mund të lirohet, thirret funksioni out_of_memory. Në këtë fazë, asaj i mbetet vetëm një gjë për të bërë - të përfundojë një ose më shumë procese. A duhet që OOM-vrasësi ta përfundojë procesin menjëherë apo mund të presë? Natyrisht, kur thirret out_of_memory, është për shkak të pritjes për një operacion I/O ose paging në disk. Prandaj, vrasësi i OOM duhet së pari të kryejë kontrolle dhe, në bazë të tyre, të vendosë që procesi duhet të përfundojë. Nëse të gjitha kontrollet e mëposhtme janë pozitive, OOM do të përfundojë procesin.

Zgjedhja e procesit

Kur kujtesa mbaron, funksioni thirret out_of_memory(). Ka një funksion select_bad_process(), e cila merr një vlerësim nga funksioni badness(). Procesi "më i keq" do të jetë në shënjestër. Funksioni badness() zgjedh një proces sipas rregullave të caktuara.

  1. Kerneli ka nevojë për një memorie minimale për vete.
  2. Ju duhet të lironi shumë memorie.
  3. Nuk ka nevojë të përfundoni proceset që përdorin pak memorie.
  4. Proceset minimale duhet të kryhen.
  5. Algoritme komplekse që rrisin shanset e përfundimit për ato procese që vetë përdoruesi dëshiron të përfundojë.

Pasi ka përfunduar të gjitha këto kontrolle, OOM shqyrton rezultatin (oom_score). OOM emëron oom_score çdo proces, dhe më pas e shumëzon këtë vlerë me sasinë e memories. Proceset me vlera më të mëdha kanë më shumë gjasa të bien viktimë e Vrasësit të OOM. Proceset e lidhura me përdoruesin rrënjë kanë një rezultat më të ulët dhe kanë më pak gjasa të detyrohen të përfundojnë.

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

ID-ja e procesit Postgres është 3813, kështu që në një predhë tjetër është e mundur të merret rezultati duke përdorur këtë parametër kernel oom_score:

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

Nëse nuk dëshironi që OOM-Killer të vrasë fare procesin, ekziston një opsion tjetër i kernelit: oom_score_adj. Shtoni një vlerë të madhe negative për të zvogëluar shanset për të përfunduar një proces që vlerësoni.

sudo echo -100 > /proc/3813/oom_score_adj

Për të vendosur një vlerë oom_score_adj, vendosni OOMScoreAdjust në bllokun e shërbimit:

[Service]
OOMScoreAdjust=-1000

Ose përdorni oomprotect në një ekip rcctl.

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

Përfundimi me forcë i një procesi

Kur një ose më shumë procese janë zgjedhur tashmë, OOM-Killer thërret funksionin oom_kill_task(). Ky funksion i dërgon procesit një sinjal përfundimi. Në rast të mungesës së memories oom_kill() E thërret këtë funksion për të dërguar një sinjal SIGKILL në proces. Një mesazh është shkruar në regjistrin e kernelit.

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

Si të kontrolloni OOM-Killer

Në Linux, mund të aktivizoni ose çaktivizoni OOM-Killer (edhe pse kjo e fundit nuk rekomandohet). Për të aktivizuar ose çaktivizuar, përdorni parametrin vm.oom-kill. Për të aktivizuar OOM-Killer në kohën e ekzekutimit, ekzekutoni komandën sysctl.

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

Për të çaktivizuar OOM-Killer, specifikoni vlerën 0 në të njëjtën komandë:

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

Rezultati i kësaj komande nuk do të ruhet përgjithmonë, por vetëm deri në rindezjen e parë. Nëse keni nevojë për më shumë këmbëngulje, shtoni këtë rresht në skedar /etc/sysctl.conf:

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

Një mënyrë tjetër për të aktivizuar dhe çaktivizuar është të shkruani një ndryshore panic_on_oom. Vlera mund të kontrollohet gjithmonë /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Nëse e vendosni vlerën në 0, atëherë kur kujtesa të mbarojë, nuk do të ketë panik të kernelit.

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

Nëse e vendosni vlerën në 1, atëherë kur kujtesa të mbarojë, do të ndodhë një panik kernel.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer jo vetëm që mund të ndizet dhe fiket. Ne kemi thënë tashmë se Linux mund të rezervojë më shumë memorie për proceset sesa është e disponueshme pa e ndarë atë në të vërtetë dhe kjo sjellje kontrollohet nga një parametër i kernelit Linux. Variabla është përgjegjëse për këtë vm.overcommit_memory.

Ju mund të specifikoni vlerat e mëposhtme për të:

0: Vetë kerneli vendos nëse do të rezervojë shumë memorie. Ky është parazgjedhja në shumicën e versioneve të Linux.
1: Kerneli do të rezervojë gjithmonë memorie shtesë. Kjo është e rrezikshme, sepse kujtesa mund të mbarojë, sepse, me shumë mundësi, një ditë proceset do ta kërkojnë atë.
2: kerneli nuk do të rezervojë më shumë memorie sesa është specifikuar në parametër overcommit_ratio.

Me këtë parametër, ju specifikoni përqindjen e memories që lejohet të mbi-rezervohet. Nëse nuk ka vend për të, nuk ndahet memorie dhe rezervimi do të refuzohet. Ky është opsioni më i sigurt i rekomanduar për PostgreSQL. OOM-Killer ndikohet nga një element tjetër - aftësia e shkëmbimit, e cila kontrollohet nga ndryshorja cat /proc/sys/vm/swappiness. Këto vlera i tregojnë kernelit se si të trajtojë paging. Sa më e lartë të jetë vlera, aq më pak ka gjasa që OOM të përfundojë procesin, por për shkak të operacioneve I/O ka një ndikim negativ në bazën e të dhënave. Dhe anasjelltas - sa më e ulët të jetë vlera, aq më e lartë është gjasat e ndërhyrjes OOM-Killer, por performanca e bazës së të dhënave është gjithashtu më e lartë. Vlera e paracaktuar është 60, por nëse e gjithë baza e të dhënave përshtatet në memorie, është më mirë të vendosni vlerën në 1.

Rezultatet e

Mos lejoni që "vrasësi" në OOM-Killer t'ju trembë. Në këtë rast, vrasësi do të jetë shpëtimtari i sistemit tuaj. Ai "vras" proceset më të këqija dhe e shpëton sistemin nga përplasja. Për të shmangur nevojën për të përdorur OOM-Killer për të përfunduar PostgreSQL, vendosni në vm.overcommit_memory vlera 2. Kjo nuk garanton që OOM-Killer nuk do të duhet të ndërhyjë, por do të zvogëlojë gjasat për të detyruar procesin e PostgreSQL të përfundojë.

Burimi: www.habr.com

Shto një koment