Agordo de Out-Of-Memory Killer en Linukso por PostgreSQL

Agordo de Out-Of-Memory Killer en Linukso por PostgreSQL

Kiam datumbaza servilo ĉesas neatendite en Linukso, vi devas trovi la kialon. Povas esti pluraj kialoj. Ekzemple, SIGSEGV — malsukceso pro cimo en la malantaŭa servilo. Sed ĉi tio estas malofta. Plej ofte, vi simple elĉerpas diskospacon aŭ memoron. Se vi elĉerpas diskon, ekzistas nur unu elirejo - liberigu spacon kaj rekomencu la datumbazon.

Murdinto-El-Memoria

Kiam servilo aŭ procezo elĉerpigas memoron, Linukso ofertas 2 solvojn: kraŝi la tutan sistemon aŭ ĉesigi la procezon (aplikaĵon) kiu manĝas memoron. Estas pli bone, kompreneble, ĉesigi la procezon kaj savi la OS de kraŝo. En resumo, Out-Of-Memory Killer estas procezo kiu mortigas aplikaĵon por savi la kernon de kraŝo. Ĝi oferas la aplikaĵon por ke la OS funkcias. Ni unue diskutu kiel OOM funkcias kaj kiel kontroli ĝin, kaj poste vidu kiel OOM Killer decidas kiun aplikaĵon ĉesigi.

Unu el la ĉefaj taskoj de Linukso estas asigni memoron al procezoj kiam ili petas ĝin. Tipe, procezo aŭ aplikaĵo petas memoron de la OS, sed ne plene uzas ĝin. Se la OS donas memoron al ĉiuj, kiuj petas ĝin, sed ne planas uzi ĝin, tre baldaŭ la memoro elĉerpiĝos kaj la sistemo malsukcesos. Por eviti tion, la OS rezervas memoron por la procezo, sed ne efektive liberigas ĝin. Memoro estas asignita nur kiam procezo efektive uzos ĝin. Okazas, ke la OS ne havas liberan memoron, sed ĝi asignas memoron al procezo, kaj kiam procezo bezonas ĝin, la OS asignas ĝin se ĝi povas. La malavantaĝo estas, ke foje la OS rezervas memoron, sed en la ĝusta tempo mankas libera memoro, kaj la sistemo kraŝas. OOM ludas gravan rolon en ĉi tiu scenaro kaj finas procezojn por malhelpi la kernon panikiĝi. Kiam PostgreSQL-procezo estas devigita finiĝi, mesaĝo aperas en la protokolo:

Out of Memory: Killed process 12345 (postgres).

Se la sistemo estas malmulte da memoro kaj ĝi ne povas esti liberigita, la funkcio estas vokita out_of_memory. En ĉi tiu etapo, ŝi havas nur unu aferon por fari - plenumi unu aŭ plurajn procezojn. Ĉu OOM-murdinto devas tuj ĉesigi la procezon aŭ ĉu ĝi povas atendi? Evidente, kiam out_of_memory estas vokita, ĝi estas pro atendado de I/O operacio aŭ paĝigo al disko. Tial, la OOM-murdinto unue devas fari kontrolojn kaj, surbaze de ili, decidi, ke la procezo devas esti ĉesigita. Se ĉiuj ĉekoj sube estas pozitivaj, OOM finos la procezon.

Proceza elekto

Kiam memoro elĉerpiĝas, la funkcio estas vokita out_of_memory(). Ĝi havas funkcion select_bad_process(), kiu ricevas taksadon de la funkcio badness(). La "plej malbona" ​​procezo estos celita. Funkcio badness() elektas procezon laŭ certaj reguloj.

  1. La kerno bezonas iom da minimuma memoro por si mem.
  2. Vi devas liberigi multe da memoro.
  3. Ne necesas ĉesigi procezojn, kiuj uzas malmulte da memoro.
  4. Minimumaj procezoj devas esti kompletigitaj.
  5. Kompleksaj algoritmoj, kiuj pliigas la eblecojn de kompletigo por tiuj procezoj, kiujn la uzanto mem volas plenumi.

Fininte ĉiujn ĉi tiujn kontrolojn, OOM ekzamenas la poentaron (oom_score). OOM asignas oom_score ĉiu procezo, kaj tiam multobligas ĉi tiun valoron per la kvanto de memoro. Procezoj kun pli grandaj valoroj pli verŝajne estos viktimoj de la OOM Killer. Procezoj asociitaj kun la radika uzanto havas pli malaltan poentaron kaj estas malpli verŝajne devigitaj fini.

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

