Ticket #1340 (closed バグ指摘: 修正済)

Opened 11 years ago

Last modified 10 years ago

PHP+APC3.1でAPCをonにするとSESSIONへの書き込みが出来ない不具合

Reported by: kimoto Owned by: Seasoft
Priority: Milestone: EC-CUBE2.12.1
Component: フロント Version: 2.11.4
Keywords: Cc:
修正済み: yes

Description (last modified by Seasoft) (diff)

PHP5.2.10以降でAPCをonにするとEC-CUBEが動かなくなってしまいます

エラー内容

Fatal error: Class 'MDB2' not found in /var/www/apps/eccube-2.11.1/data/class/SC_Query.php on line 76
 
Call Stack:
    0.0820    2554744   1. SC_Helper_Session->sfSessWrite() /var/www/apps/eccube-2.11.1/data/class/helper/SC_Helper_Session.php:0
    0.0820    2555336   2. SC_Query->SC_Query() /var/www/apps/eccube-2.11.1/data/class/helper/SC_Helper_Session.php:85

下記で発現を確認

  • EC-CUBE 2.11.1 + PHP 5.3.6 + APC 3.1.6
  • EC-CUBE 2.11.4 + PHP 5.2.17 + APC 3.1.7
  • apc.enabled を変更できない環境にて apc.cache_by_default = Off で発現しなくなることを確認

r21638

Change History

comment:1 follow-up: ↓ 2 Changed 11 years ago by kimoto

LC_Page::destroyにsession_write_close()を追記することで動作することを確認していますがコミットしても大丈夫でしょうか?

comment:2 in reply to: ↑ 1 Changed 11 years ago by Seasoft

EC-CUBE は APC との相性の悪さが指摘されていたので、対応に向けた具体的な改修は興味深いですね。

LC_Page::destroyにsession_write_close()を追記することで動作することを確認していますがコミットしても大丈夫でしょうか?

LC_Page#destroy だと、ブロックを配置していると複数回呼ばれるといった事にはなりませんか?

comment:3 follow-up: ↓ 4 Changed 11 years ago by kimoto

確かに複数回呼ばれることにはなると思います

PHP5.2.9以前のものは自然にブロックの処理が終わるごとにSESSIONを保存していると思うので自然な動きではないでしょうか?

comment:4 in reply to: ↑ 3 Changed 11 years ago by Seasoft

PHP5.2.9以前のものは自然にブロックの処理が終わるごとにSESSIONを保存していると思うので自然な動きではないでしょうか?

本当にそんな動作になっていたのですか!? それは、非常に良くない予感。#571 の解決にも繋がりそうな情報です。興味深い。
(う~ん、でも #571 での調査情報と矛盾するような。バージョン違うので、その辺りの影響もあるかもしれませんね。)

少なくとも、最後にまとめて複数 WRITE するのは、余計に状況を悪くする気もします。
(READ WRITE READ WRITE が READ READ WRITE WRITE になるということですよね?)

ちなみに、過去に MDB2 を読み込んだ事実を APC によって抹消されていそうな動作ですが、エラー箇所の直前で require_once とかで再度読み込むなどでは対応できないですかね。

comment:5 follow-ups: ↓ 6 ↓ 11 Changed 11 years ago by kimoto

勘違い、かもしれませんがresize_image.phpと同様、ブロックをinclude php で呼んでいる場合に別プロセスとして実行されSESSIONの読み書きもその中で行われていないのでしょうか?

 http://goo.gl/vXTRN ここの記事にもあるのですがPHPのバージョンが上がった際に open、read、write、closeが open、read、close、writeとなった為に起きている問題だと認識しています

     function SC_Helper_Session() {
         $this->objDb = new SC_Helper_DB_Ex();
         register_shutdown_function('session_write_close');
         session_set_save_handler(array(&$this, 'sfSessOpen'),
                                  array(&$this, 'sfSessClose'),
                                  array(&$this, 'sfSessRead'),
                                  array(&$this, 'sfSessWrite'),
                                  array(&$this, 'sfSessDestroy'),
                                  array(&$this, 'sfSessGc'));
     }

こう書くことでも一応動くことは確認しています またPHP5でしか書けませんが

    public function __destruct() 
    { 
        session_write_close(); 
    } 

こう書いてもAPCは動作するようです。 Callgraphを出力してみてるそれぞれ動作が大きく変わるのでどれが正しい書き方なのかが正直わからないところではあります。。

comment:6 in reply to: ↑ 5 Changed 11 years ago by Seasoft

勘違い、かもしれませんがresize_image.phpと同様、ブロックをinclude php で呼んでいる場合に別プロセスとして実行されSESSIONの読み書きもその中で行われていないのでしょうか?

だとしたら、個人的には結構衝撃的です。Smarty の実装を分析したことはないのですが、PHP の include や require で実装していると推測していました。(というか、今もそう信じたい。むしろ、信じてる。)

open、read、write、closeが open、read、close、writeとなった為に起きている問題だと認識しています

なるほど。勉強になります。

手法はともかく、ブロック使用時も、最後一発 WRITE になれば問題ないと思っています。問題の性質からすると、PHP 5 に依存しても、(PHP 4 の現状の動作を乱さなければ) 問題ないと思います。

comment:7 Changed 11 years ago by kajiwara

  • Milestone changed from EC-CUBE2.11.2 to EC-CUBE2.11.3(仮)

APCに関しては、結構根が深い可能性が高く、現状では解決していませんので、一旦マイナーバージョンの次期開発にチケットを移行したいと思います。

comment:8 Changed 11 years ago by kotani

  • Milestone changed from EC-CUBE2.11.3 to EC-CUBE2.11.4(仮)

comment:9 Changed 10 years ago by kotani

  • Milestone changed from EC-CUBE2.11.5 to EC-CUBE2.12.0alpha

comment:10 Changed 10 years ago by Seasoft

  • Version changed from 2.11.1 to 2.11.4
  • Description modified (diff)
  • Summary changed from EC-CUBE2.11.1+PHP5.3.6+APC3.1.6でAPCをonにするとSESSIONへの書き込みが出来ない不具合 to PHP+APC3.1でAPCをonにするとSESSIONへの書き込みが出来ない不具合

EC-CUBE 2.11.4 でも発現を確認。

comment:11 in reply to: ↑ 5 Changed 10 years ago by Seasoft

  • Owner changed from somebody to Seasoft
  • 修正済み set
  • Status changed from new to assigned
  • Description modified (diff)

その後、私どもの顧客環境でも本件問題に遭遇することが数事例ありました。とりあえずは、APC の設定変更で回避していますが、やはり APC に対応できるのは理想だとは思います。

register_shutdown_function で処理するのは問題無さそうです。(素の PHP でも write 一発である事を確認した。)

また、 最新の PHP マニュアル を見ると、むしろ register_shutdown_function で対応するのは、素の EC-CUBE であっても適切なようです。

comment:12 Changed 10 years ago by h_yoshimoto

  • Status changed from assigned to closed
  • Resolution set to 修正済

EC-CUBE 2.12(r21950) + PHP 5.3.8 + APC 3.1.9 にて再現しない事を確認しました。

一旦閉じさせて頂きます。ありがとうございました。

Note: See TracTickets for help on using tickets.