处理大量小文件

新建 1000000 个文件,可以使用下面脚本:

#!/bin/bash
while [ "$i" != "1000000" ]
do
    touch $i
   i=$(($i+1))
done

或者使用 @shellxy 大神的一句话:

# touch `seq 1000000`

不过速度都不是很快。在新建的过程中有可能出现:

touch: cannot touch `xxxxxxx': No space left on device

# df -i
Filesystem  Inodes   IUsed   IFree IUse% Mounted on
/dev/sda1     1048576 1038575   10001  100% /

可以发现 /dev/sda1 这个文件系统的 inode 表用完了。再 df 看看:

# df -Th
Filesystem Size  Used Avail Use% Mounted on
/dev/sda1     3.9G  3.5G  198M  95% /

即使还有 200M,也没用,因为一个 inode 至少要有一个 block 来记录信息,现在 inode 用完了,再多的 data block 也没用,更详细的解释可以看这里

可以 cp 些文件试试:

# cp /root/bigfile /root/t
cp: cannot create regular file `/root/t/bigfile': No space left on device

# pwd
/root
# ll
drwxr-xr-x  2 root root 19349504 Jun 19 10:46 t/
# df -i
Filesystem  Inodes   IUsed   IFree IUse% Mounted on
/dev/sda2     1106496  976    1105520  1% /var
# mkdir /var/test
# cp -av t/* /var/test/
-bash: /bin/cp: Argument list too long
# mv t/* /var/test/
-bash: /bin/mv: Argument list too long

可以使用如下方式:

# find ./t -type f -exec cp {} test \;
# find ./t -type f | xargs [-n 100] cp {} ./test

最后删除建议不要使用 rm -rf * 来删除,这样一来速度非常非常慢,二来可能出现下面的提示:

# rm -rf /root/t
-bash: /bin/rm: Argument list too long

新建一个空目录,使用 rsync 间接删除:

# mkdir /root/test
# rsync -a –delete-before  /tmp/test/    /root/t

或者:

# find /root/t -type f -exec rm -rf {} \;

避免出现此类问题?目前想到的是重做文件系统(LVM?RAID?)。如果该系统上会产生像上面那样 10000000 类似的小文件,在选择  data block 时可以选的小些;如果都是大文件,选择 4K 的就可以了。Linux 默认选的是 4K。