Soluzione 1:
Ciò è probabilmente dovuto al fatto che, anche se si tronca il file, il processo di scrittura sul file continuerà a scrivere a qualsiasi offset si trovasse alla fine. Quindi quello che sta succedendo è che logrotate tronca il file, la dimensione è zero, il processo scrive di nuovo nel file, continuando dall'offset che aveva interrotto, e ora hai un file con byte NULL fino al punto in cui lo hai troncato più il nuovo voci scritte nel registro.
od -c dopo troncamento + crescita improvvisa, output generato sulla falsariga di:
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>
Ciò che dice è dall'offset 0 a 33255657600 il tuo file è costituito da byte nulli e quindi da alcuni dati leggibili. Arrivare a questo stato non richiede lo stesso tempo necessario per scrivere effettivamente tutti quei byte nulli. I filesystem ext{2,3,4} supportano qualcosa chiamato file sparse, quindi se cerchi oltre una regione di un file che non contiene nulla, si presume che quella regione contenga byte null e non occuperà spazio su disco. Quei byte nulli non verranno effettivamente scritti, si presume che siano lì, quindi il tempo necessario per passare da 0 a 3,5 GB non richiede molto tempo. (Puoi testare la quantità di tempo necessaria facendo qualcosa come dd if=${HOME}/.bashrc of=largefile.bin seek=3432343264 bs=1
, questo dovrebbe generare un file di oltre 3 GB in pochi millisecondi).
Se esegui ls -ls
sui tuoi file di registro dopo che sono stati troncati e hanno avuto di nuovo una crescita improvvisa, ora dovrebbe riportare un numero all'inizio della riga che rappresenta la dimensione effettiva (in blocchi occupati sul disco), che probabilmente è di ordini di grandezza inferiore al dimensione riportata solo da ls -l
.
Soluzione 2:
Sono estremamente fiducioso che Kjetil l'abbia colpito. Drew, potresti non essere ancora convinto dalla sua spiegazione, ma ti esorto a leggere attentamente ciò che ha detto.
Se lo accetti, la correzione consiste nell'arrestare e riavviare l'applicazione quando i registri vengono ruotati o utilizzare uno strumento come "rotatelogs" di Apache, in cui si invia l'output del registro allo strumento tramite una pipe e lo strumento si prende cura di ruotando il file di registro ogni tanto. Ad esempio, una delle mie istanze di apache accede con
ErrorLog "|/usr/sbin/rotatelogs /www/logs/error_log 604800"
che causa molti file di registro con nomi come
-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
apparire senza riavviare apache; Posso quindi comprimerli manualmente dopo il fatto. Nota come la rotazione viene eseguita ogni settimana, ovvero ogni 604800 secondi, essendo questo l'argomento passato a rotatelogs
.
Se non riesci a fermare e riavviare l'app e non può accedere tramite una pipe, allora penso che tu abbia un vero problema. Forse altri avranno suggerimenti.