如何使ext3 / linux上的`rm`更快?


32

我已经使用默认选项安装了ext3文件系统。在上面,我有一些〜100GB的文件。

删除任何此类文件都需要很长时间(8分钟),并且会导致大量io流量,这会增加服务器上的负载。

有什么方法可以使公司不那么混乱?


4
基本上,这里没有方法可行,因此我们开发了自己的方法。在此处进行了描述:depesz.com/index.php/2010/04/04/how-to-remove-backups

Answers:


14

最有趣的答案最初埋在对该问题的评论中。这是使它更加可见的一流答案:

基本上,这里没有方法可行,因此我们开发了自己的方法。在此处进行了描述:http : //www.depesz.com/index.php/2010/04/04/how-to-remove-backups/ – depesz 2010年4月6日15:15

该链接是对探索和发现可行解决方案的难以置信的全面分析。

另请注意:

文章说:

如您所见,我-c2 -n7对ionice 使用了选项,这似乎很理智。

的确如此,但用户TafT表示,如果您不希望受到干扰,那么-c3“空转”将比-c2“尽力而为” 更好。他曾经-c3在后台进行构建,并且发现它可以很好地工作而不会导致构建一直等待。如果您确实有100%的io使用率,-c3则不会让删除操作完全完成,但是他不希望这是您根据实际测试得出的结果。


18

升级到ext4或其他使用扩展区的现代文件系统。由于ext3使用间接块方案而不是扩展数据块,因此删除大文件不可避免地需要大量工作。



4

就效率而言,每个文件使用一个rm并不是最佳选择,因为每个rm都需要fork和exec。

假设您有一个list.txt包含要删除的文件,这样做会更有效,但是仍然很慢:

xargs -i rm {} < list.txt

另一种方法是:( nice -20 xargs -i rm {} < list.txt
这将花费更少的时间,但是会大大影响您的系统:)

要么

我不知道这有多快,但是:

mv <file-name> /dev/null 

要么

使用快速文件系统(使用循环设备?)创建一个特殊的挂载点,并使用该挂载点存储和删除庞大的文件。
(也许在删除文件之前将文件移到那里,也许速度更快,或者当您希望文件消失时只是将其卸载)

要么

cat /dev/null > /file/to/be/deleted(现在大小为零),如果您希望它rm -rf <file>现在消失

或者甚至更好

放下猫,然后做 # > /file/to/be/emptied


好吧,我要删除1个文件,所以没有开销。


1

我在以合理的速度删除目录时遇到了问题,结果是进程锁定了磁盘并创建了尝试访问磁盘的大量进程。ionice不能正常工作,它只是继续使用99%的磁盘IO并将所有其他进程锁定。

这是对我有用的Python代码。它一次删除500个文件,然后休息2秒钟让其他进程执行其工作,然后继续。效果很好。

import os, os.path
import time

for root, dirs, files in os.walk('/dir/to/delete/files'):
    file_num = 0
    for f in files:
        fullpath = os.path.join(root, f)
        os.remove(fullpath)
        if file_num%500 == 1:
            time.sleep(2)
            print "Deleted %i files" % file_num
        file_num = file_num + 1

1
在ext3文件系统上的100G +文件上尝试一下。问题在于单个文件的大小,而不是文件数。

就您而言,这似乎行不通。但是我有很多小文件。感谢您的反馈。
尼克·伍德汉姆斯

1

我的两分钱。

我已经有这个问题了。“在必须快速运行的顺序脚本中,该过程确实删除了很多文件” ..因此,“ rm”将使该脚本速度接近IO等待/执行时间。

为了使事情更快,我添加了每个cron启动的另一个进程(bash脚本)。像垃圾收集器一样,它删除特定目录中的所有文件。

然后,我通过用mv将“ rm”替换为“垃圾文件夹”来更新了原始脚本(通过在文件名的末尾添加一个计数器来重命名文件以避免冲突)。

这对我有用,脚本运行至少快3倍。但是仅当垃圾文件夹和原始文件位于同一安装点(同一设备)下以避免文件复制时,该方法才有效。(同一设备上的mv消耗的IO低于rm)

希望有帮助。


0

还要注意,丹尼斯·威廉姆森(Dennis Williamson)的答案(建议将ionice作为负载的一种解决方法)仅在您的块设备使用CFQ io调度程序时才有效。


0

您可以尝试创建一个循环文件​​系统来存储备份。

# dd if=/dev/zero of=/path/to/virtualfs bs=100M count=1024 # 100 MB * 1024 = 100 GB
# mke2fs /path/to/virtualfs
# mount -t ext2 /path/to/virtualfs /mnt/backups -o loop

然后,当您要清除备份时:

# umount /mnt/backups
# mke2fs /path/to/virtualfs
# mount -t ext2 /path/to/virtualfs /mnt/backups -o loop

快点!整个虚拟文件系统很快就会被清除。


不能解决问题,因为只有当我想删除给定文件系统上的所有备份时,它才起作用。

0

您可以使用多头蒙山xargs

find . -type f | xargs -P 30 rm -rf 

其中30是要创建的线程数。如果使用零,则系统将创建可供执行任务的用户使用的最大线程数。


1
find有一个-delete选择,这是一个更好的选择。
阿里尔

0

mv <文件名> / dev / null

/ dev / null是文件而不是目录。无法将文件移到文件中,否则可能会覆盖它。

使用快速文件系统(使用循环设备?)创建一个特殊的挂载点,并使用该挂载点存储和删除您的大文件。(也许在删除文件之前将文件移到那里,也许速度更快,或者当您希望文件消失时只是将其卸载)

我认为这不切实际。与OP相比,它将不必要地使用更多的I / O。


-1

/ dev / null是文件而不是目录。无法将文件移到文件中,否则可能会覆盖它。

实际上,这是一种设备,写入其中的所有数据都会被丢弃,因此mv <file> /dev/null很有意义


在类似Unix的操作系统中,免费百科全书来自Wikipedia,/ dev / null或null设备是一个特殊文件,该文件会丢弃所有写入其中的数据(但报告写操作成功),并且不向任何进程提供任何数据从中读取(立即产生EOF)。[1]


1
这是错误的,而且非常危险。/ dev / null是设备,它是一个类似于文件的特殊对象。如果您是root用户,则“ mv / some / file / dev / null”将删除特殊的/ dev / null设备并将文件移动到那里!因此,下一次有人尝试使用/ dev / null时,他们将使用真实文件而不是设备,从而导致灾难。(当Wikipedia说“丢弃所有写入它的数据”时,这意味着“ cat / some / file> / dev / null”将读取/ some / file并丢弃您读取的数据,但这不会影响原始文件)。
user9876 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.