Postavljanje alata za uklanjanje nestašice memorije u Linux za PostgreSQL

Postavljanje alata za uklanjanje nestašice memorije u Linux za PostgreSQL

Kad u Linux Poslužitelj baze podataka neočekivano se prekida i potrebno je utvrditi uzrok. Može postojati nekoliko razloga. Na primjer, SIGSEGV — kvar zbog greške u pozadinskom poslužitelju. Ali ovo je rijetkost. Najčešće jednostavno ostanete bez prostora na disku ili memorije. Ako vam ponestane prostora na disku, postoji samo jedan izlaz - oslobodite prostor i ponovno pokrenite bazu podataka.

Ubojica bez pamćenja

Kada ti poslužitelja ili procesu ponestane memorije, Linux Ubojica zbog nedostatka memorije nudi dva rješenja: rušenje cijelog sustava ili prekid procesa (aplikacije) koji troši memoriju. Naravno, bolje je prekinuti proces i spasiti OS od rušenja. Ukratko, Ubojica zbog nedostatka memorije je proces koji prekida aplikaciju kako bi spasio kernel od rušenja. Žrtvuje aplikaciju kako bi OS nastavio raditi. Prvo ćemo razgovarati o tome kako OOM radi i kako ga kontrolirati, a zatim ćemo pogledati kako OOM Killer odlučuje koje aplikacije će prekinuti.

Jedan od glavnih zadataka Linux — Dodijelite memoriju procesima kada je zatraže. Tipično, proces ili aplikacija traži memoriju od OS-a, ali je ne koristi u potpunosti. Ako OS dodijeli memoriju svima koji je zatraže, ali je ne planiraju koristiti, sustav će brzo ostati bez memorije i sustav će se srušiti. Kako bi se to spriječilo, OS rezervira memoriju za proces, ali je zapravo ne dodjeljuje. Memorija se dodjeljuje samo kada proces zapravo namjerava koristiti je. Ponekad OS nema slobodne memorije, ali dodjeljuje memoriju procesu, a kada je procesu potrebna, OS je dodjeljuje ako može. Nedostatak je što OS ponekad rezervira memoriju, ali kada je potrebna, nema slobodne memorije, što uzrokuje pad sustava. OOM igra ključnu ulogu u ovom scenariju, prekidajući procese kako bi se spriječila panika kernela. Kada se PostgreSQL proces prisilno prekine, u zapisniku se pojavljuje sljedeća poruka:

Out of Memory: Killed process 12345 (postgres).

Ako sustavu nedostaje memorije i ne može se osloboditi, poziva se funkcija out_of_memory. U ovoj fazi joj preostaje samo jedno - završiti jedan ili više procesa. Treba li OOM-killer odmah prekinuti proces ili može pričekati? Očito, kada se pozove out_of_memory, to je zbog čekanja I/O operacije ili straničenja na disk. Stoga OOM ubojica prvo mora izvršiti provjere i na temelju njih odlučiti da je proces potrebno prekinuti. Ako su sve provjere u nastavku pozitivne, OOM će prekinuti proces.

Izbor procesa

Kada ponestane memorije, poziva se funkcija out_of_memory(). Ima funkciju select_bad_process(), koji dobiva ocjenu od funkcije badness(). Ciljat će se "najgori" proces. Funkcija badness() odabire proces prema određenim pravilima.

  1. Kernel treba minimalnu memoriju za sebe.
  2. Morate osloboditi puno memorije.
  3. Nema potrebe prekidati procese koji koriste malo memorije.
  4. Potrebno je dovršiti minimalne procese.
  5. Složeni algoritmi koji povećavaju šanse za dovršetak za one procese koje sam korisnik želi dovršiti.

Nakon završetka svih ovih provjera, OOM ispituje rezultat (oom_score). OOM imenuje oom_score svaki proces, a zatim množi ovu vrijednost s količinom memorije. Veća je vjerojatnost da će procesi s većim vrijednostima postati žrtve OOM Killera. Procesi povezani s root korisnikom imaju niži rezultat i manja je vjerojatnost da će biti prisiljeni prekinuti.

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

ID Postgres procesa je 3813, tako da je u drugoj ljusci moguće dobiti rezultat pomoću ovog parametra jezgre oom_score:

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

