如何在不计数的情况下确定目录中有多少个文件?

如何在不计数的情况下确定目录中有多少个文件?

我在高流量网络服务器上遇到了相当严重的问题。 PHP 页面速度明显减慢,并且这似乎只是访问会话或引用数据库中的某个表的页面上的问题。在“/var/log/messages”日志文件中,我看到数十万条以下错误:“内核:EXT4-fs 警告(设备 dm-0):ext4_dx_add_entry:目录索引已满!”

我怀疑 '/var/lib/php/sessions' 存在瓶颈,因为我无法在 Filezilla 中打开该文件夹,并且无法使用 grep 计算文件/子目录的数量。虽然这很可能是硬盘损坏的情况,但我想首先通过检查该目录内的文件数量来验证我的预感。

您如何在不实际计算文件夹中文件数量的情况下查找文件夹中的文件数量?

答案1

目录的大小(如 所示ls -ld /var/lib/php/sessions)可以给出指示。如果文件很小,那么文件就不会很多。如果它很大,那么那里可能有很多条目,或者过去可能有很多条目。

只要不stat单独列出文件,列出内容不会比读取相同大小的文件花费更长的时间。

可能发生的情况是您有一个lsdosls -F或 的别名ls --color。这些选项会导致lstat对每个文件执行系统调用,以查看它们是否是文件或目录。

您还需要确保列出点文件并且使文件列表保持未排序。为此,请运行:

command ls -f /var/lib/php/sessions | wc -l

如果没有太多文件名具有换行符,那么这应该可以给您一个很好的估计。

$ ls -lhd 1
drwxr-xr-x 2 chazelas chazelas 69M Aug 15 20:02 1/
$ time ls -f 1 | wc -l
3218992
ls -f 1  0.68s user 1.20s system 99% cpu 1.881 total
wc -l  0.00s user 0.18s system 9% cpu 1.880 total
$ time ls -F 1 | wc -l
<still running...>

您还可以通过从 的输出中使用的 inode 数量减去文件系统中其他位置的唯一文件数量来推断那里的文件数量df -i

例如,如果文件系统安装/var在 GNU 上find

find /var -xdev -path /var/lib/php/sessions -prune -o \
  -printf '%i\n' | sort -u | wc -l

查找不在 /var/lib/php/sessions 中的文件数量。如果将其减去IUsed输出中的字段df -i /var,您将得到链接到的文件数量的近似值(因为某些特殊 inode 未链接到典型 ext 文件系统中的任何目录),而这些文件在/var/lib/php/sessions其他任何地方都没有链接(请注意, /var/lib/php/sessions 很可能包含同一文件的十亿个条目(实际上,文件上的最大链接数将比大多数文件系统上的链接数要低得多),因此该方法是并非万无一失)。

请注意,如果读取目录内容应该相对较快,则删除文件可能会非常慢。

rm -r,删除文件时,首先列出目录内容,然后调用unlink()每个文件。对于每个文件,系统都必须在这个巨大的目录中查找该文件,如果不对其进行哈希处理,其成本可能会非常昂贵。

答案2

我想你可以ls -1 /var/lib/php/sessions | wc -l通过 SSH使用

请注意,它是ls -(one)并且ws -(letter l)

答案3

在 ext2/3/4 中,您可以根据目录本身的大小进行一些近似。这不是很准确,但允许在不“计数”的情况下进行有根据的猜测。

默认情况下,目录从 4096 字节开始。当它获得更多条目时,它的大小会增大(但永远不会再缩小)。经过一些测试,发现每个条目占用 12 个字节,并且当达到限制时会增长 4096。这意味着,如果当前目录大小为 16384,则一次有 1,024 到 1,365 个条目。

还有一个技巧可以立即查看这些目录中的文件。当您运行时ls,将读取整个目录,然后进行排序。您可以使用 禁用排序ls -1U

相关内容