因此,我从监控系统中的一个盒子上收到了一个警告,指出文件系统上的空闲索引节点的数量正在减少。

df -i输出显示以下内容:

Filesystem       Inodes  IUsed    IFree IUse% Mounted on
/dev/xvda1       524288 422613   101675   81% /


如您所见,根分区已使用了其索引节点的81%。
我怀疑它们都在单个目录中使用。但是如何找到它在哪里?

#1 楼

我在stackoverflow上看到了这个问题,但是我不喜欢任何答案,而且无论如何,这确实是一个问题。
基本上,文件系统中的每个文件都使用一个索引节点。因此,用尽inode通常意味着您周围有很多小文件。因此问题就变成了“哪个目录中包含大量文件?”
在这种情况下,我们关心的文件系统是根文件系统/,因此我们可以使用以下命令:
{ find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n; } 2>/dev/null

这将转储文件系统上每个目录的列表,并以该目录中的文件(和子目录)为前缀。因此,文件数量最多的目录将位于底部。
在我的情况下,出现以下内容:
   1202 /usr/share/man/man1
   2714 /usr/share/man/man3
   2826 /var/lib/dpkg/info
 306588 /var/spool/postfix/maildrop

因此,基本上/var/spool/postfix/maildrop正在消耗所有inode。 > *请注意,这个答案确实有三个需要注意的地方。它不能正确处理路径中带有换行符的任何内容。我知道我的文件系统没有带换行符的文件,并且由于这仅用于人类消费,因此潜在的问题不值得解决,可以始​​终将\n替换为-z,并对上述sortuniq命令使用head -zn10选项,例如以下:
{ find / -xdev -printf '%h
for i in `find . -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n
' |sort -z |uniq -zc |sort -zk1rn; } 2>/dev/null

您还可以在命令中添加-xdev以获取前10个最常用的inode。
如果文件分散在大量目录中,它也无法处理。但这不太可能,因此我认为风险可以接受。它还会多次计数到同一文件的硬链接(因此仅使用一个inode)。同样,不太可能产生误报*

我不喜欢stackoverflow答案中的任何答案的主要原因是它们都跨越了文件系统边界。由于我的问题是在根文件系统上,因此这意味着它将遍历每个已挂载的文件系统。将/mnt/foo扔到find命令上甚至无法正常工作。
例如,最受好评的答案是这样的:
如果将其更改为
for i in `find . -xdev -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n

,即使find . -xdev -type d是一个安装,它也是根目录文件系统,因此它会出现在ls -a $i中,然后传递给find,它将进入安装文件中。
我的答案中的q4312079q列出了安装文件中每个文件的目录。因此基本上具有如下文件结构:
/foo/bar
/foo/baz
/pop/tart

我们最终得到
/foo
/foo
/pop

,所以我们只需要计算重复行数即可。

评论


@MohsenPahlevanzadeh并不是我的答案的一部分,我是在评论为什么我不喜欢该解决方案,因为这是对该问题的常见答案。

–随钻
2014-2-26在18:23

使用绑定挂载是避免搜索其他文件系统的更可靠的方法,因为它允许访问挂载点下的文件。例如,假设我在/ tmp下创建了300,000个文件,然后将系统配置为在/ tmp上安装tmpfs。这样一来,仅凭find便无法找到文件。不太可能是senario,但值得注意。

– Graeme
2014年2月26日在18:25

两项工作都只需要删除sort,因为当输出足够大时sort需要创建一个文件,这是不可能的,因为我使用了100%的inode。

– qwertzguy
2015年8月6日,下午2:55

请注意,-printf似乎是要查找的GNU扩展,因为OS X中可用的BSD版本不支持它。

–熊佳亚诺夫
16年6月11日在19:19

所有文件都在一个目录中这一假设很困难。许多程序都知道单个目录中的许多文件性能不佳,因此会散列一两个目录级别

– PlasmaHH
18年7月10日在7:21

#2 楼

这是按请求方的请求从此处重新发布的:

du --inodes -S | sort -rh | sed -n \
        '1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/.../;p}'


如果要保留在同一文件系统中,请执行以下操作:

du --inodes -xS


以下是一些示例输出:

15K     /usr/share/man/man3
4.0K    /usr/lib
3.6K    /usr/bin
2.4K    /usr/share/man/man1
1.9K    /usr/share/fonts/75dpi
...
519     /usr/lib/python2.7/site-packages/bzrlib
516     /usr/include/KDE
498     /usr/include/qt/QtCore
487     /usr/lib/modules/3.13.6-2-MANJARO/build/include/config
484     /usr/src/linux-3.12.14-2-MANJARO/include/config


现在使用LS:

几个人提到他们没有up-最新的coreutils和--inodes选项对他们不可用。所以,这是ls:

ls ~/test -AiR1U | 
sed -rn '/^[./]/{h;n;};G;
    s|^ *([0-9][0-9]*)[^0-9][^/]*([~./].*):|:|p' | 
sort -t : -uk1.1,1n |
cut -d: -f2 | sort -V |
uniq -c |sort -rn | head -n10


如果您很好奇,那么regex的那乏味点儿的实质是在每个filename递归中替换ls's搜索结果以及找到它的目录名称。从那里开始,只需压缩重复的inode编号,然后计算重复的目录名称并进行相应排序即可。

-U选项对排序特别有帮助,因为它不会进行排序,而是以原始顺序(或以inode编号)显示目录列表。

当然,-1非常有用,因为它确保每行一个结果,无论文件名中可能包含换行符还是尝试解析列表时可能出现的其他不幸的问题。

当然,所有的-A和inode的-i以及递归的-R,这就是它的长短。

底层的方法是我替换每一个ls的文件名及其在sed中的包含目录名。接下来……嗯,我自己有点模糊。我可以肯定,它可以准确计数文件,如您在此处看到的:

% _ls_i ~/test
> 100 /home/mikeserv/test/realdir
>   2 /home/mikeserv/test
>   1 /home/mikeserv/test/linkdir


这为我提供了与du命令几乎相同的结果:

DU:

15K     /usr/share/man/man3
4.0K    /usr/lib
3.6K    /usr/bin
2.4K    /usr/share/man/man1
1.9K    /usr/share/fonts/75dpi
1.9K    /usr/share/fonts/100dpi
1.9K    /usr/share/doc/arch-wiki-markdown
1.6K    /usr/share/fonts/TTF
1.6K    /usr/share/dolphin-emu/sys/GameSettings
1.6K    /usr/share/doc/efl/html


LS:

14686   /usr/share/man/man3:
4322    /usr/lib:
3653    /usr/bin:
2457    /usr/share/man/man1:
1897    /usr/share/fonts/100dpi:
1897    /usr/share/fonts/75dpi:
1890    /usr/share/doc/arch-wiki-markdown:
1613    /usr/include:
1575    /usr/share/doc/efl/html:
1556    /usr/share/dolphin-emu/sys/GameSettings:


我认为include只是取决于程序首先查看的目录-因为它们是相同的文件,并且经过硬链接。有点喜欢上面的事情。我可能对此有误-我欢迎更正...

DU DEMO

% du --version
> du (GNU coreutils) 8.22


建立测试目录:

% mkdir ~/test ; cd ~/test
% du --inodes -S
> 1       .


某些子目录:

% mkdir ./realdir ./linkdir
% du --inodes -S
> 1       ./realdir
> 1       ./linkdir
> 1       .


制作一些文件:

% printf 'touch ./realdir/file%s\n' `seq 1 100` | . /dev/stdin
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .


一些硬链接:

% printf 'n="%s" ; ln ./realdir/file$n ./linkdir/link$n\n' `seq 1 100` | 
    . /dev/stdin
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .


查看硬链接:

% cd ./linkdir
% du --inodes -S
> 101

% cd ../realdir
% du --inodes -S
> 101


他们'单独计算,但转到一个目录...

% cd ..
% du --inodes -S
> 101     ./realdir
> 1       ./linkdir
> 1       .


然后我从下面运行了我的运行脚本,并且:

> 100     /home/mikeserv/test/realdir
> 100     /home/mikeserv/test/linkdir
> 2       /home/mikeserv/test


和Graeme的:

> 101 ./realdir
> 101 ./linkdir
> 3 ./


所以我认为这表明计数inode的唯一方法是使用inode。而且,由于对文件进行计数意味着对inode进行计数,因此您不能对inode进行双重计数-要对文件进行精确计数,就不能对inode进行多次计数。

评论


哪个版本添加了--inodes?哪个“变体” /“风味” /“ posix-wannabes” /“实现” /具有什么?

–n611x007
17年1月25日在1:42



Ubuntu 14.04.5:du:无法识别的选项'--inodes'

–普特尼克
17年7月18日在10:22

du(GNU coreutils)自2014年以来的版本8.23(在我过时的Debian Jessie中)。 Debian> Ubuntu为这个双关语感到抱歉:P Ubuntu的包太旧了...

–丹尼尔·W。
19年4月18日在11:43



#3 楼

我使用了SO Q&A中题为:我的所有inode都在哪里使用的答案?当我们的NAS大约2年前用完时:

$ find . -type d -print0 \
    | while IFS= read -rd '' i; do echo $(ls -a "$i" | wc -l) "$i"; done \
    | sort -n


示例

$ find . -type d -print0 \
    | while IFS= read -rd '' i; do echo $(ls -a "$i" | wc -l) "$i"; done \
    | sort -n
...
110 ./MISC/nodejs/node-v0.8.12/out/Release/obj.target/v8_base/deps/v8/src
120 ./MISC/nodejs/node-v0.8.12/doc/api
123 ./apps_archive/monitoring/nagios/nagios-check_sip-1.3/usr/lib64/nagios
208 ./MISC/nodejs/node-v0.8.12/deps/openssl/openssl/doc/crypto
328 ./MISC/nodejs/node-v0.8.12/deps/v8/src
453 ./MISC/nodejs/node-v0.8.12/test/simple


检查设备的Inodes

取决于您的NAS,它可能无法提供功能全面的df命令。因此,在这些情况下,您可以改为使用tune2fs

$ sudo tune2fs -l /dev/sda1 |grep -i inode
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super huge_file uninit_bg dir_nlink extra_isize
Inode count:              128016
Free inodes:              127696
Inodes per group:         2032
Inode blocks per group:   254
First inode:              11
Inode size:           128
Journal inode:            8
Journal backup:           inode blocks


跨文件系统边界

您可以使用-xdev开关将find定向到将搜索范围缩小到仅启动搜索的设备。

示例

假设我通过我的NAS通过NFS共享自动挂载了/home目录,其名称为mulder

$ df -h /home/sam 
Filesystem            Size  Used Avail Use% Mounted on
mulder:/export/raid1/home/sam
                      917G  572G  299G  66% /home/sam


注意,安装点仍被认为是系统本地的。

$ df -h /home/ .
Filesystem            Size  Used Avail Use% Mounted on
-                        0     0     0   -  /home
/dev/mapper/VolGroup00-LogVol00
                      222G  159G   52G  76% /


现在,当我启动find

$ find / -xdev  | grep '^/home'
/home


发现/home但没有自动装入的内容,因为它们位于不同的设备上!

文件系统类型

您可以使用find-fstype的开关来控制find将查找哪种类型的文件系统。

   -fstype type
          File is on a filesystem of type type.  The valid filesystem types 
          vary among different versions of Unix; an incomplete list of 
          filesystem  types that are accepted on some version of Unix or 
          another is: ufs, 4.2, 4.3, nfs, tmp, mfs, S51K, S52K.  You can use 
          -printf with the %F directive to see the types of your
          filesystems.


示例

我拥有什么文件系统?

$ find . -printf "%F\n" | sort -u
ext3


所以您可以使用它控制穿越:

仅ext3

$ find . -fstype ext3 | head -5
.
./gdcm
./gdcm/gdcm-2.0.16
./gdcm/gdcm-2.0.16/Wrapping
./gdcm/gdcm-2.0.16/Wrapping/CMakeLists.txt


仅nfs

$ find . -fstype nfs | head -5
$ 


ext3和ext4

$ find . -fstype ext3 -o -fstype ext4 | head -5
.
./gdcm
./gdcm/gdcm-2.0.16
./gdcm/gdcm-2.0.16/Wrapping
./gdcm/gdcm-2.0.16/Wrapping/CMakeLists.txt


评论


您如何防止它跨越文件系统边界?就像/已满,并且已经安装了网络文件系统一样,您也不想深入研究网络文件系统。

–随钻
14年2月26日在18:34

@Patrick-查看更新,您可以使用-fstype对其进行控制来查找。

–slm♦
14年2月26日在18:55

@Gilles-简单的答案...并没有完全找到find的手册页8-)

