Menyediakan Pembunuh Out-Of-Memory dalam Linux untuk PostgreSQL

Menyediakan Pembunuh Out-Of-Memory dalam Linux untuk PostgreSQL

Apabila pelayan pangkalan data berhenti secara tiba-tiba di Linux, anda perlu mencari sebabnya. Mungkin ada beberapa sebab. Sebagai contoh, SIGSEGV — kegagalan disebabkan oleh pepijat dalam pelayan bahagian belakang. Tetapi ini jarang berlaku. Selalunya, anda kehabisan ruang cakera atau memori. Jika anda kehabisan ruang cakera, hanya ada satu jalan keluar - kosongkan ruang dan mulakan semula pangkalan data.

Pembunuh Habis Ingatan

Apabila pelayan atau proses kehabisan memori, Linux menawarkan 2 penyelesaian: ranap keseluruhan sistem atau tamatkan proses (aplikasi) yang memakan memori. Adalah lebih baik, sudah tentu, untuk menamatkan proses dan menyelamatkan OS daripada ranap. Secara ringkasnya, Pembunuh Out-Of-Memory ialah proses yang membunuh aplikasi untuk menyelamatkan kernel daripada ranap. Ia mengorbankan aplikasi untuk memastikan OS berjalan. Mari kita bincangkan dahulu cara OOM berfungsi dan cara mengawalnya, kemudian lihat cara OOM Killer memutuskan aplikasi yang hendak ditamatkan.

Salah satu tugas utama Linux adalah untuk memperuntukkan memori kepada proses apabila mereka memintanya. Biasanya, proses atau aplikasi meminta memori daripada OS, tetapi tidak menggunakannya sepenuhnya. Jika OS memberikan memori kepada semua orang yang memintanya tetapi tidak bercadang untuk menggunakannya, tidak lama lagi memori akan kehabisan dan sistem akan gagal. Untuk mengelakkan ini, OS menyimpan memori untuk proses itu, tetapi sebenarnya tidak melepaskannya. Memori diperuntukkan hanya apabila proses sebenarnya akan menggunakannya. Ia berlaku bahawa OS tidak mempunyai memori percuma, tetapi ia memberikan memori kepada proses, dan apabila proses memerlukannya, OS memperuntukkannya jika ia boleh. Kelemahannya ialah kadangkala OS menyimpan memori, tetapi pada masa yang tepat tiada memori percuma, dan sistem ranap. OOM memainkan peranan penting dalam senario ini dan menamatkan proses untuk mengelakkan kernel daripada panik. Apabila proses PostgreSQL terpaksa ditamatkan, mesej muncul dalam log:

Out of Memory: Killed process 12345 (postgres).

Jika sistem kekurangan memori dan ia tidak boleh dibebaskan, fungsi itu dipanggil out_of_memory. Pada peringkat ini, dia hanya mempunyai satu perkara yang perlu dilakukan - menyelesaikan satu atau lebih proses. Sekiranya pembunuh OOM menamatkan proses dengan serta-merta atau bolehkah ia menunggu? Jelas sekali, apabila out_of_memory dipanggil, ia disebabkan oleh menunggu operasi I/O atau paging ke cakera. Oleh itu, pembunuh OOM mesti melakukan pemeriksaan terlebih dahulu dan, berdasarkan mereka, memutuskan bahawa proses itu perlu ditamatkan. Jika semua semakan di bawah adalah positif, OOM akan menamatkan proses tersebut.

Pemilihan proses

Apabila memori kehabisan, fungsi dipanggil out_of_memory(). Ia mempunyai fungsi select_bad_process(), yang menerima penilaian daripada fungsi badness(). Proses "terburuk" akan disasarkan. Fungsi badness() memilih proses mengikut peraturan tertentu.

  1. Kernel memerlukan memori minimum untuk dirinya sendiri.
  2. Anda perlu membebaskan banyak memori.
  3. Tidak perlu menamatkan proses yang menggunakan sedikit memori.
  4. Proses minimum perlu diselesaikan.
  5. Algoritma kompleks yang meningkatkan peluang penyiapan untuk proses tersebut yang pengguna sendiri mahu selesaikan.

Setelah menyelesaikan semua semakan ini, OOM meneliti skor (oom_score). OOM melantik oom_score setiap proses, dan kemudian mendarabkan nilai ini dengan jumlah memori. Proses dengan nilai yang lebih besar lebih berkemungkinan menjadi mangsa Pembunuh OOM. Proses yang dikaitkan dengan pengguna akar mempunyai skor yang lebih rendah dan kurang berkemungkinan dipaksa untuk ditamatkan.

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

ID proses Postgres ialah 3813, jadi dalam shell lain adalah mungkin untuk mendapatkan skor menggunakan parameter kernel ini oom_score:

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

