Loading...

文章背景图

Linux下的文件清理

2026-04-17
0
-
- 分钟
|

在一般情况下备份文件等不用的文件时,可以直接使用rm -f,但是使用有时会有一些问题。所以这时会需要一些其他的方法

这里以nginx的access.log为例来进行操作。

先说直接删除然后创建可能会出现的问题,Linux和Windows不同,在Windows删除文件时,如果文件被占用,会直接拒绝删除,而Linux不会,Linux会文件系统中access.log的inode的磁盘引用数减一,当inode磁盘引用数和内存引用数都为零时,才会真正删除这个文件,nginx占用这个文件,access.log的内存引用数并不会减到0,而使用ls来查看看不到这个文件了,可以通过lsof|grep deleted来查看删除却任然被占用的文件,所以文件并没有被删除,而这时创建新的文件,Linux会给他分配一个新的indoe,nginx并没用使用新的inode,后续的日志仍然会写入老的inode下的文件,新的文件并不会有新的内容,删除的文件也不会被释放,需要重启nginx才能完全释放空间。所以出现删除大文件之后磁盘空间没有释放的清空可以lsof|grep deleted看一下是不是被占用。

echo "" > access.log

使用这个命令可以实现无需重启可以直接完成文件的清理,但是这个命令清空文件获得的文件大小并不是0,而是1,因为echo “”这个命令实际上是重定向一个换行符,所以这个命令在清空之后也会进行写入,如果io压力过大,echo ""首先进行文件元数据的清空,然后到文件中写入,会进行两次io操作

cat /dev/null > access.log

/dev/null是一个Linux中的特殊的文件设备,这个设备不会存储任何数据,读取也不会有输出,主要作用是将数据丢弃,这个操作可以直接将这个access.log文件大小变成0,而且只会修改元数据,不涉及到二次写入。

> access.log

这个命令和cat /dev/null的效果相同,效率会更高,这个命令可以少fork()一次,是Linux内置的命令。

truncate -s 0 access.log

这个命令可以将文件大小变成0,相当于文件清空,在多数情况下不会使用,但是这个命令可以不改变访问时间戳,在需要保留文件元数据的情况下可以使用。还有情况就是在清空的文件不是日志文件,在清空日志备份文件等大文件时,例如nginx服务开启了日志轮询,但是连续几天网站访问量过大,io压力很大,磁盘使用也很多,现在我需要临时清理一部分备份,备份文件也很大,如果直接使用>access.log.bak很有可能再次磁盘抖动,让当前服务写入直接卡死,可以使用这个命令通过循环的方式,让备份日志逐步释放,避免影响到正常业务。

评论交流

文章目录