Ρύθμιση του Out-Of-Memory Killer στο Linux για PostgreSQL

Ρύθμιση του Out-Of-Memory Killer στο Linux για PostgreSQL

Όταν μέσα Linux сервер базы данных непредвиденно завершает работу, нужно найти причину. Причин может быть несколько. Например, SIGSEGV — αποτυχία λόγω σφάλματος στον διακομιστή υποστήριξης. Αλλά αυτό είναι σπάνιο. Τις περισσότερες φορές, απλώς εξαντλείται ο χώρος στο δίσκο ή η μνήμη. Εάν εξαντληθεί ο χώρος στο δίσκο, υπάρχει μόνο μία διέξοδος - ελευθερώστε χώρο και επανεκκινήστε τη βάση δεδομένων.

Δολοφόνος εκτός μνήμης

Όταν εσύ υπηρέτης или процесса заканчивается память, Linux предлагает 2 пути решения: обрушить всю систему или завершить процесс (приложение), который съедает память. Лучше, конечно, завершить процесс и спасти ОС от аварийного завершения. В двух словах, Out-Of-Memory Killer — это процесс, который завершает приложение, чтобы спасти ядро от сбоя. Он жертвует приложением, чтобы сохранить работу ОС. Давайте сначала обсудим, как работает OOM и как его контролировать, а потом посмотрим, как OOM Killer решает, какое приложение завершить.

Одна из главных задач Linux — выделять память процессам, когда они ее просят. Обычно процесс или приложение запрашивают у ОС память, а сами используют ее не полностью. Если ОС будет выдавать память всем, кто ее просит, но не планирует использовать, очень скоро память закончится, и система откажет. Чтобы этого избежать, ОС резервирует память за процессом, но фактически не выдает ее. Память выделяется, только когда процесс действительно собирается ее использовать. Случается, что у ОС нет свободной памяти, но она закрепляет память за процессом, и когда процессу она нужна, ОС выделяет ее, если может. Минус в том, что иногда ОС резервирует память, но в нужный момент свободной памяти нет, и происходит сбой системы. OOM играет важную роль в этом сценарии и завершает процессы, чтобы уберечь ядро от паники. Когда принудительно завершается процесс PostgreSQL, в логе появляется сообщение:

Out of Memory: Killed process 12345 (postgres).

Εάν η μνήμη του συστήματος είναι χαμηλή και δεν μπορεί να ελευθερωθεί, καλείται η λειτουργία out_of_memory. Σε αυτό το στάδιο, έχει μόνο ένα πράγμα να κάνει - να ολοκληρώσει μία ή περισσότερες διαδικασίες. Πρέπει το OOM-killer να τερματίσει αμέσως τη διαδικασία ή μπορεί να περιμένει; Προφανώς, όταν καλείται out_of_memory, αυτό οφείλεται στην αναμονή για λειτουργία I/O ή σελιδοποίηση στο δίσκο. Επομένως, ο δολοφόνος του OOM πρέπει πρώτα να πραγματοποιήσει ελέγχους και, βάσει αυτών, να αποφασίσει ότι η διαδικασία πρέπει να τερματιστεί. Εάν όλοι οι παρακάτω έλεγχοι είναι θετικοί, το OOM θα τερματίσει τη διαδικασία.

Επιλογή διαδικασίας

Όταν εξαντληθεί η μνήμη, καλείται η λειτουργία out_of_memory(). Έχει μια λειτουργία select_bad_process(), το οποίο λαμβάνει αξιολόγηση από τη συνάρτηση badness(). Η «χειρότερη» διαδικασία θα είναι στοχευμένη. Λειτουργία badness() επιλέγει μια διαδικασία σύμφωνα με ορισμένους κανόνες.

  1. Ο πυρήνας χρειάζεται κάποια ελάχιστη μνήμη για τον εαυτό του.
  2. Πρέπει να ελευθερώσετε πολλή μνήμη.
  3. Δεν χρειάζεται να τερματίσετε διεργασίες που χρησιμοποιούν λίγη μνήμη.
  4. Πρέπει να ολοκληρωθούν ελάχιστες διαδικασίες.
  5. Πολύπλοκοι αλγόριθμοι που αυξάνουν τις πιθανότητες ολοκλήρωσης για εκείνες τις διεργασίες που θέλει να ολοκληρώσει ο ίδιος ο χρήστης.

Έχοντας ολοκληρώσει όλους αυτούς τους ελέγχους, το OOM εξετάζει τη βαθμολογία (oom_score). Το ΟΟΜ διορίζει oom_score κάθε διεργασία και, στη συνέχεια, πολλαπλασιάζει αυτή την τιμή με την ποσότητα της μνήμης. Οι διαδικασίες με μεγαλύτερες τιμές είναι πιο πιθανό να πέσουν θύματα του OOM Killer. Οι διεργασίες που σχετίζονται με τον χρήστη root έχουν χαμηλότερη βαθμολογία και είναι λιγότερο πιθανό να αναγκαστούν να τερματιστούν.

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

Το αναγνωριστικό διαδικασίας Postgres είναι 3813, επομένως σε άλλο κέλυφος είναι δυνατό να λάβετε τη βαθμολογία χρησιμοποιώντας αυτήν την παράμετρο πυρήνα oom_score:

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

Εάν δεν θέλετε το OOM-Killer να σκοτώσει καθόλου τη διαδικασία, υπάρχει μια άλλη επιλογή πυρήνα: oom_score_adj. Προσθέστε μια μεγάλη αρνητική τιμή για να μειώσετε τις πιθανότητες ολοκλήρωσης μιας διαδικασίας που εκτιμάτε.

sudo echo -100 > /proc/3813/oom_score_adj

