虚拟机日记清理后空间没释放怎么办?核心结论是:多数情况下不是日志没删掉,而是已删除文件仍被进程占用、清理路径被挂载覆盖,或者精简置备磁盘和快照没有在虚拟化层回收空间。 下文按日志场景说明,先查文件系统,再查进程句柄,最后查虚拟化层。
先判断空间卡在哪:df、du和lsof三件套
清理日志后空间没回来,先别急着重启虚拟机,重启有时有效,但它只是把“被进程占用的已删除文件”强行释放,生产环境代价高,更稳妥的做法是先定位。
Linux虚拟机日志清理后空间未释放原因:先找deleted句柄
在Linux虚拟机里执行:
df -hT du -xhd1 /var/log | sort -h lsof +L1
如果df显示分区快满,但du统计/var/log并不大,常见原因是日志文件被rm删除后,rsyslog、journald、Nginx、Tomcat等进程仍持有文件句柄,此时文件在目录里看不见,块却还被占用。
继续查:
lsof | grep deleted ls -l /proc/<pid>/fd | grep deleted
找到对应进程后,优先重启或重载对应服务,
systemctl restart rsyslog systemctl restart systemd-journald systemctl reload nginx
确认不是关键业务进程后,也可对单个已删除文件描述符执行truncate释放空间;生产环境更建议走服务重启或重载,避免误伤。
清理路径被挂载覆盖,删了也白删
另一种情况是/var/log或某个日志目录被单独挂载覆盖,你删除的是下层目录文件,空间自然不释放,用下面命令确认:
findmnt /var/log mount | grep -E 'var|log'
du -x只统计同一文件系统,跨挂载点统计容易误判,先确认日志真实所在分区,再清理。
| 现象 | 更可能的原因 | 验证动作 | 处理方向 |
|---|---|---|---|
| df满、du小 | 已删除文件仍被进程打开 | lsof +L1 |
重启服务或处理fd |
| df和du都大 | 日志未真正清理或删错目录 | du -xhd1 /var/log |
按日志类型用原生命令 |
| 客户机df正常、宿主机存储满 | 快照或精简置备未回收 | 查快照、lsblk -D |
fstrim、unmap、合并快照 |
| Windows C盘满、清理事件日志无效 | 卷影副本、休眠文件或句柄占用 | vssadmin、handle |
调整卷影存储、ReTrim |
按日志类型处理,别用一把rm走天下
systemd journal日志:用vacuum,不要直接rm
journal日志常见于/var/log/journal,直接rm -rf后,journald仍可能持有句柄,正确动作是:
journalctl --disk-usage journalctl --vacuum-size=500M journalctl --vacuum-time=7d
需要长期控制,可编辑/etc/systemd/journald.conf,设置SystemMaxUse=1G、RuntimeMaxUse=200M,
systemctl restart systemd-journald
业内专家指出,文件系统删除只是解除目录项,不等于底层块立即归还;对正在写入的日志,清空内容通常比直接删除文件更稳。
rsyslog和logrotate:copytruncate与create要配对
/var/log/messages、/var/log/secure这类日志被rsyslog打开时,直接rm会让进程继续写已删除inode,可以临时清空:
truncate -s 0 /var/log/messages systemctl reload rsyslog
logrotate配置里,copytruncate适合不能重载的进程;create方式则要在postrotate里重载服务,检查:
lsof /var/log/messages logrotate -d /etc/logrotate.conf
数据库和应用日志:走原生命令
MySQL的binlog不要直接删文件,用:
PURGE BINARY LOGS BEFORE NOW() - INTERVAL 7 DAY;
PostgreSQL的WAL要看归档和复制槽,不能把pg_wal当普通日志清,Nginx、Tomcat日志清理后,配合reload让句柄切换,行业共识认为,数据库日志清理必须保留恢复链路,直接删文件可能带来一致性风险。
云服务器虚拟机日志清理后空间未回收:别忽略虚拟化层
精简置备磁盘不会因为客户机删文件自动缩小
qcow2、vmdk等精简置备磁盘只记录块分配,客户机里删除日志,文件系统释放了块,但虚拟化层不一定马上知道,Linux虚拟机可执行:
fstrim -av lsblk -D
确认挂载选项支持discard,VMware环境可在维护窗口评估esxcli storage vmfs unmap;Windows虚拟机可用:
Optimize-Volume -DriveLetter C -ReTrim -Verbose
KVM/qcow2镜像可在离线状态用virt-sparsify压缩,或qemu-img convert重建镜像,操作前做备份,避免影响快照链。
虚拟机日志清理和快照空间占用对比:谁在吃盘
日志清理释放的是客户机文件系统块;快照占用的是虚拟化层增量块,两者不是一回事,快照存在时,即使你在虚拟机里删了日志,快照文件也可能继续保留旧数据块,检查快照管理器,确认是否有长期未合并的快照、克隆临时盘、备份挂载盘。
云盘扩容费用不低,先做完df、du、lsof、快照和TRIM检查,再决定是否付费扩容,北京、上海等地域的云服务器实例排查路径相同,不必因为地域不同就认定是平台侧问题。
Windows虚拟机C盘日志清理后空间没释放怎么排查
先看卷影副本:
vssadmin list shadowstorage
再看事件日志是否被占用,可用wevtutil cl System清理指定日志,被句柄占用时,用Sysinternals的handle.exe查占用进程,页面文件和休眠文件也会占C盘,可检查:
powercfg /h off
精简置备Windows虚拟机同样需要Optimize-Volume -ReTrim,否则底层镜像不会明显缩小。
两个验证动作,确认空间真的回来了
用df、du和lsof做闭环
清理后按顺序复核:
df -h du -xhd1 / lsof +L1 journalctl --disk-usage
如果df可用空间仍小,再看inode:df -i,ext4保留块也会让可用空间看起来偏少,可用tune2fs -l /dev/vda1 | grep Reserved查看,调整tune2fs -m要谨慎,别在生产分区随手改。
检查快照和存储回收状态
在虚拟化平台确认快照是否合并、精简置备是否支持UNMAP、备份任务是否临时挂载了磁盘,客户机内空间正常、宿主机数据存储仍满,问题通常就在这一层。
处理这类问题,顺序比命令更重要:先判断空间卡在文件系统、进程句柄还是虚拟化层,再选择truncate、重启服务、fstrim或合并快照,只盯着/var/log反复删文件,往往解决不了虚拟机层面的空间账本。
Q&A:虚拟机日志清理后空间没释放怎么办
删除日志后df没变,重启虚拟机有用吗?
重启能释放被进程占用的已删除文件,但不是首选,先用lsof +L1定位PID,重启对应服务更可控,生产虚拟机重启前确认业务窗口和快照状态。
云服务器上清理日志后磁盘空间没减少,是云厂商的问题吗?
多数不是,云盘按块管理,客户机内删除文件不等于后端立即回收;精简置备、快照和备份盘都可能让空间账本滞后,先查df、du、lsof +L1和快照,再提交工单,据主流云厂商公开文档,TRIM/UNMAP支持与实例类型、磁盘类型有关,需以控制台说明为准。
Linux虚拟机日志清理后空间未释放,直接truncate大日志安全吗?
对正在写入的普通文本日志,truncate比rm更稳妥,因为保留inode,进程继续写;但数据库WAL、binlog不要用truncate,要用原生命令,操作前用lsof /var/log/xxx.log确认句柄和属主,若df与du长期不一致,且lsof +L1没有deleted句柄,下一步应检查挂载覆盖、文件系统保留块和虚拟化层快照,而不是继续删除日志。