Ρύθμιση 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

Προσθέστε ένα σχόλιο