La Postgres-proceza ID estas 3813, do en alia ŝelo eblas akiri la poentaron uzante ĉi tiun kernan parametron oom_score:

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

Se vi tute ne volas, ke OOM-Killer ĉesigu la procezon, ekzistas alia kerna opcio: oom_score_adj. Aldonu grandan negativan valoron por redukti la ŝancojn kompletigi procezon, kiun vi taksas.

sudo echo -100 > /proc/3813/oom_score_adj

Por agordi valoron oom_score_adj, agordu OOMScoreAdjust en la servobloko:

[Service]
OOMScoreAdjust=-1000

Aŭ uzi oomprotect en teamo rcctl.

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

Forto ĉesigo de procezo

Kiam unu aŭ pluraj procezoj jam estas elektitaj, OOM-Killer vokas la funkcion oom_kill_task(). Ĉi tiu funkcio sendas finsignalon al la procezo. En kazo de manko de memoro oom_kill() Vokas ĉi tiun funkcion por sendi SIGKILL-signalon al la procezo. Mesaĝo estas skribita al la kerno-protokolo.

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

Kiel kontroli OOM-Killer

En Linukso, vi povas aktivigi aŭ malŝalti OOM-Killer (kvankam ĉi-lasta ne rekomendas). Por aktivigi aŭ malŝalti uzu la parametron vm.oom-kill. Por ebligi OOM-Killer ĉe rultempo, rulu la komandon sysctl.

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

Por malŝalti OOM-Killer, specifu la valoron 0 en la sama komando:

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

La rezulto de ĉi tiu komando ne estos konservita por ĉiam, sed nur ĝis la unua rekomenco. Se vi bezonas pli da persisto, aldonu ĉi tiun linion al la dosiero /etc/sysctl.conf:

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

Alia maniero por ebligi kaj malŝalti estas skribi variablon panic_on_oom. La valoro ĉiam povas esti kontrolita /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Se vi fiksas la valoron al 0, tiam kiam la memoro elĉerpiĝos, ne estos kerna paniko.

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

Se vi fiksas la valoron al 1, tiam kiam la memoro elĉerpiĝos, kerna paniko okazos.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer ne nur povas esti ŝaltita kaj malŝaltita. Ni jam diris, ke Linukso povas rezervi pli da memoro por procezoj ol estas disponebla sen efektive asigni ĝin, kaj ĉi tiu konduto estas regata de parametro de Linukso-kerno. La variablo respondecas pri tio vm.overcommit_memory.

Vi povas specifi la sekvajn valorojn por ĝi:

0: La kerno mem decidas ĉu rezervi tro da memoro. Ĉi tio estas la defaŭlta ĉe plej multaj versioj de Linukso.
1: La kerno ĉiam rezervos kroman memoron. Ĉi tio estas riska, ĉar la memoro eble elĉerpiĝas, ĉar, plej verŝajne, iam la procezoj postulos ĝin.
2: la kerno ne rezervos pli da memoro ol specifita en la parametro overcommit_ratio.

Kun ĉi tiu parametro, vi specifas la procenton de memoro kiu rajtas esti trorezervita. Se ne estas loko por ĝi, neniu memoro estas asignita, kaj la rezervado estos rifuzita. Ĉi tiu estas la plej sekura opcio rekomendita por PostgreSQL. OOM-Killer estas tuŝita de alia elemento - la interŝanĝa kapablo, kiu estas regata de la variablo cat /proc/sys/vm/swappiness. Ĉi tiuj valoroj diras al la kerno kiel trakti paĝigon. Ju pli alta la valoro, des malpli verŝajne estas, ke OOM finos la procezon, sed pro I/O-operacioj ĝi havas negativan efikon al la datumbazo. Kaj inverse - ju pli malalta la valoro, des pli alta la probableco de interveno de OOM-Killer, sed la rendimento de la datumbazo ankaŭ estas pli alta. La defaŭlta valoro estas 60, sed se la tuta datumbazo taŭgas en memoro, estas pli bone agordi la valoron al 1.

Rezultoj

Ne lasu la "murdinton" en OOM-Killer timigi vin. En ĉi tiu kazo, la murdinto estos la savanto de via sistemo. Ĝi "mortigas" la plej malbonajn procezojn kaj savas la sistemon de kraŝo. Por eviti devi uzi OOM-Killer por ĉesigi PostgreSQL, agordu al vm.overcommit_memory valoro 2. Ĉi tio ne garantias, ke OOM-Killer ne devos interveni, sed ĝi reduktos la verŝajnecon devigi la PostgreSQL-procezon finiĝi.

fonto: www.habr.com

Aldoni komenton