meta 目录里 2000 个 0 字节文件,我用 awk 筛出来没敢删
meta 目录跑了一年多,版本快照和临时文件混在一起,ls -l 已经看不出异常。上周备份前扫了一眼容量,发现 du -sh 比 df 少了将近 3 个 G,才回头去数文件个数。
环境是 Ubuntu 20.04,meta 目录下大约 4.6 万个文件,其中快照目录占大头。我先用 find 按大小筛出 0 字节的文件:
find /data/meta -type f -size 0 -printf '%T@ %p\n' | sort -n | awk '{print $2}' > /tmp/zero_files.txt
wc -l /tmp/zero_files.txt
结果 2000 出头。这些文件大多在 snapshots/ 下面,命名像 chunk.000123,时间戳集中在两次发布之间。我猜是迁移脚本中断留下的占位文件,但不敢直接 xargs rm,因为校验脚本可能把它们当成空块参与计算。
于是先做交叉验证:把文件名列表和最近一次全量校验的输出比对,确认这些文件不在校验清单里。命令是这么拼的:
awk -F/ '{print $NF}' /tmp/zero_files.txt | sort > /tmp/zero_names.txt
sort /data/meta/checksums.sha256 | awk '{print $2}' | xargs -n1 basename | sort > /tmp/checked_names.txt
comm -12 /tmp/zero_names.txt /tmp/checked_names.txt | wc -l
输出是 0。说明校验清单里没有它们。但另一个问题冒出来:checksums.sha256 本身是增量生成的,最近一次全量校验是两周前,中间新写入的快照不在清单里。所以“不在清单里”不等于“可以删”。
我的做法是先挪不删。建一个隔离目录,用 mv 移过去,保留目录结构:
mkdir -p /data/meta_quarantine
while read -r f; do
rel="${f#/data/meta/}"
mkdir -p "/data/meta_quarantine/$(dirname "$rel")"
mv "$f" "/data/meta_quarantine/$rel"
done < /tmp/zero_files.txt
挪完跑了一次增量校验,90 秒左右,结果和挪之前一致。这说明这些空文件确实没参与校验。但代价是隔离目录也要占 inode,如果文件系统 inode 本来就紧张,这个操作等于把问题从一边搬到另一边。
哪里会失效:如果空文件是被硬链接引用的占位,mv 只移动了目录项,原 inode 还在,du 不会降;如果文件系统开了 nodiratime 之类的挂载选项,时间戳排序可能不准;另外 find -size 0 对稀疏文件也会命中,不能只看大小。
我现在留着隔离目录没删,打算等下一次全量校验跑完再决定。你们在 meta 目录里遇到这种 0 字节文件,是直接清还是先隔离观察?
0
赞同度 100% · 0 条评论 · 2 阅读
0 条评论
还没有评论,写下第一条。