First and foremost, I just wanted to thank you Tom for this excellent site. It's proven to be a truly invaluable resource for so many of us.
My comment is about Paul's post above. Here's a quick recap:
>I have a good solution for this:
>if the file name is ABC.trc
>just do:
>echo "" > ABC.trc
>it will shrink the file and the process will continue to >write to it but you will not run out of space!
I have tested this extensively on Linux, and believe Paul may be correct. I understand this may seem more of an OS topic, but it also has direct relevance to Oracle, when dealing with management of the alert log. Here are my steps to reproduce:
It will take two windows. Steps of which are identified below. I am using the Bash shell:
[ window 1 ]
jaclyn:/# df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 16G 14G 2.0G 87% /
The thing to note here is the amount of free space. 2.0G in this case. Let's simulate a 1G log file:
[ window 1 ]
jaclyn:/# dd if=/dev/sda of=temp.txt bs=8192 count=131072
This may take a few minutes, depending on the speed of your machine. In the meantime, you can verify fuser actually works in another window:
[ window 2 ]
jaclyn:/# fuser -v /temp.txt
USER PID ACCESS COMMAND
/temp.txt: root 17409 F.... dd
From this we can see the dd command has the file open for writing (that's what the capital F in access refers to)
Now wait for dd to finish:
[ window 1 ]
jaclyn:/# dd if=/dev/sda of=temp.txt bs=8192 count=131072
131072+0 records in
131072+0 records out
1073741824 bytes (1.1 GB) copied, 190.562 seconds, 5.6 MB/s
Check the free space now (should be 1G less):
[ window 1 ]
jaclyn:/# df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 16G 15G 1018M 94% /
And it is (now only 1018M or ~1G). Please keep in mind I am the only one on this system, and not performing any other tasks.
Here I have a small routine in C that will open a file read/write, and print out it's size and the SEEK_END position every 5 seconds:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
int main(int argc, char **argv) {
int fd;
unsigned pos;
struct stat stats;
if (argc != 2)
exit(1);
if ((fd = open(argv[1], O_RDWR)) == -1) {
perror("Error in open()");
exit(1);
}
while(1) {
if ((pos = lseek(fd, 0, SEEK_END)) == -1)
perror("Error in lseek()");
else
printf("lseek to %u\n", pos);
if (fstat(fd, &stats))
perror("Error in fstat()");
else
printf("size = %u\n", stats.st_size);
printf("\n");
usleep(5000000);
}
}
Compile and start the program:
[ window 1 ]
jaclyn:/# gcc open_and_seek.c
jaclyn:/# ./a.out temp.txt
lseek to 1073741824
size = 1073741824
lseek to 1073741824
size = 1073741824
Let this run in window 1, and now truncate the file in window 2:
[ window 2 ]
jaclyn:/# > /temp.txt
Let's now go back and look at window 1:
[ window 1 ]
lseek to 0
size = 0
lseek to 0
size = 0
Also try this in window 2:
[ window 2 ]
jaclyn:/# df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 16G 14G 2.0G 87% /
The space is indeed reclamed, and fuser will prove the file is
still open for writing:
[ window 2 ]
jaclyn:/# fuser -v /temp.txt
USER PID ACCESS COMMAND
/temp.txt: root 17433 F.... a.out
It may also be interesting to note exactly what ` > <file> ' does:
jaclyn:/# strace -e trace=open /bin/bash -c '> /test.txt' 2>&1 | grep test.txt
open("/test.txt", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
Apparently opening for truncation (O_TRUNC) directly affects other processes that already have this file open. I should also note that if you
remove or
delete the file, then the behavior
is as Tom suggested -- that is, the space will not really be freed until all file handles are released.