MySQLマスターの1つでOOM Killerが呼び出され、MySQLサーバーをシャットダウンして重大な中断を引き起こしました。以下はカーネルログです。
[2006013.230723] mysqld invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0
[2006013.230733] Pid: 1319, comm: mysqld Tainted: P 2.6.32-5-amd64 #1
[2006013.230735] Call Trace:
[2006013.230744] [<ffffffff810b6708>] ? oom_kill_process+0x7f/0x23f
[2006013.230750] [<ffffffff8106bde2>] ? timekeeping_get_ns+0xe/0x2e
[2006013.230754] [<ffffffff810b6c2c>] ? __out_of_memory+0x12a/0x141
[2006013.230757] [<ffffffff810b6d83>] ? out_of_memory+0x140/0x172
[2006013.230762] [<ffffffff810baae8>] ? __alloc_pages_nodemask+0x4ec/0x5fc
[2006013.230768] [<ffffffff812fca02>] ? io_schedule+0x93/0xb7
[2006013.230773] [<ffffffff810bc051>] ? __do_page_cache_readahead+0x9b/0x1b4
[2006013.230778] [<ffffffff810652f8>] ? wake_bit_function+0x0/0x23
[2006013.230782] [<ffffffff810bc186>] ? ra_submit+0x1c/0x20
[2006013.230785] [<ffffffff810b4e53>] ? filemap_fault+0x17d/0x2f6
[2006013.230790] [<ffffffff810cae1e>] ? __do_fault+0x54/0x3c3
[2006013.230794] [<ffffffff812fce29>] ? __wait_on_bit_lock+0x76/0x84
[2006013.230798] [<ffffffff810cd172>] ? handle_mm_fault+0x3b8/0x80f
[2006013.230803] [<ffffffff8103a9a0>] ? pick_next_task+0x21/0x3c
[2006013.230808] [<ffffffff810168ba>] ? sched_clock+0x5/0x8
[2006013.230813] [<ffffffff81300186>] ? do_page_fault+0x2e0/0x2fc
[2006013.230817] [<ffffffff812fe025>] ? page_fault+0x25/0x30
このマシンには64GBのRAMがあります。
以下はmysql設定変数です。
innodb_buffer_pool_size = 48G
innodb_additional_mem_pool_size = 512M
innodb_log_buffer_size = 64M
いくつかのnagiosプラグインとメトリック収集スクリプトに加えて、このシステムで実行される他の項目はありません。誰かがOOM Killerが呼び出される理由と、将来の呼び出しを防ぐ方法を理解するのに役立ちますか? OOMキラーにmysqlサーバーをシャットダウンしないように指示する方法はありますか?oom_adj
OOMキラーによってプロセスが終了するのを防ぐために、プロセスの値を非常に小さく設定できることがわかります。しかし、これが起こるのを防ぐための別の方法はありますか?
答え1
Linuxにはメモリオーバーコミットがあります。これは、プロセスがシステムで実際に使用可能なメモリよりも多くのメモリを要求できることを意味します。プログラムが malloc() を試みると、カーネルは「いいね、メモリを手に入れました」と言いますが、保持しません。メモリは、プロセスがその空間に何かを書き込むときにのみ予約されます。
違いを確認するために、仮想メモリと常駐メモリという2つの指標があります。 Virtual はプロセスが要求したメモリで、Resident はプロセスが実際に使用するメモリです。
このシステムを使用すると、カーネルが使用可能なメモリよりも多くのメモリを付与する「超過サブスクリプション」が発生する可能性があります。その後、システムに0バイトの空きメモリとスワップがある場合、彼は次のことを行う必要があります。犠牲(殺人)空きメモリを取得するプロセスです。
OOM Killerが動作する場所です。 OOMは、メモリ消費や他の多くの要因に基づいてプロセスを選択します(親プロセスは子プロセスの1/2を取得し、ルート所有プロセスの場合、スコアは4に分割されます。Linux-MM.org/OOM_Killer
ファイルを調整してOOMスコアに影響を与えることができます/proc/MySQL_PID/oom_adj
。に設定すると、-17
プロセスは終了しません。しかし、そうする前に、あなたはする必要がありますMySQL設定ファイルの調整MySQL メモリ使用量を制限します。そうしないと、OOM Killerが他のシステムプロセス(SSH、crontabなど)を終了し、サーバーが非常に不安定な状態になり、次の問題が発生する可能性があります。データ破損これは他の何よりも悪いです。
また、より多くのスワップを使用することを検討することもできます。
[編集する]
次の2つのsysctlsを介してオーバーコミットの動作を変更することもできます。
vm.overcommit_memory
vm.overcommit_ratio
で述べたようにカーネル文書
過剰なメモリ使用量:
値にはメモリオーバーコミットを有効にするフラグが含まれています。
このフラグが 0 の場合、カーネルは、ユーザー空間がより多くのメモリを要求したときに残っている空きメモリ量を見積もろうとします。
このフラグが1の場合、カーネルは実際にメモリが不足するまで常に十分なメモリがあるふりをします。
このフラグが2の場合、カーネルは「オーバーコミットしない」ポリシーを使用してメモリオーバーコミットを防止しようとします。 user_reserve_kbytesがこのポリシーに影響を与えることに注意してください。
この機能は「もしあれば」に大量のメモリを malloc() がメモリを多く使わないプログラムが多いため便利です。
デフォルト値は 0 です。
詳細については、Documentation/vm/overcommit-accounting および security/commoncap.c::cap_vm_enough_memory() を参照してください。
乱用率:
overcommit_memoryが2に設定されている場合、コミットされたアドレス空間は、スワップにこの割合の物理RAMを加えた値を超えることはできません。探す。
[/編集する]