つっこみ

つっこみ欄にコメントを記載して[つっこむ]ボタンを押してください。
お名前欄の記載は省略できます。

お名前 :
←ここのテキストボックスはスパム対策用なので何も入力しないでください
つっこみ :

[キャンセル]


つっこみ先の記事

・ 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に達するにはだいぶ時間的余裕があるはずなので、例によってよくわからない問題は先送りするのでした(笑)。

# そのうち普通に使えるようになることを願おう・・・

■この記事への permanent link URL(下にいくほどファイルサイズが大きくなります)
  http://toriyu.jp/hitorigoto/id1415.html
  http://toriyu.jp/hitorigoto/2005-02-04.html (1日分)
  http://toriyu.jp/hitorigoto/2005-02.html#id1415 (1ヶ月分)