2026年7月5日(日)掲載 2,285本日 0
HN15085

PostgreSQLとOOM Killer:なぜ厳格なメモリオーバーコミット設定が必要なのか

PostgreSQL and the OOM killer: Why we use strict memory overcommit

furkansahin1日前

議論

11
1Bender1日前

記事でも言及されてるけど、mode 2を使うときは特に慎重になったほうがいいよ。もし既にovercommit ratioを調整済みなら、forkができなくなる可能性があるからね。まずはQA/Perf環境でテストして、全アプリケーションの再起動も試してみるべき。本番環境にデプロイする前には負荷テストと完全なQAテストをやっておくこと。それに、本番環境に適用するときも、いきなりsysctl設定ファイルに書くよりは、確信が持てるようになるまでアプリのデプロイスクリプト経由で動的に設定を変えていくのがおすすめかな。

昔、かなり古いカーネルでこれと同じことを試した経験があるんだけど(記事にもある通り当時のカーネルの話ね)、個人的にはovercommitを0のままにして、ratioも0にして、vmscanに触られたくないプログラムのoom_score_adjを1000に設定する方がトラブルが少なかったよ。もちろん、vm.min_free_kbytesやvm.admin_reserve_kbytes、vm.user_reserve_kbytesを設定するときはRedhatの推奨式を使うのが前提ね。あと、アプリの管理者がメモリを際限なく使い切るような設定にしないよう、厳しく監視しておくことも忘れずに。

2leononame1日前

これには何度も泣かされたよ。仕事でGo製のアプリとPostgreSQLを同じマシンで動かしてるんだけど、バックエンドのアプリが大量の仮想メモリを確保するんだ。最初はovercommitを0(ヒューリスティック)にしてたんだけど、PostgreSQLで大きなクエリを投げるとクラッシュするから2に設定したんだ。でも今度はシステム全体が少し不安定になっちゃって。バックエンドが相変わらず大量の仮想メモリを確保しようとするせいで、割り当て時にエラーが出るようになったんだ。

今は経験則で安定する値にovercommit_ratioを設定してるけど、結局のところ万能な解決策なんてない気がする。Goに限らず、管理された言語のほとんどは仮想メモリをドカ食いするのが好きだからね。結局のところ、バックエンドとデータベースを別のサーバーで動かすのが一番の解決策だろうね。

3ozgune1日前

(UbicloudのOzgunです)

ブログ記事の技術的な内容は同意できるけど、タイトルの表現は少し強すぎたかなと反省してる。UbicloudのようなマネージドPostgresプロバイダーとしては、厳格なメモリオーバーコミット設定を採用しているよ。大規模にPostgresを運用してきた経験から言っても、デフォルトのままよりは有効化したほうがいいという結論に達したんだ。

ただ、他の多くのシナリオでは、厳格なメモリオーバーコミットを有効にすることで予期せぬ副作用があることも理解できる。だからこそ、Linuxはデフォルトで厳格なオーバーコミットを適用していないんだろうね。

4otterley1日前

データベースみたいにミッションクリティカルなサービスは、専用のコンピュートノードに分離するのが一番だっていういい教訓だと思う。

5wongarsu1日前

今回ばかりは、Windowsがオーバーコミットをしないという決定を下していることが理にかなっているように思える。

6baq約23時間前

2026年になってもLinuxのvmデフォルト設定は狂ってるとしか思えないよ。

  • メモリ圧迫でシステムが死ぬ(スワップの有無に関わらず。むしろスワップがないほうが事態は悪化するってのは今や常識のはずなんだけど)
  • 空きメモリが大量にあるのにディスク圧迫でシステムが死ぬ(これの診断は本当に楽しいよ)
  • 技術的に死なないにしても、OOM Killerのせいでメモリ圧迫時に無用(あるいはそれ以下)な状態になる
  • どんな形式のメモリ圧縮も有効化されていない
  • ...

WindowsもmacOSも、どんなワークロードに対しても最初からずっとうまくやってるよね。

7man8alexd約23時間前

Mode 0(ヒューリスティック)の説明は間違ってるよ。その複雑なヒューリスティックは10年近く前に削除されてる。現在は、物理メモリを超える単一の割り当てをカーネルが拒否する、ただそれだけ。

あとこの記事は、重要なプロセスのOOM Killerを回避するための現代的な正解である「OOM Score Adjust」を無視してるね。

手動でCommitLimitをいじるなんて、古臭い上に不正確でエラーも起きやすいやり方だよ。ENOMEMを適切に処理できる単一プロセス向けのワークロード以外には向いてない。ファイルページのキャッシュメモリの動的な割り当てを完全に無視してるからね。ファイル操作が異常に増えれば、結局OOMが発生する。逆にファイル操作が少ない時は、メモリ圧迫が起きずキャッシュが解放されないせいでメモリを無駄にすることになる。strict overcommitは使わないほうがいい。

810000truths約21時間前

オーバーコミットを無効にしたカーネル上で、うまく動作することを売りにしたLinuxディストリビューションがあれば興味あるな。でも、それを実現するのは相当大変だろう。fork()に伴う明白な問題は別としても、malloc()の失敗チェックをせずに暗黙的にオーバーコミットに依存しているプログラムやライブラリが世の中には多すぎるからね。

9mono442約21時間前

メモリオーバーコミットを無効にするとRAMが無駄になるのが問題だよね。スワップを設定すれば回避できるけど、今度はディスクスペースが無駄になる。

10senderista約21時間前

OOMを適切に処理するやり方は、成熟したデータベースがやっていることだね。独自のメモリ管理を実装して、管理システムと統合された自前のアロケーターを使い、すべての割り当てパスがOOMから回復できるようにする。言うは易く行うは難しだけどね。