Linux磁盘满了怎么清理内存空间

文章导读
「磁盘满了」和「内存不够」是两件事:df -h 报满时,清理文件不会让 free 显示的空闲内存变多;反过来,内存紧张也不该靠删文件解决。看到磁盘告警,先确认是磁盘块满、inode 满,还是被进程占着却没释放的已删文件,再决定删什么、怎么删。判断顺序错,容易删了东西空间却不涨,或者删掉正在写的日志导致服务异常。
📋 目录
  1. 一 Linux磁盘满先定位在哪一层
  2. 二 Linux磁盘满:先看这四个位置
  3. 三 Linux磁盘满:按可能性从高到低排除
  4. 四 Linux磁盘满:改完怎么确认真的解决了
A A

「磁盘满了」和「内存不够」是两件事: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。

下面几条命令可以在目标主机上直接按顺序执行,定位阶段只读不改:

Linux磁盘满了怎么清理内存空间
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磁盘满:按可能性从高到低排除

下面按常见程度排序,每条都给出确认动作和处理方式,确认不了就往下一条走,不要跳过验证直接删。

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

如果 df 和 du 结果对不上,先看第 5 条和挂载覆盖,这两个是最容易被忽略的方向。

Linux磁盘满:改完怎么确认真的解决了

清理后至少要确认三件事:容量回来了、不是靠暂时性手段撑住的、写入恢复正常。

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。

回滚办法要提前想好,改配置前先备份:

  1. cp /etc/logrotate.d/<服务名> /etc/logrotate.d/<服务名>.bak,异常时改回并执行 logrotate -d 做语法检查。
  2. 修改 /etc/systemd/journald.conf 前同样备份,改完执行 systemctl restart systemd-journald;回滚即恢复备份文件并重新 daemon-reload。
  3. 修改 /etc/docker/daemon.json 前备份,改完执行 systemctl daemon-reload && systemctl restart docker;回滚是恢复备份并重启 docker。注意重启 docker 会重启容器,需要窗口。
  4. 删除文件前把要删的目录先 mv 到同一文件系统的临时位置,确认服务正常后再真正删除,这样回滚成本最低。

如果最终确认是磁盘容量本身不够,扩容或迁移数据比反复清理更合适;扩容后记得回到 df -hT 确认新容量已生效,未生效通常是文件系统未扩展,需要结合具体文件系统类型处理。