Linux でデータベース サーバーが予期せず終了した場合は、その理由を見つける必要があります。 理由はいくつか考えられます。 例えば、 シグセグ — バックエンドサーバーのバグによる失敗。 しかし、これはまれです。 ほとんどの場合、単にディスク容量またはメモリが不足しているだけです。 ディスク領域が不足した場合、解決策は XNUMX つだけです。領域を解放してデータベースを再起動することです。
メモリ不足キラー
サーバーまたはプロセスのメモリが不足した場合、Linux は 2 つの解決策を提供します。システム全体をクラッシュするか、メモリを消費しているプロセス (アプリケーション) を終了します。 もちろん、プロセスを終了して OS がクラッシュしないようにする方が良いでしょう。 一言で言えば、メモリ不足キラーは、カーネルのクラッシュを防ぐためにアプリケーションを強制終了するプロセスです。 OS を実行し続けるためにアプリケーションが犠牲になります。 まず、OOM の仕組みとその制御方法について説明し、次に OOM Killer がどのアプリケーションを終了するかを決定する方法を見てみましょう。
Linux の主なタスクの XNUMX つは、プロセスが要求したときにプロセスにメモリを割り当てることです。 通常、プロセスまたはアプリケーションは OS にメモリを要求しますが、それを完全には使用しません。 OS がメモリを要求した全員にメモリを割り当てても、それを使用する予定がない場合、すぐにメモリが枯渇してシステムが故障します。 これを回避するために、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
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
プロセスの強制終了
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 = 1
OOM-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