tmpfs 已滿,儘管幾乎沒有使用。我該如何調試這個
我有一個帶有 / on tmpfs 的系統。大多數 / 子目錄都安裝了 aufs,覆蓋讀寫根文件系統和只讀基本文件系統(系統從只讀介質引導)。早些時候,我曾經使用 unionfs 而不是 aufs。它一直正常工作,直到最近 tmpfs 開始填滿。我不確定是什麼觸發了這種變化。可能是 unionfs 到 aufs 的更改、核心升級或系統中的某些更改以及它訪問文件系統的方式。
無論如何,似乎是 tmpfs 的行為有些錯誤。
儘管系統不應該向 tmpfs 寫入很多內容,但其中相當一部分已用完:
# df -m / Filesystem 1M-blocks Used Available Use% Mounted on tmpfs 200 50 151 25% /
儘管:
# du -smx / 2 /
這是我的測試系統,基本上什麼都不做。當使用率迅速達到 90% 以上並且系統崩潰時,生產系統就會磨損。
我懷疑這些被刪除的文件仍然打開,但是:
# lsof | grep deleted
什麼都不顯示。
另一個想法是, / 上的一些文件被安裝在它上面的文件系統屏蔽,所以我嘗試了這個:
# mount --bind / /mnt # du -sm /mnt 2 /mnt
儘管如此,沒有失去 48MB 的痕跡。
如何找出正在使用我的 tmpfs 文件系統的內容?
系統資訊:
# uname -rm 3.4.6 i686
更新:我已經嘗試過核心 3.4.17 和 3.6.6 - 沒有變化。
在 aufs 維護者 Junjiro Okajima 的幫助下,我自己解開了這個謎團。
調試問題的第一步是以可控的方式重現它。我花了一些時間(現在我想知道為什麼這麼多)才發現問題是在通過 aufs 寫入和刪除文件時發生的。
重現問題
創建掛載點:
# cd /tmp # mkdir rw # mkdir mnt
掛載 tmpfs:
# mount -t tmpfs none /tmp/rw
掛載aufs,用/tmp/rw覆蓋/usr:
# mount -t aufs -n -o "br:/tmp/rw:/usr" none "/tmp/mnt"
現在我可以看到 /tmp/mnt 下的 /usr 內容:
# ls /tmp/mnt bin games include lib lib64 local sbin share src
我感興趣的是下面 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
/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
請注意使用情況統計數據的變化。
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
失去了四個塊。
當我重複
dd
andrm
命令幾次時,我得到:# df /tmp/rw Filesystem 1K-blocks Used Available Use% Mounted on none 1031128 36 1031092 1% /tmp/rw
越來越多的 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
但是,由於文件被刪除,無法直接看到:
# ls -l /tmp/rw/.aufs.xino ls: cannot access /tmp/rw/.aufs.xino: No such file or directory
不過,可以從 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
詳細資訊在aufs 手冊頁中進行了描述。
解決方案
“xino 文件”可以通過以下方式手動截斷:
# mount -o remount,itrunc_xino=0 /tmp/mnt
在掛載 aufs 時,可以使用 trunc_xino 選項請求自動截斷 xino 文件:
# mount -t aufs -n -o "br:/tmp/rw:/usr,trunc_xino" none "/tmp/mnt"
我仍然不知道它如何影響文件系統性能,或者這是否真的能解決我在生產中的 tmpfs 空間不足問題……但我學到了很多東西。