まめ畑

ゆるゆると書いていきます

eacceleratorとgraceful restart

PHP5.3.8とeaccelerator0.9.6.1の組み合わせで使ってる際に起こったこと。
httpdをgraceful restartとすると、eacceleratorのキャッシュにhitしたタイミングで、Segmentation faultを出してPHPが落ちてしまう。当然、処理が中途半端なところで終わるので、httpdのアクセスログには返したレスポンスなどは出ずに、Segmentation faultの文字がエラーログに出る。コネクションはリセットされてクライアントには何も返さない。


httpdをrestartした場合は、問題なく動作しているが、graceful restartを行うと、ほぼこの症状になる。
key/contents/sessionキャッシュをdisk_onlyにしても症状は変わらない。復帰させるのは、eacceleratorのキャッシュディレクトリを空にしてhttpdをrestartすれば良い。


過去に同じような構成で、このような症状に当たったことが無いので、詳細を調査中。
メモリ上にあるキャッシュは消えているが、graceful restartにすると、まだそのメモリ領域を参照し続けてしまうのだろうか…


eacceleratorのビルドオプションに「--with-eaccelerator-doc-comment-inclusion」を追加してるけど、これが悪さするともコード読んだりする限り思えない…
しかし、ticket#416にこのオプションで同様の問題が起こることと修正の記述が。
eacceleratorを切ってgraceful restartすると問題は起こらない。


eaccelerator.shm_only="0" を eaccelerator.shm_only="1" に変更し、シェアードメモリだけにキャッシュを配置すると問題は起こらなくなった。
海外のフォーラムでも同様の症状が昔から報告されていて、restartで起こる事もあるとの事。検証環境ではgraceful restartでのみ起こっている。
シェアードメモリ中のキャッシュとディスクにキャッシュが存在している場合にrestartをすると、シェアードメモリ中のキャッシュは消えているが、ディスクに残っているキャッシュデータから参照しようとしてSegmentation faultになっているのか…
もう少し詳細に調査する必要がある。フォーラム中にある、coredumpの結果などを見ると、mod_phpがSegmentation faultを出している感じなので、eacceleratorだけが悪いわけでも無いのかもしれない。


**追記**
httpdを再起動したタイミングでは、きちんとメモリ中のキャッシュは削除されていました。Segmentation faultを出している状態でも、キャッシュされていないPHPプログラムは正常にレスポンスを返してきており、Segmentation fault発生時もある程度までPHPコードが実行されてキャッシュに乗っている状態でした。キャッシュされたコードから呼び出した先がメモリ上から消えておりSegmentation faultが出ている感じです。メモリ上のキャッシュは消えているが、ディスク上のキャッシュはまだ生きているような不整合が起こっているような動作をしています。


もう少し詳細調べてますが、曖昧なところが多いので、原因判明したらまとめようと思います。