Ako ne želite da OOM-Killer uopće prekine proces, postoji još jedna opcija kernela: oom_score_adj. Dodajte veliku negativnu vrijednost kako biste smanjili šanse za dovršetak procesa koji cijenite.

sudo echo -100 > /proc/3813/oom_score_adj

Za postavljanje vrijednosti oom_score_adj, postavite OOMScoreAdjust u servisnom bloku:

[Service]
OOMScoreAdjust=-1000

Ili koristiti oomprotect u timu rcctl.

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

Prisilno prekidanje procesa

Kada je jedan ili više procesa već odabrano, OOM-Killer poziva funkciju oom_kill_task(). Ova funkcija šalje procesu prekidni signal. U slučaju nedostatka memorije oom_kill() Poziva ovu funkciju da pošalje SIGKILL signal procesu. Poruka se upisuje u dnevnik kernela.

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

Kako kontrolirati OOM-Killer

В Linux OOM-Killer možete omogućiti ili onemogućiti (iako se ovo drugo ne preporučuje). Da biste ga omogućili ili onemogućili, upotrijebite parametar vm.oom-kill. Da biste omogućili OOM-Killer tijekom izvođenja, pokrenite naredbu sysctl.

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

Da biste onemogućili OOM-Killer, navedite vrijednost 0 u istoj naredbi:

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

Rezultat ove naredbe neće biti spremljen zauvijek, već samo do prvog ponovnog pokretanja. Ako trebate više upornosti, dodajte ovaj redak u datoteku /etc/sysctl.conf:

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

Drugi način omogućavanja i onemogućavanja je pisanje varijable panic_on_oom. Vrijednost se uvijek može provjeriti /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Ako postavite vrijednost na 0, tada kada ponestane memorije, neće biti panike u kernelu.

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

Ako postavite vrijednost na 1, kada ponestane memorije, pojavit će se panika kernela.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer se može uključiti i isključiti, kao što smo već spomenuli. Linux može rezervirati više memorije za procese nego što je dostupno, ali je zapravo neće dodijeliti, a to ponašanje kontrolira parametar kernela LinuxVarijabla je odgovorna za to. vm.overcommit_memory.

Za njega možete odrediti sljedeće vrijednosti:

0: Sama jezgra odlučuje hoće li rezervirati previše memorije. To je zadana vrijednost u većini verzija. Linux.
1: Kernel će uvijek rezervirati dodatnu memoriju. To je riskantno, jer memorija može ponestati, jer, najvjerojatnije, jednog dana će to procesi zahtijevati.
2: kernel neće rezervirati više memorije nego što je navedeno u parametru overcommit_ratio.

Pomoću ovog parametra određujete postotak memorije koji je dopušteno prerezervirati. Ako za to nema mjesta, memorija se ne dodjeljuje i rezervacija će biti odbijena. Ovo je najsigurnija opcija preporučena za PostgreSQL. Na OOM-Killer utječe još jedan element - mogućnost zamjene, koja je kontrolirana varijablom cat /proc/sys/vm/swappiness. Ove vrijednosti govore kernelu kako da rukuje straničenjem. Što je viša vrijednost, manja je vjerojatnost da će OOM prekinuti proces, ali zbog I/O operacija to ima negativan utjecaj na bazu podataka. I obrnuto - što je niža vrijednost, veća je vjerojatnost intervencije OOM-Killera, ali je i izvedba baze podataka veća. Zadana vrijednost je 60, ali ako cijela baza podataka stane u memoriju, bolje je postaviti vrijednost na 1.

Rezultati

Ne dopustite da vas "ubojica" u OOM-Killeru prestraši. U ovom slučaju, ubojica će biti spasitelj vašeg sustava. “Ubija” najgore procese i spašava sustav od pada. Kako biste izbjegli korištenje OOM-Killer-a za prekid PostgreSQL-a, postavite na vm.overcommit_memory vrijednost 2. Ovo ne jamči da OOM-Killer neće morati intervenirati, ali će smanjiti vjerojatnost prisilnog prekida PostgreSQL procesa.

Izvor: www.habr.com

Kupite pouzdan hosting za stranice s DDoS zaštitom, VPS VDS poslužiteljima 🔥 Kupite pouzdan web hosting sa DDoS zaštitom, VPS VDS servere | ProHoster