
Kiam en Linux La datumbaza servilo neatendite ĉesas funkcii, kaj la kaŭzo devas esti determinita. Povus 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 vi servilo aŭ la procezo elĉerpas memoron, Linux La Memor-Mortiganto proponas du solvojn: kraŝigi la tutan sistemon aŭ ĉesigi la procezon (aplikaĵon), kiu konsumas memoron. Kompreneble, estas pli bone ĉesigi la procezon kaj savi la operaciumon de kraŝo. Mallonge, la Memor-Mortiganto estas procezo, kiu ĉesigas aplikaĵon por savi la kernon de kraŝo. Ĝi oferas la aplikaĵon por plu funkcii la operaciumon. Ni unue diskutu kiel Memor-Mortiganto funkcias kaj kiel kontroli ĝin, kaj poste rigardu kiel la Memor-Mortiganto decidas, kiujn aplikaĵojn ĉesigi.
Unu el la ĉefaj taskoj Linux — Asignu memoron al procezoj kiam ili petas ĝin. Tipe, procezo aŭ aplikaĵo petas memoron de la operaciumo sed ne uzas ĝin tute. Se la operaciumo asignas memoron al ĉiu, kiu petas ĝin sed ne planas uzi ĝin, la sistemo rapide elĉerpos memoron, kaj la sistemo kraŝos. Por malhelpi tion, la operaciumo rezervas memoron por procezo sed fakte ne asignas ĝin. Memoro estas asignita nur kiam procezo fakte intencas uzi ĝin. Foje la operaciumo ne havas liberan memoron, sed ĝi asignas memoron al procezo, kaj kiam la procezo bezonas ĝin, la operaciumo asignas ĝin se ĝi povas. La malavantaĝo estas, ke foje la operaciumo rezervas memoron, sed kiam necese, ne estas libera memoro, kaŭzante sistemkraŝon. OOM ludas ŝlosilan rolon en ĉi tiu scenaro, finante procezojn por malhelpi la kernon panikiĝi. Kiam la PostgreSQL-procezo estas perforte finita, la jena 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.
- La kerno bezonas iom da minimuma memoro por si mem.
- Vi devas liberigi multe da memoro.
- Ne necesas ĉesigi procezojn, kiuj uzas malmulte da memoro.
- Minimumaj procezoj devas esti kompletigitaj.
- 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
2Se 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_adjPor agordi valoron oom_score_adj, agordu OOMScoreAdjust en la servobloko:
[Service]
OOMScoreAdjust=-1000Aŭ uzi oomprotect en teamo rcctl.
rcctl set <i>servicename</i> oomprotect -1000Forto ĉ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
В Linux Vi povas ebligi aŭ malebligi OOM-Killer (kvankam ĉi-lasta ne estas rekomendinda). Por ebligi aŭ malebligi ĝin, uzu la parametron vm.oom-kill. Por ebligi OOM-Killer ĉe rultempo, rulu la komandon sysctl.
sudo -s sysctl -w vm.oom-kill = 1Por malŝalti OOM-Killer, specifu la valoron 0 en la sama komando:
sudo -s sysctl -w vm.oom-kill = 0La 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.confAlia 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
0Se vi fiksas la valoron al 0, tiam kiam la memoro elĉerpiĝos, ne estos kerna paniko.
$ echo 0 > /proc/sys/vm/panic_on_oomSe vi fiksas la valoron al 1, tiam kiam la memoro elĉerpiĝos, kerna paniko okazos.
echo 1 > /proc/sys/vm/panic_on_oomOOM-Killer povas esti ŝaltita kaj malŝaltita, kiel ni jam menciis. Linux povas rezervi pli da memoro por procezoj ol haveblas, sed ne fakte asigni ĝin, kaj ĉi tiu konduto estas kontrolata per kerna parametro LinuxLa variablo respondecas pri tio. vm.overcommit_memory.
Vi povas specifi la sekvajn valorojn por ĝi:
0: La kerno mem decidas ĉu rezervi tro multe da memoro. Tio estas la defaŭlta valoro en plej multaj versioj. Linux.
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
