这是我的原创的个人心得,若有纰漏,多多指教
更多内容可以访问我的博客
前言
公司有台服务器产生太多临时文件,同事在删除文件的时候,说使用 rsync 会更快一些,使用 rm 可能会把机器搞挂,还引用网上一篇文章说
“rsync所做的系统调用很少:没有针对单个文件做lstat和unlink操作。命令执行前期,rsync开启了一片共享内存,通过mmap方式加载目录信息。只做目录同步,不需要针对单个文件做unlink”
我对此抱有好奇与怀疑,在我的Linux知识中,从 Linux 中删除文件,需要是文件的硬连接数n_link归零、进程正在打开该文件的数n_count归零,才可以触发文件系统对 inode 与对应磁盘块的回收,实现删除操作。这是金科玉言,彻底删除文件的系统调用必然用到 unlink 与 close。
对于网传的理论,我在互联网上仔细搜索,发现太多转载的雷同的文章,却没有精华文章对上面的话做详细的解释。我决定自己研究下
删除大量文件的方法
网传这样的方法
例如删除某目录下一万个以上小文件,使用 rm * -rf
,既有操作上的风险,又耗时。
建议使用 rsync
mkdir /tmp/blank_dir
rsync --delete-before -a -H -v /tmp/blank_dir/ target_dir
- 先建立空目录,再同步空目录到目标目录
- 注意以上命令中 blank_dir 后带
/
rsync 选项说明:
–delete-before 接收者在传输之前进行删除操作
–progress 在传输时显示传输过程
–a 归档模式,表示以递归方式传输文件,并保持所有文件属性
–H 保持硬连接的文件
–v 详细输出模式
–stats 给出某些文件的传输状态
为什么删除一万个文件以上, rsync 比 rm 快
从根本入手,直接查看系统调用情况,于是动手测试
实验环境:Linux Arch 4.19
创建一定数量的空白文件,分别使用 rm 与 rsync 删除,并使用 strace -c
统计系统调用,需要额外注意的是 rsync 在本地使用了三个进程(generator, sender, receiver),所以需要 -f
选项告诉 strace 同时跟踪所有fork和vfork出来的进程。(由于 strace 输出的信息太多,为了阅读体验,打印详情在附录)
第一次,创建10个文件,分别删除,查看统计输出
查看 rm 的系统调用,耗时0.000000,总次数62
for i in $(seq 10); do touch tmp_$i;done
strace -c rm * -rf
查看 rsync 的系统调用,总耗时0.008647,总次数365
for i in $(seq 10); do touch tmp_$i;done
strace -c -f rsync --delete -a -H ../blank_dir/ ./
因为10个文件的删除,几乎看不到时间,我第二次测试,删除一万个文件,结果:
rm 的系统调用,总耗时0.201209,总次数20063
rsync 的系统调用,总耗时0.625734,总次数20374
从这个结果来看,似乎 rsync 比 rm 要慢,这里有我使用 strace -f
统计 rsync 三个进程总耗时的原因,改用使用 time 命令来计时,删除一万个文件以上,rsync 确实是比 rm 快上一些,那是因为我电脑cpu在三个以上,三个进程的rsync当然快一些
我的结论
网传的 “删除多个文件,rsync 比 rm 快” 的方法,我认为不一定准确,理由如下:</