VMware虚拟机Linux磁盘满清理收缩教程

发布时间:2026-11-09 20:41 最后更新:2026-11-09 20:50 浏览量:共 3 次浏览

VMware 虚拟机 Linux 磁盘满清理 + 虚盘收缩教程

适用系统:Debian / Ubuntu(宝塔面板) 示例现状:168.2GB / 195.8GB,剩余约 27.6G

原理:VMware 精简磁盘不会自动回收已删除文件占用的块。必须在虚拟机内部把空闲区域写 0,关机后在 VMware 执行【压缩】,宿主机磁盘空间才会真正释放。

本版已按宝塔面板环境复核修订:原脚本中会误删 MySQL/PHP 的 socket、填零数据未落盘、终端断开留下满盘文件、面板日志路径写错等问题均已修正。


一、操作前确认(3 件事)

  1. 快照:VMware 里【虚拟机】→【快照】→【快照管理器】,有快照先删除(会合并到当前磁盘)。有快照时压缩不可用或回收不到空间。
  2. 磁盘类型:只有「按需分配(精简置备)」的虚拟磁盘,压缩才有意义。如果创建时勾选了「立即分配所有磁盘空间」,宿主机占用本来就是满的,压缩不会变小。
  3. 分区:本教程只处理 / 所在分区。先执行 df -h,如果 /www、/data 是独立分区,需要对每个分区分别填零。

二、注意事项

  • 填零期间根分区会 100% 占满,面板打不开、MySQL/网站写日志报错,属于正常现象,不要重启虚拟机。
  • 建议在业务低峰期执行。如果数据库写入不能中断,可以先在面板里停止 MySQL,填零完成后再启动。
  • 必须【正常关机】,暂停状态无法压缩磁盘。
  • 填零时出现 No space left on device 是预期报错,属于正常现象。
  • 宝塔 Web 终端断开不会中断填零(脚本已放后台);如果虚拟机断电或被强制关机,重新登录后第一时间执行 rm -f /zero.fill。

三、步骤 1:查看占用

宝塔面板左侧【终端】执行(root):