–slm♦
14年2月27日,0:33

@Gilles-手册页似乎并不表明-xtype排除文件系统,它看起来是在查看文件的类型。我只找到这样的例子:find。 \(-fstype nfs -prune \)

–slm♦
2014-2-27在0:39



@Gilles-我在评论Patrick的问题中谈到了如何避免跨文件系统边界查找。在他的前。他提到“像/如果已满,并且已安装网络文件系统,就不想深入研究网络文件系统”。

–slm♦
2014年2月27日,下午1:51

#4 楼

查找使用的inode的命令:

for i in /*; do echo $i; find $i |wc -l | sort ; done


#5 楼

我发现使用以下命令进行挖掘更快捷,更容易:

$ sudo du -s --inodes * | sort -rn

170202  var
157325  opt
103134  usr
53383   tmp
<snip>


然后您可以进入var,例如,查看使用目录的大型inode。在那里。

评论


正在寻找这样的东西。谢谢

–安瓦尔
20年4月3日,11:35

如果删除-s,它将为您“深入”并节省大量时间。

–橙色狗
20 May 26 '23:05

@OrangeDog会递归列出每个文件,这使得很难查看哪些目录贡献最大。在您发现我的罪魁祸首之前,通常不必深入太多的目录级别(因此不会花很长时间)。

– JonoB
20-05-28在0:44

@JonoB就是排序是为了。您可以获得与在每个步骤中手动重复的信息完全相同的信息,只是更快。

–橙色狗
20年5月28日在9:24

如果未指定-s,则将列出@OrangeDog每个叶目录。在-var上使用-s:34106文件夹3643 db 124日志32在上运行19后台处理11 rpc 7```不使用:34110文件夹34014文件夹/ s0 34013文件夹/ s0 / y6dlxn_x0wsfb5yv_fpglzlc0000gn 28592文件夹/ s0 / y6dlxn_x0wspgl5tv 17369文件夹/ s0 / y6dlxn_x0wsfb5yv_fpglzlc0000gn / T / broccoli-10284w53i1ho5mEPf IMO很难知道哪个目录贡献最大。

– JonoB
20-05-28在23:30



#6 楼

要列出/的详细inode用法,请使用以下命令:

echo "Detailed Inode usage for: $(pwd)" ; for d in `find -maxdepth 1 -type d |cut -d\/ -f2 |grep -xv . |sort`; do c=$(find $d |wc -l) ; printf "$c\t\t- $d\n" ; done ; printf "Total: \t\t$(find $(pwd) | wc -l)\n" 


评论


欢迎到这里!我建议下一次格式化更好。

–peterh-恢复莫妮卡
15年3月29日在10:36

这是一个单行,我认为这没有任何问题。

– sjas
16年5月18日在13:11

#7 楼

绝对最多的回答可以帮助理解linux和unix中的inode的概念,但是当涉及到从磁盘删除或删除inode的实际问题时,它并没有真正的帮助。在基于ubuntu的系统上执行此操作的一种更简单的方法是删除不需要的linux内核标头和映像。

sudo apt-get autoremove


会为您做到这一点。就我而言,由于收到警报,i节点的使用率为78%。

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/xvda1     524288 407957 116331   78% /
none           957443      2 957441    1% /sys/fs/cgroup
udev           956205    388 955817    1% /dev
tmpfs          957443    320 957123    1% /run
none           957443      1 957442    1% /run/lock
none           957443      1 957442    1% /run/shm
none           957443      5 957438    1% /run/user


运行sudo apt-get autoremove命令后,它已降至29%

$ df -i
Filesystem     Inodes  IUsed  IFree IUse% Mounted on
/dev/xvda1     524288 150472 373816   29% /
none           957443      2 957441    1% /sys/fs/cgroup
udev           956205    388 955817    1% /dev
tmpfs          957443    320 957123    1% /run
none           957443      1 957442    1% /run/lock
none           957443      1 957442    1% /run/shm
none           957443      5 957438    1% /run/user


这只是我的观察,节省了我的时间。人们可能会找到比这更好的解决方案。

#8 楼

到目前为止,每个答案都假设问题出在单个目录中,而不是所有导致问题的子目录中。幸运的是,解决方案是仅使用较少的标志。

# du --inodes --one-file-system /var | sort --numeric-sort
...
2265    /var/cache/salt/minion
3818    /var/lib/dpkg/info
3910    /var/lib/dpkg
4000    /var/cache/salt/master/gitfs/refs
4489    /var/lib
5709    /var/cache/salt/master/gitfs/hash
12954   /var/cache/salt/master/gitfs
225058  /var/cache/salt/master/jobs
241678  /var/cache/salt/master
243944  /var/cache/salt
244078  /var/cache
248949  /var


或使用更短的选项:du --inodes -x | sort -n。不幸的是,并非所有版本的du都具有inodes选项。