解決策 1:
これはおそらく、ファイルを切り捨てても、ファイルへの書き込みプロセスが最後にあったオフセットで書き込みを続行するためです。何が起こっているのかというと、logrotate がファイルを切り捨て、サイズがゼロで、プロセスがファイルに再度書き込み、中断したオフセットで続行し、切り捨てた時点までの NULL バイトと新しいファイルができたということです。ログに書き込まれたエントリ。
od -c 切り捨て + 急激な成長の後、次の行に沿って生成された出力:
0000000 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
*
33255657600 \0 C K B - s e r v e r [ h t t
33255657620 <more log output>
これが言っているのは、オフセット 0 から 33255657600 までのファイルがヌル バイトといくつかの判読可能なデータで構成されているということです。この状態に到達するのに、これらすべての null バイトを実際に書き込むのにかかる時間と同じ時間はかかりません。 ext{2,3,4} ファイルシステムはスパース ファイルと呼ばれるものをサポートしているため、何も含まれていないファイルの領域を超えてシークすると、その領域にはヌル バイトが含まれていると見なされ、スペースを占有しません。ディスク上。これらのヌルバイトは実際には書き込まれず、そこにあると想定されるため、0 から 3.5GB に移動するのにかかる時間はそれほどかかりません。 ( dd if=${HOME}/.bashrc of=largefile.bin seek=3432343264 bs=1
のようなことを行うことで、かかる時間をテストできます 、これにより、数ミリ秒で 3GB を超えるファイルが生成されます)。
ls -ls
を実行すると ログファイルが切り捨てられて再び急激に大きくなった後、実際のサイズ (ディスク上で占有されているブロック単位) を表す数値が行の先頭に報告されるはずです。これはおそらく、 ls -l
だけでサイズが報告されました .
解決策 2:
私は非常に Kjetilがヒットしたと確信しています。ドリュー、あなたは彼の説明にまだ納得していないかもしれませんが、彼の言ったことを注意深く読むことをお勧めします.
それを受け入れる場合、修正は、ログがローテーションされたときにアプリケーションを停止して再起動するか、Apache の「rotatelogs」のようなツールを使用してログ出力をパイプ経由でツールに送り、ツールが処理することです。ログファイルを頻繁にローテーションします。たとえば、私のApacheインスタンスのログの1つは
ErrorLog "|/usr/sbin/rotatelogs /www/logs/error_log 604800"
これにより、
のような名前のログファイルが大量に発生します。-rw-r--r-- 1 root root 4078 Dec 21 01:04 error_log.1292457600
-rw-r--r-- 1 root root 4472 Dec 29 08:41 error_log.1293062400
-rw-r--r-- 1 root root 78630 Jan 4 12:57 error_log.1293667200
-rw-r--r-- 1 root root 15753 Jan 12 01:10 error_log.1294272000
Apacheを再起動せずに表示する;後で手動で圧縮できます。 rotatelogs
に渡される引数である 604800 秒ごとに、毎週ローテーションがどのように行われるかに注意してください。 .
アプリを停止して再起動できず、パイプ経由でログに記録できない場合は、本当の問題があると思います.おそらく、他の人から提案があるでしょう。