Για να ορίσετε μια τιμή oom_score_adj, ορίστε το OOMScoreAdjust στο μπλοκ υπηρεσιών:

[Service]
OOMScoreAdjust=-1000

Ή χρησιμοποιήστε oomprotect σε μία ομάδα rcctl.

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

Αναγκαστικός τερματισμός μιας διαδικασίας

Όταν μία ή περισσότερες διεργασίες είναι ήδη επιλεγμένες, το OOM-Killer καλεί τη συνάρτηση oom_kill_task(). Αυτή η λειτουργία στέλνει ένα σήμα τερματισμού στη διαδικασία. Σε περίπτωση έλλειψης μνήμης oom_kill() Καλεί αυτή τη συνάρτηση για να στείλει ένα σήμα SIGKILL στη διεργασία. Γράφεται ένα μήνυμα στο αρχείο καταγραφής του πυρήνα.

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

Πώς να ελέγξετε το OOM-Killer

В Linux можно включать и отключать OOM-Killer (хотя последнее не рекомендуется). Для включения и отключения используйте параметр vm.oom-kill. Για να ενεργοποιήσετε το OOM-Killer κατά το χρόνο εκτέλεσης, εκτελέστε την εντολή sysctl.

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

Για να απενεργοποιήσετε το OOM-Killer, καθορίστε την τιμή 0 στην ίδια εντολή:

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

Το αποτέλεσμα αυτής της εντολής δεν θα αποθηκευτεί για πάντα, αλλά μόνο μέχρι την πρώτη επανεκκίνηση. Εάν χρειάζεστε περισσότερη επιμονή, προσθέστε αυτή τη γραμμή στο αρχείο /etc/sysctl.conf:

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

Ένας άλλος τρόπος για να ενεργοποιήσετε και να απενεργοποιήσετε είναι να γράψετε μια μεταβλητή panic_on_oom. Η τιμή μπορεί πάντα να ελεγχθεί /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Εάν ορίσετε την τιμή στο 0, τότε όταν η μνήμη εξαντληθεί, δεν θα υπάρχει πανικός στον πυρήνα.

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

Εάν ορίσετε την τιμή σε 1, τότε όταν τελειώσει η μνήμη, θα προκληθεί πανικός πυρήνα.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer можно не только включать и выключать. Мы уже говорили, что Linux может зарезервировать для процессов больше памяти, чем есть, но не выделять ее по факту, и этим поведением управляет параметр ядра Linux. За это отвечает переменная vm.overcommit_memory.

Μπορείτε να καθορίσετε τις ακόλουθες τιμές για αυτό:

0: ядро само решает, стоит ли резервировать слишком много памяти. Это значение по умолчанию в большинстве версий Linux.
1: Ο πυρήνας θα διατηρεί πάντα επιπλέον μνήμη. Αυτό είναι επικίνδυνο, γιατί η μνήμη μπορεί να εξαντληθεί, γιατί, πιθανότατα, μια μέρα θα το απαιτήσουν οι διαδικασίες.
2: ο πυρήνας δεν θα κρατήσει περισσότερη μνήμη από αυτή που καθορίζεται στην παράμετρο overcommit_ratio.

Με αυτήν την παράμετρο, καθορίζετε το ποσοστό της μνήμης που επιτρέπεται να υπερκρατηθεί. Εάν δεν υπάρχει χώρος για αυτό, δεν εκχωρείται μνήμη και η κράτηση θα απορριφθεί. Αυτή είναι η ασφαλέστερη επιλογή που προτείνεται για την PostgreSQL. Το OOM-Killer επηρεάζεται από ένα άλλο στοιχείο - την ικανότητα ανταλλαγής, η οποία ελέγχεται από τη μεταβλητή cat /proc/sys/vm/swappiness. Αυτές οι τιμές λένε στον πυρήνα πώς να χειρίζεται τη σελιδοποίηση. Όσο υψηλότερη είναι η τιμή, τόσο λιγότερο πιθανό είναι το OOM να τερματίσει τη διαδικασία, αλλά λόγω των λειτουργιών I/O έχει αρνητικό αντίκτυπο στη βάση δεδομένων. Και αντίστροφα - όσο χαμηλότερη είναι η τιμή, τόσο μεγαλύτερη είναι η πιθανότητα παρέμβασης OOM-Killer, αλλά η απόδοση της βάσης δεδομένων είναι επίσης υψηλότερη. Η προεπιλεγμένη τιμή είναι 60, αλλά εάν ολόκληρη η βάση δεδομένων χωράει στη μνήμη, είναι προτιμότερο να ορίσετε την τιμή σε 1.

Αποτελέσματα της

Μην αφήσετε τον «δολοφόνο» στο OOM-Killer να σας τρομάξει. Σε αυτή την περίπτωση, ο δολοφόνος θα είναι ο σωτήρας του συστήματός σας. «Σκοτώνει» τις χειρότερες διαδικασίες και σώζει το σύστημα από κατάρρευση. Για να αποφύγετε τη χρήση του OOM-Killer για τον τερματισμό της PostgreSQL, ορίστε το σε vm.overcommit_memory τιμή 2. Αυτό δεν εγγυάται ότι το OOM-Killer δεν θα χρειαστεί να παρέμβει, αλλά θα μειώσει την πιθανότητα να αναγκαστεί να τερματιστεί η διαδικασία PostgreSQL.

Πηγή: www.habr.com

Αγοράστε αξιόπιστη φιλοξενία για ιστότοπους με προστασία DDoS, διακομιστές VPS VDS 🔥 Αγοράστε αξιόπιστη φιλοξενία ιστοσελίδων με προστασία DDoS, διακομιστές VPS VDS | ProHoster