新年第一单,竟然不是数据库直接相关的工作,是怎样删除大文件的内容.
有位客户突然来电说mongodb 硬盘爆满发现log文件已经达到634G,怎么处理。mongodb这个简单 可以通过方式截断日志,
如下:
use admin;
db.adminCommand( { logRotate : 1 } );
截断完之后返现日志文件大概有600G!
现在难题来了,平时习惯用我们删除文件基本都是rm -rf删除系统,当使用rm -rf xxxx.log删除后,使用df -h发现空间并未释放情况
lsof | grep delete
kill -9 xxx
但是觉得这样不安全。
比如文件被进程锁定,或者有进程一直在向这个文件写数据等等。
要理解这个问题,就需要知道Linux下文件的存储机制和存储结构。空间还没释放,就是因为进程一直无法处理这个文件,导致Linux还认为存在这个文件,导致不能释放。
下面是通过自己试验和互谅网上查询整理的方式:
1)清空或者让一个文件成为空白的最简单方式,是像下面那样,通过 shell 重定向 null (不存在的事物)到该文件:
# > access.log
使用 ‘true’ 命令重定向来清空文件
下面将使用 : 符号,它是 shell 的一个内置命令,等同于 true 命令,它可被用来作为一个 no-op(即不进行任何操作)。
另一种清空文件的方法是将 : 或者 true 内置命令的输出重定向到文件中,具体如下:
: > access.log
或
true > access.log
使用 cat/cp/dd 实用工具及 /dev/null 设备来清空文件
cat /dev/null > access.log
dd if=/dev/null of=access.log
使用 echo 命令清空文件
echo “” > access.log
或者
echo > access.log
使用 truncate 命令来清空文件内容
truncate 可被用来将一个文件缩小或者扩展到某个给定的大小。
你可以利用它和 -s 参数来特别指定文件的大小。要清空文件的内容,则在下面的命令中将文件的大小设定为 0:
truncate -s 0 access.log
6.rsync清空文件
–delete-before 接收者在传输之前进行删除操作
rsync-a –delete-before –progress –stats /root/blank.txt /root/nohup.out
为什么rsync能够快速删除大文件
1、rm命令大量调用了lstat64和unlink,可以推测删除每个文件前都从文件系统中做过一次lstat操作。过程:正式删除工作的第一阶段,需要通过getdirentries64调用,分批读取目录(每次大约为4K),在内存中建立rm的文件列表;第二阶段,lstat64确定所有文件的状态;第三阶段,通过unlink执行实际删除。这三个阶段都有比较多的系统调用和文件系统操作。
2、rsync所做的系统调用很少:没有针对单个文件做lstat和unlink操作。命令执行前期,rsync开启了一片共享内存,通过mmap方式加载目录信息。只做目录同步,不需要针对单个文件做unlink。
另外,在其他人的评测里,rm的上下文切换比较多,会造成System CPU占用较多——对于文件系统的操作,简单增加并发数并不总能提升操作速度。
注意:执行命令之后用iostat 和 top查看服务器状态,是否稳定,如出现指标上升应该强制停掉。
最终使用cat /dev/null > access.log 1~2秒处理了问题。