「磁盘满了」和「内存不够」是两件事:df -h 报满时,清理文件不会让 free 显示的空闲内存变多;反过来,内存紧张也不该靠删文件解决。看到磁盘告警,先确认是磁盘块满、inode 满,还是被进程占着却没释放的已删文件,再决定删什么、怎么删。判断顺序错,容易删了东西空间却不涨,或者删掉正在写的日志导致服务异常。
先跑df -hT和df -i分清是容量满还是 inode 满,再用du -x -h --max-depth=1逐层定位到具体目录,最后用lsof +L1查有没有「已删除但被进程持有」的文件。删除前确认写入进程和备份,线上优先截断或轮转,不要直接rm正在写的日志。清理只释放磁盘,不释放内存。
Linux磁盘满先定位在哪一层
磁盘满通常出在下面几层中的一层,每层都有对应的检查位置,先确认层再动手,能避免在错误的层上反复操作。
- 文件系统数据块层:
df -hT看目标挂载点的 Use%,Use% 接近 100% 说明块用满。同时看挂载点是不是你以为的那个目录。 - inode 层:
df -i看 IUse%。块还有空余但 inode 用满,同样写不进新文件,常见于大量小文件目录(缓存、队列、session 文件)。 - 进程持有层:文件已被删除,但进程还开着文件描述符,空间不归还。用
lsof +L1看有没有 link count 为 0 的大文件。 - 目录占用层:确认是哪个目录吃掉了空间,用
du从挂载点根往下逐层缩小;-x参数保证不跨文件系统统计。 - 挂载覆盖层:如果
du统计出来远小于df的已用容量,先怀疑有目录被另一个文件系统挂载覆盖,检查findmnt输出与/etc/fstab。
下面几条命令可以在目标主机上直接按顺序执行,定位阶段只读不改:

df -hT
df -i
findmnt -T /
du -x -h --max-depth=1 / 2>/dev/null | sort -h
lsof +L1 2>/dev/null | head -n 20
du 在大目录上会跑较久,可以先从 /var、/home、/data 这类业务目录开始,不必每次扫全盘。定位结论要落到「哪个挂载点、哪个目录、哪类文件」三件事上,再进入清理。
Linux磁盘满:先看这四个位置
按位置排查比按感觉删文件可靠。以下四个位置覆盖了多数情况,路径和命令都写全,照着执行即可。
日志
journalctl --disk-usage:看 systemd journal 占用;清理用journalctl --vacuum-size=500M(大小按实际容量定)。du -sh /var/log/* | sort -h | tail -n 20:找出最大的日志文件或子目录。- 容器日志:
/var/lib/docker/containers/*/*-json.log,用du -sh /var/lib/docker/containers确认。
命令输出
df -hT里的 Mounted on 列要和你以为的挂载点核对一致,Use% 与 Avail 同时看。df -i的 IUse% 单独判断,别只看块使用率。lsof +L1输出里的 SIZE 列,是被删除文件仍占用的空间量。
配置项
/etc/logrotate.conf与/etc/logrotate.d/:确认轮转周期、保留份数、是否copytruncate。/etc/systemd/journald.conf:SystemMaxUse、MaxRetentionSec决定 journal 上限。/etc/docker/daemon.json:data-root与log-opts(max-size、max-file)决定镜像和日志落盘位置与上限。/etc/fstab:核对是否有独立分区、是否设了reserve相关参数。
面板字段
- 云控制台的「磁盘使用率」通常来自监控 agent 采样,可能滞后;以实例内
df为准。 - 控制台的「快照 / 备份 / 镜像」占用是独立的计费项,不一定体现在实例内
df上,但会占你的存储额度。 - 如果用的是带「磁盘配额」的面板,注意配额上限和实际用量是两个字段,别把配额当容量。
Linux磁盘满:按可能性从高到低排除
下面按常见程度排序,每条都给出确认动作和处理方式,确认不了就往下一条走,不要跳过验证直接删。

- 日志暴涨。确认:
du -sh /var/log/* | sort -h | tail。处理:优先用logrotate -f /etc/logrotate.d/<服务名>触发轮转;临时止血可用truncate -s 0 /var/log/xxx.log(前提是确认该文件可以清空且服务支持)。 - 容器镜像与容器日志堆积。确认:
docker system df、du -sh /var/lib/docker/*。处理:docker system prune前先确认没有需要保留的停止容器和悬空镜像,线上建议先docker image ls人工核对。 - 数据库 binlog / WAL / 备份文件。确认:
du -sh /var/lib/mysql/*或对应数据目录。处理:按数据库自身的清理机制(如 binlog 保留天数)处理,不要直接删数据目录里的文件。 - 临时文件与打包备份。确认:
du -x -h --max-depth=2 /tmp /var/tmp /data 2>/dev/null | sort -h | tail。处理:确认无进程使用后再删,lsof /tmp/xxx可以查占用。 - 已删除但被进程持有的文件。确认:
lsof +L1。处理:重启或重载对应进程释放句柄;不建议直接 kill 业务进程,先看该文件属于哪个服务。 - inode 耗尽。确认:
df -i的 IUse% 接近 100%。处理:定位小文件密集目录(如缓存、邮件队列),按业务逻辑清理;建大量小文件的服务要考虑调大 inode 或改存储结构,这属于重建文件系统级别的操作,需评估。 - 预留块与配额限制。确认:
tune2fs -l /dev/xxx | grep -i reserved(ext 系)或配额命令输出。处理:reserved块是给 root 留的余量,调小会影响 root 在满盘时的写能力,是否调整要结合环境确认。
如果 df 和 du 结果对不上,先看第 5 条和挂载覆盖,这两个是最容易被忽略的方向。
Linux磁盘满:改完怎么确认真的解决了
清理后至少要确认三件事:容量回来了、不是靠暂时性手段撑住的、写入恢复正常。

df -hT
df -i
du -x -h --max-depth=1 / 2>/dev/null | sort -h
lsof +L1 2>/dev/null | head
tail -n 50 /var/log/messages 2>/dev/null
- 容量与 inode 双双回落,且
lsof +L1没有残留的大文件。 - 观察时长按业务写入节奏定:日志类问题建议至少观察一个完整的轮转周期(例如一天)再看
df曲线是否平稳;一次性大文件清理观察数小时即可。没有出现再次逼近阈值,才算处理完成。 - 业务侧确认:
systemctl status <服务名>为 active,应用日志不再出现No space left on device。
回滚办法要提前想好,改配置前先备份:
cp /etc/logrotate.d/<服务名> /etc/logrotate.d/<服务名>.bak,异常时改回并执行logrotate -d做语法检查。- 修改
/etc/systemd/journald.conf前同样备份,改完执行systemctl restart systemd-journald;回滚即恢复备份文件并重新daemon-reload。 - 修改
/etc/docker/daemon.json前备份,改完执行systemctl daemon-reload && systemctl restart docker;回滚是恢复备份并重启 docker。注意重启 docker 会重启容器,需要窗口。 - 删除文件前把要删的目录先
mv到同一文件系统的临时位置,确认服务正常后再真正删除,这样回滚成本最低。
如果最终确认是磁盘容量本身不够,扩容或迁移数据比反复清理更合适;扩容后记得回到 df -hT 确认新容量已生效,未生效通常是文件系统未扩展,需要结合具体文件系统类型处理。