ひとりごと

新しい記事:[1416]  古い記事:[1414] 表示単位 :

ついったー[おとなり日記] かがみさん Y.Kumagaiさん

2005/02/04 (金)

・ integerの罠

うちの WWWサーバのログは PHP を使って PostgreSQL に食べさせて検索とかしやすいようにしています。増殖するテキストを食べさせるのに適当な方法が思いつかなかったので、~適当なタイミングでログを一行ずつ読込み、最後までいったら次回シークすべきところを記録して終了する~という方法をとっています。

それはそれで良いのですが、どうも長く使っていると動かなくなるときがあります。ログファイルが大きくなると動かなくなるみたいなので前におかしくなったときは grep でローカルアドレスからのアクセスを排除して小さくした記憶があるのですが、ちょっと原因を調べてみました。

%ls -l /var/log/httpd-access.log
-rw-r--r-- 1 root wheel 2150278654 Feb 4 09:15 /var/log/httpd-access.log
うむむむ、このサイズが非常に怪しいですね。でもって次回アクセスのために記録している場所はPostgreSQLのテーブルなのですが、この定義が 'integer' になっていました。で、PostgreSQLのマニュアルを見ますと、integer は 4バイト符号付のことで、長いものはbigintというのがあるのだそうです。さっそくテーブルを書き換えて再度試してみました。

やっぱりうごきません

むむむ、こしゃくな。なんかよくわかんないので、始めにファイルサイズを調べているところだけ抜き出してみました。

% php -r 'echo filesize("/var/log/httpd-access.log");'
-2144688642

あれま、原因はこれでしたか。PHPは型に関してかなりいいかげんで宣言文もないからどうやったらいいのかな~とか思いつつも無理やりキャストしてもやっぱりうまくいきません。で、うちの手元のマニュアルには記述がなかったのですが、本家の最新マニュアルには下記のようにありました。

注意: PHPの数値型は符号付整数であり、多くのプラットフォームでは32ビットの整数を取るため、 filesize()は2GBより大きなファイルについては期待とは違う 値を返すことがあります。2GBから4GBのサイズのファイルについては sprintf("%u", filesize($file))を使うことで打開されます。
ふむふむ、こういう書き方をしているってことは、まっとうな回避方法は存在しないということですな。PHPには長い整数の概念が無いのかな? 再コンパイルすれば回避できる可能性はありますが、つられて軒並みパフォーマンスが下がるような気もします。ということで、現在2GBのファイルが4GBに達するにはだいぶ時間的余裕があるはずなので、例によってよくわからない問題は先送りするのでした(笑)。

# そのうち普通に使えるようになることを願おう・・・
[つっこみ]

新しい記事:[1416]  古い記事:[1414] 表示単位 :
※このページへのリンクは自由です。リンクの方法については[つっこみ]で表示されるページの最後をごらんください。
たかたに(takatani@mars.dti.ne.jp)