Linux 7.0でPostgreSQLの性能が半減 — プリエンプション変更が引き起こしたスピンロック地獄の全容

はじめに

Linux 7.0カーネルの開発版で、PostgreSQLのスループットが約50%も低下する深刻なパフォーマンスリグレッションが報告されました。AWSのエンジニアがGraviton4環境で検証した結果、カーネルスケジューラの設計変更がPostgreSQLのロック機構と相性最悪であることが判明。しかもLinux 7.0のリリースは4月中旬に迫っており、根本的な修正は間に合わない見通しです。この記事では、問題の技術的な原因、影響範囲、そしてエンジニアが今取るべき対策を解説します。

何が起きたのか — AWS環境での検証結果

2026年4月初旬、AWSのエンジニアがLinux 7.0の開発カーネル上でPostgreSQLのベンチマークを実施し、衝撃的な結果を報告しました。

テスト環境はAWS EC2 m8g.24xlarge(Graviton4、96vCPU)で、pgbenchのsimple-updateワークロードを1024クライアントで実行。Linux 7.0では約50,751 TPSだったスループットが、問題のコミットをリバートすると98,565 TPSまで回復しました。つまり、Linux 7.0を使うだけでスループットが1.94倍も悪化していたのです。

この数字はベンチマーク上の話にとどまりません。実運用に置き換えれば、同じクエリ処理量を維持するためにサーバー台数を2倍にする必要があるということです。10台のPostgreSQLサーバーを運用している組織なら、20台必要になる計算になります。

原因 — PREEMPT_NONE削除とスピンロックの衝突

問題の根本は、Linux 7.0 rc1で導入されたカーネルのプリエンプションモデル変更です。

従来のLinuxカーネルには、サーバー用途向けにPREEMPT_NONE(プリエンプションなし)というオプションが用意されていました。これはカーネルコード実行中にタスク切り替えを最小限に抑えるモードで、データベースサーバーのようにスループットを重視するワークロードに適していました。

Linux 7.0では、Intelのカーネル開発者ペーター・ジルストラ氏のコミットにより、x86やARM64などの主要アーキテクチャからPREEMPT_NONEが削除されました。目的はカーネルの簡素化とPREEMPT_RT(リアルタイム対応)への統合推進です。新しいカーネルではPREEMPT_FULLPREEMPT_LAZYの2モデルのみが提供されます。

ここでPostgreSQLの設計が問題に絡みます。PostgreSQLはマルチスレッドではなくプロセスモデルを採用しており、共有メモリへのアクセスに**ユーザースペーススピンロック(s_lock)**を多用します。スピンロックとは、ロックが取得できるまでCPUをビジーウェイトさせる軽量な排他制御機構です。

PREEMPT_NONEの環境では、スピンロックを保持しているプロセスがプリエンプト(中断)されにくいため、ロック保持時間が短く済みました。ところがPREEMPT_LAZY環境ではロック保持中にもプリエンプションが発生するようになり、ロックを持ったまま中断されたプロセスの復帰を他のプロセスがスピンして待ち続けるという非効率な状態が発生します。

パフォーマンスプロファイリングの結果、CPU時間の55%がPostgreSQLのユーザースペーススピンロックで消費されていることが判明しました。本来の処理に使われるべきCPUリソースの半分以上が、ロック待ちの空回りに費やされていたのです。

なぜ修正が難しいのか — カーネルとアプリの責任分界点

この問題の厄介な点は、カーネル側・PostgreSQL側のどちらか一方だけでは解決が困難なことです。

カーネル開発者のジルストラ氏は「PostgreSQL側がRSEQ(Restartable Sequences)のタイムスライス拡張を活用すべき」と指摘しています。RSEQはLinuxカーネルが提供する比較的新しい機能で、ユーザースペースのクリティカルセクション実行中にプリエンプションを検知・制御できる仕組みです。

しかし、RSEQのサポートをPostgreSQLに組み込むにはコード変更が必要で、これは短期間では実現できません。PostgreSQLコミュニティがRSEQを採用する具体的なタイムラインも示されておらず、Linux 7.0のリリースには間に合わないとされています。

一方で、カーネル側でPREEMPT_NONEを復活させる案もありますが、これはカーネル簡素化とリアルタイム対応という設計方針に逆行するため、メインラインへの採用は期待しにくい状況です。AWSは既定値をPREEMPT_NONEに差し戻すパッチを提案していますが、議論は継続中です。

エンジニアへの影響 — Ubuntu 26.04 LTSが直撃

この問題が特に深刻なのは、Ubuntu 26.04 LTS(4月23日リリース予定)がLinux 7.0カーネルを採用する予定だからです。

Ubuntu LTSは企業のサーバー環境で広く採用されており、リリース後は多くの本番PostgreSQL環境がLinux 7.0上で動作することになります。影響を受けるのはGraviton4のような大規模インスタンスに限りません。マルチコア環境でPostgreSQLを高負荷運用しているすべての組織が潜在的なリスクを抱えます。

今すぐ取るべき対策:

  • Ubuntu 26.04 LTSへのアップグレードを急がない。 既存のUbuntu 24.04 LTSやRHEL系の安定カーネルを維持し、Linux 7.0の問題が解決されるまで待つのが最も安全です
  • 検証環境でベンチマークを実施する。 自社のワークロードでどの程度影響を受けるか、pgbenchやカスタムベンチマークで事前に確認しましょう
  • カーネルブートパラメータの確認。 ディストリビューションによっては、ブートパラメータでプリエンプションモデルを変更できる可能性があります。最新のカーネルドキュメントを確認してください
  • PostgreSQLのロック機構のアップデートを追跡する。 PostgreSQL開発コミュニティでのRSEQ対応議論の進展を注視しましょう

まとめ

Linux 7.0のプリエンプションモデル変更(PREEMPT_NONEの削除)が、PostgreSQLのユーザースペーススピンロックと衝突し、スループットが約50%低下する深刻なリグレッションが発生しました。カーネル側の「簡素化」という設計判断と、PostgreSQLの「プロセスモデル+スピンロック」という実装が正面衝突した形です。根本修正にはPostgreSQL側のRSEQ対応が必要ですが、短期的な解決は難しい状況です。

Ubuntu 26.04 LTSの採用を予定している組織は、必ず事前検証を行い、PostgreSQLワークロードへの影響を確認してからアップグレードを判断してください。

ソース