印度机房用 ncdu 扫盘,删完空间没回来

印度机房的备份机,Debian 12,一块 4TB 的 ext4 数据盘,挂载在 /data。某天早上 df 报 98%,业务端 rsync 开始报 No space left on device。盘上大概 60 万个文件,主要是历史备份和一堆临时导出。

按以前的习惯先 du -sh 逐层看,太慢,扫一遍十几分钟。这次改用 ncdu:

apt install ncdu
ncdu -x /data

-x 只留在同一文件系统,避免把挂载点算进去。界面里按 c 看条目数、按 s 排序、按 g 切到百分比视图,很快定位到 /data/export 下有个 1.2TB 的目录,里面全是按日期命名的子目录。挑了几个最老的删掉,ncdu 里数字确实降了,退出后 df 却几乎没动。

真正的坑在这里:那些文件还有进程开着。备份脚本里有个包装器,之前被 kill 过但子进程还在,lsof 一查就出来了:

lsof +L1 /data | head

+L1 列出 link count 小于 1 的已打开文件,也就是已删除但仍被持有的文件。确认后重启对应的服务,空间立刻回来。

为什么 ncdu 看起来「删了但没释放」:它读的是目录项,unlink 之后目录项就没了,所以界面上的数字是对的;但 inode 和数据块要等最后一个持有者关闭文件才回收,这中间 df 不会变。代价是 ncdu 本身也要建索引,60 万文件第一次扫花了大概两分钟,内存占用不算小,低配机器上要留意。

会失效的地方:文件系统不是 ext4/xfs 时 -x 的行为要看具体实现;如果有大量硬链接,ncdu 的统计口径和 df 对不上,这点和 du 一样;另外 /data 下如果还有 bind mount,-x 会把它们跳过,得单独进去看。我自己还踩过一次:在 screen 里跑 ncdu,SSH 断了之后进程被挂起,第二天再看数字是旧的,重新扫才对。

删除前我会先跑一遍 lsof +L1 看有没有人持有,比删完再找省事。你们在印度这边的机器上,删完空间不回来时一般先查进程还是先查文件系统?

0
赞同度 100% · 0 条评论 · 1 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。