
中にいるとき Linux データベースサーバーが予期せず終了し、原因を特定する必要があります。原因はいくつか考えられます。たとえば、 シグセグ — バックエンドサーバーのバグによる失敗。 しかし、これはまれです。 ほとんどの場合、単にディスク容量またはメモリが不足しているだけです。 ディスク領域が不足した場合、解決策は XNUMX つだけです。領域を解放してデータベースを再起動することです。
メモリ不足キラー
いつ サーバー またはプロセスがメモリ不足になる、 Linux メモリ不足キラーは、システム全体をクラッシュさせるか、メモリを消費しているプロセス(アプリケーション)を終了させるかの2つの解決策を提供します。もちろん、プロセスを終了させてOSのクラッシュを防ぐ方が望ましいです。つまり、メモリ不足キラーは、カーネルのクラッシュを防ぐためにアプリケーションを終了させるプロセスです。OSの動作を維持するためにアプリケーションを犠牲にします。まず、OOMの仕組みと制御方法について説明し、次にOOMキラーがどのアプリケーションを終了するかをどのように決定するかを見ていきましょう。
主なタスクの1つ Linux — プロセスがメモリを要求したときにメモリを割り当てます。通常、プロセスまたはアプリケーションは OS にメモリを要求しますが、それを完全に使用するわけではありません。OS が要求したが使用予定のないすべてのプロセスにメモリを割り当てると、システムはすぐにメモリ不足になり、システムがクラッシュします。これを防ぐために、OS はプロセス用にメモリを予約しますが、実際には割り当てません。メモリは、プロセスが実際に使用しようとしている場合にのみ割り当てられます。OS に空きメモリがない場合でも、プロセスにメモリを割り当て、プロセスが必要としたときに、可能であれば割り当てます。欠点は、OS がメモリを予約しても、必要なときに空きメモリがなく、システムがクラッシュすることがあることです。このシナリオでは、OOM が重要な役割を果たし、カーネルがパニックにならないようにプロセスを終了します。PostgreSQL プロセスが強制終了されると、ログに次のメッセージが表示されます。
Out of Memory: Killed process 12345 (postgres).システムのメモリが不足していて解放できない場合、関数が呼び出されます。 out_of_memory。 この段階で、彼女がやるべきことは XNUMX つだけ残っています。それは XNUMX つ以上のプロセスを完了することです。 OOM-killer はプロセスをすぐに終了する必要がありますか、それとも待つことができますか? out_of_memory が呼び出されるのは、I/O 操作またはディスクへのページングの待機が原因であることは明らかです。 したがって、OOM キラーはまずチェックを実行し、それに基づいてプロセスを終了する必要があるかどうかを判断する必要があります。 以下のチェックがすべて肯定的である場合、OOM はプロセスを終了します。
プロセスの選択
メモリがなくなると関数が呼び出されます out_of_memory()。 機能があります select_bad_process()、関数からの評価を受け取ります badness()。 「最悪」のプロセスが対象となります。 関数 badness() 特定のルールに従ってプロセスを選択します。
- カーネルには、それ自体のために最小限のメモリが必要です。
- 大量のメモリを解放する必要があります。
- メモリをほとんど使用していないプロセスを終了する必要はありません。
- 最小限のプロセスを完了する必要があります。
- ユーザー自身が完了したいプロセスが完了する可能性を高める複雑なアルゴリズム。
これらすべてのチェックを完了すると、OOM はスコアを検査します (oom_score)。 OOM の割り当て oom_score 各プロセスを計算し、この値にメモリ量を乗算します。 値が大きいプロセスは、OOM Killer の被害に遭う可能性が高くなります。 root ユーザーに関連付けられたプロセスはスコアが低く、強制終了される可能性が低くなります。
postgres=# SELECT pg_backend_pid();
pg_backend_pid
----------------
3813
(1 row)Postgres のプロセス ID は 3813 なので、別のシェルではこのカーネル パラメータを使用してスコアを取得できます。 oom_score:
vagrant@vagrant:~$ sudo cat /proc/3813/oom_score
2OOM-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プロセスの強制終了
XNUMX つ以上のプロセスがすでに選択されている場合、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 = 1OOM-Killer を無効にするには、同じコマンドで値 0 を指定します。
sudo -s sysctl -w vm.oom-kill = 0このコマンドの結果は永久に保存されるわけではなく、最初の再起動までのみ保存されます。 さらに永続性が必要な場合は、この行をファイルに追加してください /etc/sysctl.conf:
echo vm.oom-kill = 1 >>/etc/sysctl.conf有効または無効にするもう XNUMX つの方法は、変数を書き込むことです。 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 の「殺人者」を怖がらないでください。 この場合、キラーはシステムの救世主になります。 最悪のプロセスを「強制終了」し、システムのクラッシュを防ぎます。 PostgreSQL を終了するために OOM-Killer を使用する必要がないようにするには、次のように設定します。 vm.overcommit_memory 値 2。これは、OOM-Killer が介入する必要がないことを保証するものではありませんが、PostgreSQL プロセスが強制終了される可能性は低くなります。
出所: habr.com
