
Apabila masuk Linux Pelayan pangkalan data tamat tanpa diduga, dan puncanya perlu ditentukan. Mungkin terdapat beberapa sebab. Contohnya, 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 anda pelayan atau proses kehabisan ingatan, Linux Pembunuh Habis Memori menawarkan dua penyelesaian: merosakkan keseluruhan sistem atau menamatkan proses (aplikasi) yang memakan memori. Sudah tentu, lebih baik untuk menamatkan proses dan menyelamatkan OS daripada ranap. Pendek kata, Pembunuh Habis Memori ialah proses yang menamatkan aplikasi untuk menyelamatkan kernel daripada ranap. Ia mengorbankan aplikasi untuk memastikan OS berjalan. Mari kita bincangkan dahulu cara OOM berfungsi dan cara mengawalnya, dan kemudian lihat bagaimana Pembunuh OOM memutuskan aplikasi mana yang hendak ditamatkan.
Salah satu tugas utama Linux — Memperuntukkan memori kepada proses apabila mereka memintanya. Biasanya, proses atau aplikasi meminta memori daripada OS tetapi tidak menggunakannya sepenuhnya. Jika OS memperuntukkan memori kepada semua orang yang memintanya tetapi tidak merancang untuk menggunakannya, sistem akan cepat kehabisan memori, dan sistem akan ranap. Untuk mengelakkan ini, OS menyimpan memori untuk proses tetapi sebenarnya tidak memperuntukkannya. Memori diperuntukkan hanya apabila proses benar-benar berhasrat untuk menggunakannya. Kadangkala OS tidak mempunyai memori bebas, tetapi ia memperuntukkan memori kepada proses, dan apabila proses memerlukannya, OS memperuntukkannya jika boleh. Kelemahannya ialah kadangkala OS menyimpan memori, tetapi apabila diperlukan, tiada memori bebas, menyebabkan ranap sistem. OOM memainkan peranan penting dalam senario ini, menamatkan proses untuk mengelakkan kernel daripada panik. Apabila proses PostgreSQL ditamatkan secara paksa, mesej berikut 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.
- Kernel memerlukan memori minimum untuk dirinya sendiri.
- Anda perlu membebaskan banyak memori.
- Tidak perlu menamatkan proses yang menggunakan sedikit memori.
- Proses minimum perlu diselesaikan.
- 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
2Jika 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_adjUntuk menetapkan nilai oom_score_adj, tetapkan OOMScoreAdjust dalam blok perkhidmatan:
[Service]
OOMScoreAdjust=-1000Atau gunakan oomprotect dalam satu pasukan rcctl.
rcctl set <i>servicename</i> oomprotect -1000Paksa 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
В Linux Anda boleh mendayakan atau melumpuhkan OOM-Killer (walaupun yang kedua tidak disyorkan). Untuk mendayakan atau melumpuhkannya, gunakan parameter vm.oom-kill. Untuk mendayakan OOM-Killer pada masa jalan, jalankan arahan sysctl.
sudo -s sysctl -w vm.oom-kill = 1Untuk melumpuhkan OOM-Killer, nyatakan nilai 0 dalam arahan yang sama:
sudo -s sysctl -w vm.oom-kill = 0Hasil 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.confCara lain untuk mendayakan dan melumpuhkan ialah menulis pembolehubah panic_on_oom. Nilai sentiasa boleh didaftar masuk /proc.
$ cat /proc/sys/vm/panic_on_oom
0Jika anda menetapkan nilai kepada 0, maka apabila memori kehabisan, tidak akan ada panik kernel.
$ echo 0 > /proc/sys/vm/panic_on_oomJika anda menetapkan nilai kepada 1, maka apabila memori kehabisan, panik kernel akan berlaku.
echo 1 > /proc/sys/vm/panic_on_oomOOM-Killer boleh dihidupkan dan dimatikan, seperti yang telah kami sebutkan. Linux mungkin menyimpan lebih banyak memori untuk proses daripada yang tersedia, tetapi sebenarnya tidak memperuntukkannya, dan tingkah laku ini dikawal oleh parameter kernel LinuxPembolehubah bertanggungjawab untuk ini. vm.overcommit_memory.
Anda boleh menentukan nilai berikut untuknya:
0: Kernel itu sendiri yang memutuskan sama ada untuk menyimpan terlalu banyak memori. Ini adalah nilai lalai dalam 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
