phe*_*mer 220 filesystems inode
所以我在我们的一个机器上收到了来自我们的监控系统的警告,文件系统上的空闲 inode 数量越来越少。
df -i
输出显示:
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/xvda1 524288 422613 101675 81% /
Run Code Online (Sandbox Code Playgroud)
如您所见,根分区使用了 81% 的 inode。
我怀疑它们都在一个目录中使用。但是我怎样才能找到它的位置呢?
phe*_*mer 254
我在 stackoverflow 上看到了这个问题,但我不喜欢任何答案,无论如何,这确实是一个应该出现在 U&L 上的问题。
基本上,文件系统上的每个文件都使用一个 inode。所以用完 inode 通常意味着你有很多小文件。所以问题真的变成了,“哪个目录中有大量文件?”
在这种情况下,我们关心的文件系统是根文件系统/
,因此我们可以使用以下命令:
{ find / -xdev -printf '%h\n' | sort | uniq -c | sort -k 1 -n; } 2>/dev/null
Run Code Online (Sandbox Code Playgroud)
这将转储文件系统上每个目录的列表,并以该目录中的文件(和子目录)的数量为前缀。因此,文件数最多的目录将位于底部。
就我而言,结果如下:
1202 /usr/share/man/man1
2714 /usr/share/man/man3
2826 /var/lib/dpkg/info
306588 /var/spool/postfix/maildrop
Run Code Online (Sandbox Code Playgroud)
所以基本上/var/spool/postfix/maildrop
是消耗所有的inode。
*注意,这个答案确实有我能想到的三个警告。它无法正确处理路径中包含换行符的任何内容。我知道我的文件系统没有带换行符的文件,并且由于这仅用于人类消费,因此潜在问题不值得解决,并且可以随时替换上述and命令的\n
with\0
和 use-z
选项,如下所示:sort
uniq
{ find / -xdev -printf '%h\0' |sort -z |uniq -zc |sort -zk1rn; } 2>/dev/null
Run Code Online (Sandbox Code Playgroud)
您可以选择添加head -zn10
到命令中以获取前 10 个最常用的 inode。
如果文件分散在大量目录中,它也不会处理。但这不太可能,所以我认为风险是可以接受的。它还会多次计算指向同一文件的硬链接(因此仅使用一个 inode)。同样,不太可能给出误报*
我不喜欢 stackoverflow 答案中的任何答案的关键原因是它们都跨越了文件系统边界。由于我的问题出在根文件系统上,这意味着它会遍历每个挂载的文件系统。抛出-xdev
find 命令甚至无法正常工作。
例如,最受欢迎的答案是这个:
for i in `find . -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n
Run Code Online (Sandbox Code Playgroud)
如果我们将其改为
for i in `find . -xdev -type d `; do echo `ls -a $i | wc -l` $i; done | sort -n
Run Code Online (Sandbox Code Playgroud)
即使/mnt/foo
是一个挂载,它也是根文件系统上的一个目录,所以它会出现在 中find . -xdev -type d
,然后它会被传递到ls -a $i
,它会潜入到挂载中。
将find
在我的答案,而不是列出在安装每一个文件的目录。所以基本上有一个文件结构,例如:
/foo/bar
/foo/baz
/pop/tart
Run Code Online (Sandbox Code Playgroud)
我们最终得到
/foo
/foo
/pop
Run Code Online (Sandbox Code Playgroud)
所以我们只需要计算重复行的数量。
mik*_*erv 31
这是在提问者的要求下从这里重新发布的:
du --inodes --separate-dirs | sort -rh | sed -n \
'1,50{/^.\{71\}/s/^\(.\{30\}\).*\(.\{37\}\)$/\1...\2/;p}'
Run Code Online (Sandbox Code Playgroud)
如果你想留在同一个文件系统中,你可以:
du --inodes --one-file-system --separate-dirs
Run Code Online (Sandbox Code Playgroud)
这是一些示例输出:
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
Run Code Online (Sandbox Code Playgroud)
请注意,以上需要 GNU du
(即来自 GNU coreutils),因为 POSIXdu
不支持
--inodes
,--one-file-system
或 --separate-dirs
。(如果你有Linux的,你可能有GNU的coreutils。如果你有GNU du
,可以缩写--one-file-system
到 -x
(小写),并 --separate-dirs
以 -S
(大写)。POSIX du
识别 -x
,但不能 -S
或任何长选项。)一些人提到他们不这样做拥有最新的 coreutils 并且该--inodes
选项对他们不可用。(但它出现在 GNU coreutils 8.22 版中;如果您的版本比那个旧,您可能应该升级。)所以,这里是ls
:
ls ~/test -AiR1U |
sed -rn '/^[./]/{h;n;}; G;
s|^ *([0-9][0-9]*)[^0-9][^/]*([~./].*):|\1:\2|p' |
sort -t : -uk1.1,1n |
cut -d: -f2 | sort -V |
uniq -c | sort -rn | head -n10
Run Code Online (Sandbox Code Playgroud)
如果您很好奇,那么乏味的正则表达式的核心是将每个ls
递归搜索结果中的文件名替换为找到它的目录名。从那里开始,只需压缩重复的 inode 编号,然后计算重复的目录名称并相应地排序。
该-U
选项与在它专门针对排序特别有用不排序,而是提出在原来的顺序目录列表 – 或者,换句话说,通过 inode 编号.
当然,-A
对于(几乎)所有,-i
对于 inode 和-R
递归,这就是它的长处和短处。在 -1
(1)选项被列入的习惯势力了。
对此的基本方法是,我将 ls 的每个文件名替换为其在 sed 中的包含目录名。从那以后......好吧,我自己有点模糊。我相当确定它正在准确计算文件,正如您在此处看到的:
% _ls_i ~/test
100 /home/mikeserv/test/realdir
2 /home/mikeserv/test
1 /home/mikeserv/test/linkdir
Run Code Online (Sandbox Code Playgroud)
(其中_ls_i
代表上述ls
- sed
-... 管道,定义为别名或脚本)。
这为我提供了与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
Run Code Online (Sandbox Code Playgroud)
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:
Run Code Online (Sandbox Code Playgroud)
如果您逐行比较乏味地比较上面的内容,您会注意到du
输出的第 8 行是/usr/share/fonts/TTF
(1.6K),而ls
输出的第 8 行是/usr/include
(1613)。我认为这include
取决于程序首先查看哪个目录——因为它们是相同的文件并且是硬链接的。有点像上面的东西。不过我可能是错的——我欢迎纠正......
% du --version
du (GNU coreutils) 8.22
Run Code Online (Sandbox Code Playgroud)
创建一个测试目录:
% mkdir ~/test ; cd ~/test
% du --inodes --separate-dirs
1 .
Run Code Online (Sandbox Code Playgroud)
一些儿童目录:
% mkdir ./realdir ./linkdir
% du --inodes --separate-dirs
1 ./realdir
1 ./linkdir
1 .
Run Code Online (Sandbox Code Playgroud)
制作一些文件:
% printf 'touch ./realdir/file%s\n' `seq 1 100` | . /dev/stdin
% du --inodes --separate-dirs
101 ./realdir
1 ./linkdir
1 .
Run Code Online (Sandbox Code Playgroud)
一些硬链接:
% printf 'n="%s" ; ln ./realdir/file$n ./linkdir/link$n\n' `seq 1 100` |
. /dev/stdin
% du --inodes --separate-dirs
101 ./realdir
1 ./linkdir
1 .
Run Code Online (Sandbox Code Playgroud)
查看硬链接:
% cd ./linkdir
% du --inodes --separate-dirs
101
% cd ../realdir
% du --inodes --separate-dirs
101
Run Code Online (Sandbox Code Playgroud)
它们是单独计算的,但是向上一级目录...
% cd ..
% du --inodes --separate-dirs
101 ./realdir
1 ./linkdir
1 .
Run Code Online (Sandbox Code Playgroud)
然后我从下面运行我的运行脚本:
100 /home/mikeserv/test/realdir
100 /home/mikeserv/test/linkdir
2 /home/mikeserv/test
Run Code Online (Sandbox Code Playgroud)
以及格雷姆对类似问题的回答的输出:
101 ./realdir
101 ./linkdir
3 ./
Run Code Online (Sandbox Code Playgroud)
所以我认为这表明计算 inode 的唯一方法是通过 inode。并且因为计算文件意味着计算 inode,所以您不能重复计算 inode - 要准确计算文件 inode 不能计算多次。
小智 8
我发现使用以下命令可以更快、更轻松地进行深入研究:
$ sudo du -s --inodes * | sort -rn
170202 var
157325 opt
103134 usr
53383 tmp
<snip>
Run Code Online (Sandbox Code Playgroud)
然后您可以进入var
例如并查看使用目录的大 inode 在那里。
我使用了来自 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
Run Code Online (Sandbox Code Playgroud)
$ 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
Run Code Online (Sandbox Code Playgroud)
根据您的 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
Run Code Online (Sandbox Code Playgroud)
您可以使用-xdev
开关直接find
将搜索范围缩小到您正在启动搜索的设备。
假设我的/home
目录通过我的 NAS 中的 NFS 共享自动挂载,它的名字是 mulder。
$ df -h /home/sam
Filesystem Size Used Avail Use% Mounted on
mulder:/export/raid1/home/sam
917G 572G 299G 66% /home/sam
Run Code Online (Sandbox Code Playgroud)
请注意,挂载点仍被视为系统本地。
$ df -h /home/ .
Filesystem Size Used Avail Use% Mounted on
- 0 0 0 - /home
/dev/mapper/VolGroup00-LogVol00
222G 159G 52G 76% /
Run Code Online (Sandbox Code Playgroud)
现在当我发起find
:
$ find / -xdev | grep '^/home'
/home
Run Code Online (Sandbox Code Playgroud)
它找到/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.
Run Code Online (Sandbox Code Playgroud)
我有什么文件系统?
$ find . -printf "%F\n" | sort -u
ext3
Run Code Online (Sandbox Code Playgroud)
所以你可以用它来控制交叉:
只有 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
Run Code Online (Sandbox Code Playgroud)
只有 nfs
$ find . -fstype nfs | head -5
$
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
查找使用的 inode 的命令:
for i in /*; do echo $i; find $i |wc -l | sort ; done
Run Code Online (Sandbox Code Playgroud)