删了文件空间也不释放:inode 用尽
发布时间:2026-06-26 19:57       
更新时间:2026-06-27 16:58
df -h 明明显示磁盘没满,程序却报 No space left on device,这时要看的另一块表是 df -i:很可能不是空间用完,而是 inode 用尽。
## inode 是什么、怎么就没了
Linux 文件系统为每个文件分配一个 inode(索引节点,存储文件的元数据),总量在格式化时就固定了。海量小文件会把 inode 消耗光——每个文件哪怕只占 1KB,也要吃掉一个 inode。它与磁盘空间是两本独立账,空间有剩、inode 用光,新建文件照样失败。目录本身也占 inode,几百万个空目录同样能掏空 inode 表,清理时文件和目录一起算。
识别窍门记一条:写入报错而 df -h 空闲充足,先查 df -i 再动手,方向对了就一步到位。
## 小文件从哪来
高频来源按经验排序:PHP 的 session 文件(每个访问一个文件,量大又难自动清理)、程序缓存碎片(模板编译缓存、图片缩略图)、邮件队列堆积、crontab 任务每分钟落一个不带清理机制的小文件。定位方法:
df -i
find /var -xdev -type f | wc -l
想更快出排行,一轮 shell 就够:for d in /var/*; do echo "$d $(find $d -xdev | wc -l)"; done,文件数最多的目录直接浮出来。判断归属时注意:du 看体积不大、文件数却惊人的,就是海量小文件的巢穴。
## 批量清理的正确姿势
海量文件不要直接 rm *,参数列表会超长,用 find 配套:
find /var/lib/php/session -type f -mtime +7 -delete
-delete 由 find 自己执行删除,不经过 shell,效率高也不怕特殊文件名;更保守的写法是先 -print 预览再删。清理时按修改时间分批,一次几万到几十万个,边删边观察负载,避免 IO 打满拖垮在线业务。session 目录的清理交给定时任务固化:每天凌晨跑同一条 find 命令,把手工操作变成机制。完成后 df -i 复核,inode 恢复到正常水位才算收尾。留意 df -i 是按分区统计的,系统盘、数据盘各有各的 inode 账本,查对分区再清理。
预防永远比清理便宜:凡是"只写不删"的目录,写文件的程序必须自带过期清理。海量小文件专用的分区,格式化阶段就按小文件比例调 inode 数量(mkfs 的 -i 参数),别等用光再重建。巡检时把 df -i 和 df -h 放在一起看,两本账都不超标。