技術・開発

【Apache】PHPインストール後の再起動エラー「Apache is running a threaded MPM…」の解決策

2012年9月11日

LinuxサーバーにPHP5をインストールし、設定を終えてApacheを再起動しようとしたところ、以下のような致命的なエラー(crit)が発生して起動に失敗してしまいました。

# /etc/rc.d/init.d/apache2 restart
Apache2 HTTP Serverを停止中: [ 失敗 ]
Apache2 HTTP Serverを起動中: [Tue Sep 11 00:30:21 2012] [crit] Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe. You need to recompile PHP.
Pre-configuration failed

「PHPを再コンパイル(recompile)しろって言われてる…?」と焦りましたが、原因と簡単な解決策があったので備忘録として残しておきます。

原因:Apacheの動作モード(MPM)の不一致

エラーメッセージをそのまま直訳すると、「Apacheはスレッド型のMPMで動いているのに、あなたのPHPモジュールはスレッドセーフとしてコンパイルされていません」という意味になります。

実は、PHPインストールの際のログをよく見返してみると、しっかりと警告メッセージが出力されていました(完全にスルーしていました…orz)。

Apache2 is configured to use worker MPM. But php5-apache2 requires prefork MPM. Run the following command as root to switch MPM: /sbin/update-alternatives --config apache2

つまり、「現在のApacheは『workerモード』で動いているけれど、インストールしたPHPは『preforkモード』じゃないと動かないよ」というのが原因です。

解決策:Apacheを「prefork」に切り替える

警告メッセージの案内に従い、ApacheのMPM(マルチプロセッシングモジュール)を worker から prefork に切り替えます。

root権限で以下のコマンドを実行してください。

# /sbin/update-alternatives --config apache2

すると、以下のように選択肢が表示されます。

2 プログラムがあり 'apache2' を提供します。

  選択       コマンド
-----------------------------------------------
 + 1           /usr/sbin/apache2.worker
 * 2           /usr/sbin/apache2.prefork

Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:

ここで 2 (prefork)を入力してEnterを押します。 設定を変更した後、再度Apacheを起動します。

# /etc/rc.d/init.d/apache2 restart
Apache2 HTTP Serverを停止中: [ 失敗 ]
Apache2 HTTP Serverを起動中: [  OK  ]

無事に起動(OK)しました! (※停止が[失敗]になっているのは、そもそも先ほどのエラーで起動していなかったためです)

補足:prefork と worker の違いとは?

ざっくりとした解説ですが、Apacheの挙動には以下の違いがあります。

  • prefork(古くからの標準):リクエストごとに「プロセス」をコピーして処理する。安定性が高いが、メモリ消費がやや多い。
  • worker(Apache2からの機能):リクエストを「スレッド」で処理する。メモリ消費が少なくパフォーマンスが良い。

workerの方がパフォーマンスは高いのですが、標準的なPHPモジュール(mod_php)は「スレッドセーフ(複数のスレッドから同時に呼ばれても安全な設計)」になっていないため、安全なpreforkモードで動かすのが一般的なセオリーとなっています。

もしどうしてもworkerモードでPHPを動かしたい場合は、PHPをスレッドセーフ版として自力でリビルド(再コンパイル)するか、FastCGIなどを利用してApacheとPHPを切り離すといった少し面倒な手順が必要になります。

個人レベルのサーバーや、とてつもないアクセスを捌く環境でなければ、手軽な prefork への切り替えで全く問題ありません。 同じエラーで躓いた方の参考になれば幸いです。

-技術・開発
-, , , , , , ,