df -h /
du -sh /* 2>/dev/null | sort -rh | head -15
du -sh /www/wwwlogs /www/backup /www/server/data 2>/dev/null

宝塔机器常见的大头:

  • /www/wwwlogs:站点访问/错误日志
  • /www/backup:站点/数据库备份(确认后再删)
  • /www/server/data:MySQL 数据 + binlog(不要直接 rm)
  • /var/log、/var/lib/docker(有 Docker 时)

能手动清的先清,空闲空间越大,后面越稳。

可选:清空站点日志(会丢失历史访问记录)

# 清空全部站点日志(保留文件,nginx 可以继续写入)
find /www/wwwlogs -maxdepth 1 -type f -name "*.log" -exec truncate -s 0 {} \;
# 删除已轮转的旧日志
find /www/wwwlogs -maxdepth 1 -type f \( -name "*.log.gz" -o -name "*.log.1" \) -delete

MySQL binlog 很大时不要用 rm,用 PURGE(root 密码可在面板【数据库】页面查看):

mysql -uroot -p -e "PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 3 DAY);"

四、步骤 2:创建脚本

在宝塔终端一次性粘贴下面整段(包含结尾的 EOF),会在 /root 生成 vm-shrink.sh:

cat > /root/vm-shrink.sh <<'EOF'
#!/bin/bash
# VMware 虚拟机 Linux 磁盘清理 + 空闲空间填零(宝塔面板版)
# 适用:Debian / Ubuntu,root 执行
# 用法:
#   bash /root/vm-shrink.sh status   查看占用
#   bash /root/vm-shrink.sh clean    安全清理(可选)
#   bash /root/vm-shrink.sh fill     后台填零

case "$1" in
  status)
    echo "【根分区】"
    df -h /
    echo
    echo "【根目录占用 TOP 15】"
    du -sh /* 2>/dev/null | sort -rh | head -15
    echo
    echo "【宝塔常见大目录】"
    du -sh /www/wwwlogs /www/backup /www/server/data 2>/dev/null
    ;;

  clean)
    echo "---- 清理前 ----"
    df -h /
    apt clean 2>/dev/null
    journalctl --vacuum-size=50M 2>/dev/null
    # 只删 3 天前的普通文件;-type f 不会删掉 /tmp 下的 mysql.sock、php-cgi-*.sock
    find /tmp /var/tmp -maxdepth 1 -type f -mtime +3 -delete 2>/dev/null
    # 宝塔面板日志:新版目录是 logs,老版是 log
    rm -rf /www/server/panel/logs/* /www/server/panel/log/* 2>/dev/null
    echo "---- 清理后 ----"
    df -h /
    ;;

  fill)
    if [ -e /zero.fill ]; then
        echo "已存在 /zero.fill,请先执行:rm -f /zero.fill"
        exit 1
    fi
    echo "---- 后台开始填零 ----"
    # nohup + setsid:关闭宝塔终端不会中断;结束后自动 sync 并删除填充文件
    nohup setsid bash -c 'dd if=/dev/zero of=/zero.fill bs=1M; sync; rm -f /zero.fill; echo ZERO_FILL_DONE' > /root/zero_fill.log 2>&1 &
    echo "已启动。查看进度:df -h /    或    du -h /zero.fill"
    echo "结束标志:cat /root/zero_fill.log 出现 ZERO_FILL_DONE"
    ;;

  *)
    echo "用法:bash $0 {status|clean|fill}"
    ;;
esac
EOF

小提示:粘贴后如果还停在 > 提示符,说明结尾的 EOF 没粘上,手动输入 EOF 回车即可。

也可以用【文件】→ 进入 /root → 新建文件 vm-shrink.sh → 粘贴内容 → 保存。


五、步骤 3:安全清理(可选)

bash /root/vm-shrink.sh clean

做四件事:

  • 清 apt 缓存;
  • 收缩 systemd 日志;
  • 只删除 /tmp、/var/tmp 下 3 天前的普通文件(不会动 socket,宝塔的 mysql.sock、php-cgi-*.sock 安全);
  • 清空宝塔面板自身日志(logs / log 两个路径都尝试)。

不会碰:站点日志、网站备份、数据库文件。


六、步骤 4:后台填零

bash /root/vm-shrink.sh fill

提醒:如果数据库写入不能中断,建议先在面板【软件商店】→【MySQL】→【停止】,填零完成后再启动(见第二节注意事项)。

脚本会把 dd 放到后台(nohup setsid),关掉宝塔终端、关浏览器都不会中断。

查看进度:

df -h /
du -h /zero.fill
  • 可用空间接近 0 表示快写满了,属于正常;
  • 写满后脚本会自动 sync、删除 /zero.fill,并在日志里写入 ZERO_FILL_DONE:
cat /root/zero_fill.log

看到 ZERO_FILL_DONE 表示填零结束、填充文件已删除。

中途中止填零(如临时有事需要停止):

pkill -f "of=/zero.fill" && rm -f /zero.fill

执行后填零立即停止、空间立即释放,可以正常继续其他操作;之后想继续填零,重新执行一次 bash /root/vm-shrink.sh fill 即可。


七、步骤 5:确认

ls -l /zero.fill      # 应提示 No such file
df -h /               # 可用空间应恢复到 20G 以上(取决于清理掉了多少)

八、步骤 6:正常关机

在终端执行:

shutdown -h now

或 VMware 菜单【虚拟机】→【电源】→【关闭客户机】。

不要用「暂停」,暂停状态不能压缩磁盘。


九、步骤 7:VMware 压缩

  1. 确认虚拟机已完全关机;
  2. VMware 选中虚拟机 →【编辑虚拟机设置】→【硬盘】→ 右侧【磁盘实用工具】→【压缩】;
  3. 等待完成,期间不要打断。

如果【压缩】是灰的:检查是否真的关机、是否有快照、磁盘是否为独立磁盘。


十、步骤 8:开机验证

  • 虚拟机内 df -h /:容量不变(还是 195.8G),但可用空间变多;
  • 宿主机上查看该虚拟机目录里的 .vmdk 文件,体积应明显变小。

压缩只回收宿主机磁盘占用,不会缩小虚拟机内的分区容量。


十一、兜底:终端断开 / 中途断电

如果因为强制关机、宿主机断电等原因留下了填充文件:

rm -f /zero.fill

rm 只是删除文件,不需要额外空间,执行后空间立即释放。


十二、附:本次修订说明(原脚本的问题)

  1. 交互式 read 不能直接粘贴执行:终端是逐行交给 shell 的,read 会把后面粘贴的 if [[ ... ]] 当成输入,选项失效。改为 status / clean / fill 子命令,不需要交互。
  2. rm -rf /tmp/* 是宝塔上的高风险操作:宝塔的 PHP-FPM socket(/tmp/php-cgi-*.sock)和 MySQL socket(/tmp/mysql.sock)都在 /tmp,删掉后网站 502、面板连不上数据库。改为只删 3 天前的普通文件(-type f 不会匹配 socket)。
  3. 面板日志路径写错:宝塔实际是 /www/server/panel/logs,原脚本的 /www/server/panel/log 通常不存在;已同时兼容。
  4. 漏掉真正的大头:站点日志 /www/wwwlogs、备份 /www/backup、MySQL binlog 才是宝塔机器最常见的空间占用,原脚本没有处理;已补充查看命令和安全清理方式。
  5. **dd 后缺少 sync**:数据可能还在内存里就被 rm 掉,末尾一段空闲块实际没写零,VMware 压缩回收不到。改为 dd → sync → rm。
  6. 宝塔 Web 终端断开会杀掉 dd:留下写满的 /zero.fill,根分区 100% 满。改为 nohup setsid 后台执行,断终端不影响,并在结束后自动清理。
  7. 补上压缩前提:快照必须先删、磁盘必须是按需分配、虚拟机必须完整关机;压缩不改变虚拟机内的分区容量。

 

【END】

相关文章

如何修改宝塔下的哪个JAVA项目重启服务器时不自动启动JAVA项目
关于 PowerShell 的中文乱码问题
大白MYSQL8。0。36
密码保护:Debian 12.13下如何实现自动备份防黑客方法一例
JVM调优后备份
Debian 12 中文系统 锁定了 locale 配置文件