Jika anda tidak mahu OOM-Killer mematikan proses sama sekali, terdapat pilihan kernel lain: oom_score_adj. Tambahkan nilai negatif yang besar untuk mengurangkan peluang melengkapkan proses yang anda hargai.

sudo echo -100 > /proc/3813/oom_score_adj

Untuk menetapkan nilai oom_score_adj, tetapkan OOMScoreAdjust dalam blok perkhidmatan:

[Service]
OOMScoreAdjust=-1000

Atau gunakan oomprotect dalam satu pasukan rcctl.

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

Paksa penamatan sesuatu proses

Apabila satu atau lebih proses telah dipilih, OOM-Killer memanggil fungsi tersebut oom_kill_task(). Fungsi ini menghantar isyarat penamatan kepada proses. Sekiranya kekurangan ingatan oom_kill() Memanggil fungsi ini untuk menghantar isyarat SIGKILL kepada proses. Mesej ditulis ke log kernel.

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

Bagaimana untuk mengawal OOM-Killer

Di Linux, anda boleh mendayakan atau melumpuhkan OOM-Killer (walaupun yang terakhir tidak disyorkan). Untuk mendayakan atau melumpuhkan gunakan parameter vm.oom-kill. Untuk mendayakan OOM-Killer pada masa jalan, jalankan arahan sysctl.

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

Untuk melumpuhkan OOM-Killer, nyatakan nilai 0 dalam arahan yang sama:

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

Hasil daripada arahan ini tidak akan disimpan selama-lamanya, tetapi hanya sehingga but semula pertama. Jika anda memerlukan lebih banyak kegigihan, tambahkan baris ini pada fail /etc/sysctl.conf:

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

Cara lain untuk mendayakan dan melumpuhkan ialah menulis pembolehubah panic_on_oom. Nilai sentiasa boleh didaftar masuk /proc.

$ cat /proc/sys/vm/panic_on_oom
0

Jika anda menetapkan nilai kepada 0, maka apabila memori kehabisan, tidak akan ada panik kernel.

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

Jika anda menetapkan nilai kepada 1, maka apabila memori kehabisan, panik kernel akan berlaku.

echo 1 > /proc/sys/vm/panic_on_oom

OOM-Killer bukan sahaja boleh dihidupkan dan dimatikan. Kami telah mengatakan bahawa Linux boleh menyimpan lebih banyak memori untuk proses daripada yang tersedia tanpa benar-benar memperuntukkannya, dan tingkah laku ini dikawal oleh parameter kernel Linux. Pembolehubah bertanggungjawab untuk ini vm.overcommit_memory.

Anda boleh menentukan nilai berikut untuknya:

0: Kernel itu sendiri memutuskan sama ada untuk menyimpan terlalu banyak memori. Ini adalah lalai pada kebanyakan versi Linux.
1: Kernel akan sentiasa menyimpan memori tambahan. Ini berisiko, kerana ingatan mungkin kehabisan, kerana, kemungkinan besar, suatu hari proses akan memerlukannya.
2: kernel tidak akan menyimpan lebih banyak memori daripada yang ditentukan dalam parameter overcommit_ratio.

Dengan parameter ini, anda menentukan peratusan memori yang dibenarkan untuk ditempah secara berlebihan. Jika tiada ruang untuknya, tiada ingatan diperuntukkan, dan tempahan akan ditolak. Ini adalah pilihan paling selamat yang disyorkan untuk PostgreSQL. OOM-Killer dipengaruhi oleh elemen lain - keupayaan pertukaran, yang dikawal oleh pembolehubah cat /proc/sys/vm/swappiness. Nilai ini memberitahu kernel cara mengendalikan paging. Semakin tinggi nilai, semakin kecil kemungkinan OOM akan menamatkan proses, tetapi disebabkan oleh operasi I/O ia mempunyai kesan negatif pada pangkalan data. Dan sebaliknya - semakin rendah nilai, semakin tinggi kemungkinan campur tangan OOM-Killer, tetapi prestasi pangkalan data juga lebih tinggi. Nilai lalai ialah 60, tetapi jika keseluruhan pangkalan data sesuai dengan ingatan, lebih baik untuk menetapkan nilai kepada 1.

Keputusan

Jangan biarkan "pembunuh" dalam OOM-Killer menakutkan anda. Dalam kes ini, pembunuh akan menjadi penyelamat sistem anda. Ia "membunuh" proses yang paling teruk dan menyelamatkan sistem daripada ranap. Untuk mengelakkan penggunaan OOM-Killer untuk menamatkan PostgreSQL, tetapkan kepada vm.overcommit_memory nilai 2. Ini tidak menjamin bahawa OOM-Killer tidak perlu campur tangan, tetapi ia akan mengurangkan kemungkinan memaksa proses PostgreSQL untuk ditamatkan.

Sumber: www.habr.com

Tambah komen