我有一个在 tmpfs 上带有 / 的系统。大多数 / 子目录都挂载了 aufs,覆盖读写根文件系统和只读基本文件系统(系统从只读介质启动)。早些时候,我曾经使用 unionfs 而不是 aufs。它一直正常工作,直到最近 tmpfs 开始填满。我不确定是什么触发了变化。可能是 unionfs 到 aufs 的更改、内核升级或系统中的某些更改以及它如何访问文件系统。
无论如何,似乎是 tmpfs 的行为有些错误。
虽然系统应该不会对tmpfs写很多,但是用完还是蛮多的:
# df -m /
Filesystem 1M-blocks Used Available Use% Mounted on
tmpfs 200 50 151 25% /
Run Code Online (Sandbox Code Playgroud)
尽管:
# du -smx /
2 /
Run Code Online (Sandbox Code Playgroud)
这是我的测试系统,基本上什么都不做。当使用率迅速超过 90% 并且系统崩溃时,生产系统上的东西就会磨损。
我怀疑这些已删除的文件仍然打开,但是:
# lsof | grep deleted
Run Code Online (Sandbox Code Playgroud)
什么都不显示。
另一个想法是, / 上的某些文件被安装在其上的文件系统屏蔽,所以我尝试了这个:
# mount --bind / /mnt
# du -sm /mnt
2 /mnt
Run Code Online (Sandbox Code Playgroud)
尽管如此,仍然没有丢失 48MB 的痕迹。
我怎样才能找出是什么用完了我的 tmpfs 文件系统?
系统信息:
# uname -rm
3.4.6 i686
Run Code Online (Sandbox Code Playgroud)
更新:我尝试过内核 3.4.17 和 3.6.6 – 没有变化。
Jac*_*zny 10
在 aufs 维护者 Junjiro Okajima 的帮助下,我自己解开了这个谜团。
调试问题的第一步是以受控方式重现它。我花了一些时间(现在我想知道为什么这么多)才发现问题发生在通过 aufs 写入和删除文件时。
创建挂载点:
# cd /tmp
# mkdir rw
# mkdir mnt
Run Code Online (Sandbox Code Playgroud)
挂载 tmpfs:
# mount -t tmpfs none /tmp/rw
Run Code Online (Sandbox Code Playgroud)
挂载 aufs,用 /tmp/rw 覆盖 /usr:
# mount -t aufs -n -o "br:/tmp/rw:/usr" none "/tmp/mnt"
Run Code Online (Sandbox Code Playgroud)
现在我可以在 /tmp/mnt 下看到 /usr 内容:
# ls /tmp/mnt
bin games include lib lib64 local sbin share src
Run Code Online (Sandbox Code Playgroud)
我感兴趣的是下面 tmpfs 上的已用/可用空间:
# du -sk /tmp/rw
0 /tmp/rw
# df /tmp/rw
Filesystem 1K-blocks Used Available Use% Mounted on
none 1031128 24 1031104 1% /tmp/rw
Run Code Online (Sandbox Code Playgroud)
/tmp/rw 中没有文件,但分配了 24 个块。还是不是什么大问题。
我可以将文件写入 aufs,它将存储在 /tmp/rw 中的 tmpfs:
# dd if=/dev/zero of=/tmp/mnt/test bs=1024 count=100
100+0 records in
100+0 records out
102400 bytes (102 kB) copied, 0.000343903 s, 298 MB/s
# du -sk /tmp/rw
100 /tmp/rw
# df /tmp/rw
Filesystem 1K-blocks Used Available Use% Mounted on
none 1031128 128 1031000 1% /tmp/rw
Run Code Online (Sandbox Code Playgroud)
请注意使用情况统计数据是如何变化的。du
显示增加了 100kB,正如预期的那样,但df
输出中的“已使用”值增加了 104 个块。
当我删除文件时:
# du -sk /tmp/rw
0 /tmp/rw
# df /tmp/rw
Filesystem 1K-blocks Used Available Use% Mounted on
none 1031128 28 1031100 1% /tmp/rw
Run Code Online (Sandbox Code Playgroud)
四个块丢失。
当我重复几次dd
和rm
命令时,我得到:
# df /tmp/rw
Filesystem 1K-blocks Used Available Use% Mounted on
none 1031128 36 1031092 1% /tmp/rw
Run Code Online (Sandbox Code Playgroud)
越来越多的 tmpfs 块消失了,我不知道在哪里......
当我做了同样的-dd
和rm
直接在/ tmp / RW没有丢失这种方式。在卸载 aufs 后,tmpfs 上丢失的空间被恢复。所以,至少,我知道应该归咎于 aufs,而不是 tmpfs。
知道应该怪什么,我在 aufs-users 邮件列表上描述了我的问题。我很快就收到了第一个答案。JR Okajima帮助我解释了丢失的 tmpfs 块发生了什么。
这确实是一个删除的文件。它没有显示在lsof
任何地方,/proc/<pid>/*
因为文件没有被任何用户空间进程打开或映射。“xino 文件”文件是 aufs 的外部 inode 编号转换表,由内核 aufs 模块在内部使用。
文件路径可以从 sysfs 中读取:
# cat /sys/fs/aufs/si_*/xi_path
/tmp/rw/.aufs.xino
Run Code Online (Sandbox Code Playgroud)
但是,由于文件被删除,无法直接看到:
# ls -l /tmp/rw/.aufs.xino
ls: cannot access /tmp/rw/.aufs.xino: No such file or directory
Run Code Online (Sandbox Code Playgroud)
但是,可以从 debugfs 中读取有关其大小和其他特殊 aufs 文件大小的信息:
# for f in /sys/kernel/debug/aufs/si_8c8d888a/* ; do echo -n "$f: " ; cat $f ; done
/sys/kernel/debug/aufs/si_8c8d888a/xi0: 1, 32x4096 132416
/sys/kernel/debug/aufs/si_8c8d888a/xi1: 1, 24x4096 626868
/sys/kernel/debug/aufs/si_8c8d888a/xib: 8x4096 4096
/sys/kernel/debug/aufs/si_8c8d888a/xigen: 8x4096 88
Run Code Online (Sandbox Code Playgroud)
详细信息在aufs 手册页中描述。
“xino 文件”可以通过以下方式手动截断:
# mount -o remount,itrunc_xino=0 /tmp/mnt
Run Code Online (Sandbox Code Playgroud)
挂载 aufs 时,可以使用 trunc_xino 选项请求自动截断 xino 文件:
# mount -t aufs -n -o "br:/tmp/rw:/usr,trunc_xino" none "/tmp/mnt"
Run Code Online (Sandbox Code Playgroud)
我仍然不知道它是如何影响文件系统性能的,或者这是否真的能解决我在生产中的 tmpfs 空间不足问题……但我学到了很多。
归档时间: |
|
查看次数: |
7295 次 |
最近记录: |