N.Katoh
typer_jp****@yahoo*****
2006年 2月 12日 (日) 02:04:34 JST
加藤です。いろいろと。 新しい物がすきな方へのお願い cvsの方はとりあえず修正されています。人柱になっても良いという方は lib/Util.pm と plugin/attach/AttachHandler.pm を試してみて下さい。 #3.5.10にこの2つのファイルを上書きするだけでOKだと思います。 !!!注意!!! ただし、設定ファイルの書式を変更する修正が入っており、元に戻すと不具合が でる可能性があります。 Kinsanさんへのお返事。 まず、今回の事象を整理すると2つの問題がありました。 1. 他プロセスがファイル生成中の完全ではないファイルを読み込む。 2. 複数プロセスでファイル変更が競合し変更が反映されない。 追記の場合には1が起こる可能性はないに等しく、更新頻度の高いカウンタの機 能が変更になるまで問題が表面化しませんでした。2は以前から発生していたは ずですが、発生していても問題が表面化しにくく気付かれていませんでした。 On Sat, 11 Feb 2006 00:27:45 +0900 Kinsan <freel****@nifty*****> wrote: > Kinsanです。 > > 書き込み途中のファイルを読み込んでしまうことが問題ならば、 > 書き込む際に終端を表す文字を加えておけば、読む方ではセマフォ > 取らんでも良いように思います。 これは1の場合の解決方法ですね。 この方法では読み込んで終端文字がない場合は読み直すという事が必要になりま す。現状では追記ではないファイルはカウンタ機能を除いて圧倒的に参照する方 が多いため、あきさんのいつ読んでも完全な内容を保証するrenameの方が適して いると思います。 > もし、カウンターの数字のみを書き込むファイルならば、終端は > 改行文字で表すことにしても良いでしょう。 カウンタは2の方の対策もしなければならないという点があり、これだけでは不 足となります。 > 読む方のルーチンでは以下のように判断することにするのです。 > 1. 読み込みでopenする。openに失敗するならば、まだファイルが > ないか、他のプロセスが書き込み中と判断する。 > (必ず存在するはずのファイルならば、後者と判断。) > 2. ファイルの中身を読む。終端文字が無ければ、他のプロセスが > 書き込み中と判断する。 > > この方法で読み込み側でのロックを省略すれば、セマフォ(踏み切り) > が閉まっている時間が短くなると思います。 > > また、一般的にはUnix系ではディスクへのリードもライトもキャッ > シュしますので、リネームを使わない方法の方がキャッシュが有効 > に働き、レスポンスが良くなる可能性もあります。 先のように書き込み時にrenameを行なう事で1を防ぎ、読み込み側ではロックを 行なわないという手法で問題を解決しました。ただし、添付ファイルのカウンタ はこれだけでは不足のため、読み込み開始から書き込み完了までロックを行なう 方法をとっています。 その他の修正ヶ所候補について さて、書いている最中にログファイルに対策されていない事に気がつきましたが、 他にもありそうなので網羅的にあたってみました。落ちがあったらご指摘下さい。 探してみると意外に多くあって、ロック/アンロックをサブルーチン化した方が 良いかも知れません。 また、一時ファイル作成はmktempを使って、その場合はロックなしにした方が良 い気がしますが、どうでしょうか。 #あと、アップロードされたファイルはCGIモジュールの一時ファイルをそのま #ま使えると嬉しいのですけどね。 添付ファイルカウンタと同様な物 #新メソッドを使う Wiki::DefaultStorage::un_freeze_page (lib/Wiki/DefaultStorage.pm:489) 凍結ページの削除。 全クリアの可能性あり。 管理者のみが行なえるため発生の可能性はかなり低いが重要。 plugin::info::Counter::inline (plugin/info/Counter.pm:37) アクセスカウンタのカウントアップ。 カウンタクリア(ページ単位)の可能性あり。 ページ毎に別ファイルであるため発生の可能性はやや低い。 ファイルに追記するタイプ #おそらくロックのみでOKだと思う Wiki::DefaultStorage::freeze_page (lib/Wiki/DefaultStorage.pm:459) 凍結ページの記録。 追記モードで欠損の可能性あり。 管理者のみが行なえるため発生の可能性は低い。 plugin::editlog::EditLog::hook (plugin/editlog/EditLog.pm:44) 編集・削除時のログ記録。 追記モードで欠損の可能性あり。 編集・削除時のみであり発生の可能性は低い。 plugin::attach::AttachHandler::write_log (plugin/attach/AttachHandler.pm:201) 添付ファイルのアクセスログ記録。 追記モードで欠損の可能性あり。 plugin::core::ShowPage::write_log (plugin/core/ShowPage.pm:78) アクセスログ記録。 追記モードで欠損の可能性あり。 Util::debug (lib/Util.pm:597) デバッグログの出力。 追記モードで欠損の可能性あり。 通常は呼び出される事が無いが、デバッグ情報の欠損は嬉しくない。 空白ファイルを読む可能性のあるタイプ #一時ファイル作成→rename plugin::attach::AttachHandler::do_action (plugin/attach/AttachHandler.pm:60) アップロード実行時のデータファイル保存。 ファイル破壊・不完全ファイル読みだしの可能性あり。 ページ・ファイル名が一致する必要があり、衝突の可能性は低い。 plugin::rss::RSS::paragraph (plugin/rss/RSS.pm:52) 外部RSSデータのキャッシュ。 不完全ファイル読みだしの可能性あり。ファイル破壊の可能性も若干ある。 plugin::rss::RSSMaker::make_rss (plugin/rss/RSSMaker.pm:74) RSSファイルの作成。 不完全ファイル読みだしの可能性あり。ファイル破壊の可能性も若干ある。 plugin::rss::RSSMaker10::make_rss (plugin/rss/RSSMaker10.pm:213) RSSファイルの作成。 不完全ファイル読みだしの可能性あり。ファイル破壊の可能性も若干ある。 -- typer <typer_jp****@yahoo*****> like perl, stay FreeBSD http://freebsd.g.hatena.ne.jp/TransFreeBSD/ use fswiki http://aaa-www.net/~typer/cgi-bin/wiki.cgi/diary and named Noboru Katoh <typer****@chive*****> -- typer <typer_jp****@yahoo*****> like perl, stay FreeBSD http://freebsd.g.hatena.ne.jp/TransFreeBSD/ use fswiki http://aaa-www.net/~typer/cgi-bin/wiki.cgi/diary and named Noboru Katoh <typer****@chive*****>