Ubuntu 24.04 磁盘爆满“灵异“事件:Btrfs, Snapper 与删不掉的空间

Ubuntu 24.04 磁盘爆满"灵异"事件:Btrfs, Snapper 与删不掉的空间

Ultimate Guide: Solving "No Space Left on Device" on Ubuntu 24.04 (Btrfs) - When rm -rf Fails to Free Space

写在前面

2025年末,在配置深度学习环境(CUDA 13.1 + Torch)的过程中,我遭遇了一次极其诡异的**"磁盘假死"**事件。在 df -h 显示根目录 100% 爆满的情况下,我手动删除了近 500GB 的模型权重和缓存,但系统依然提示 No space left on device,导致 GDM 图形界面崩溃、Apt 锁死、SSH 险些断连。

本文记录了在 Ubuntu 24.04 (Btrfs文件系统) 下,如何揪出吞噬硬盘的"幽灵"------Snapper 快照,并彻底解决这一问题的完整链路。


1. 问题现象与环境

硬件与系统环境

  • OS: Ubuntu 24.04.3 LTS
  • Filesystem: Btrfs (默认安装配置)
  • Disk: 1.1T NVMe SSD

故障描述

系统运行中突然由于磁盘写满导致服务雪崩。

  1. 基础服务崩溃zsh 无法写入历史记录,apt 无法更新锁文件,mkdir 报错。
  2. 图形界面挂死systemctl status gdm 显示 Failed to start GNOME Display Manager
  3. 空间悖论
  • 使用 df -h 查看,根目录 / 使用率稳居 100%
  • 使用 rm -rf 删除了 .cache (180G) 和 anaconda3 (140G) 等大目录后,df -h 依然显示 100%,没有任何空间释放。
  • 使用 du -sh /* 统计全盘文件,发现当前可见文件总和远小于磁盘总量(仅用了约 50%)。

关键报错日志

bash 复制代码
# Zsh 报错
zsh: locking failed for /home/lff8888/.zsh_history: 设备上没有空间: reading anyway

# Apt 报错
E: 无法建立临时文件(mkstemp) /tmp/clearsigned.message.eAmY3X (28: 设备上没有空间)

# 日志清理报错
rm: cannot remove 'xxx': No space left on device

2. 核心故障分析 (Root Cause Analysis)

经过排查,这并非传统的"文件未释放占用(deleted but open)",而是 Btrfs 文件系统特性Snapper 自动快照 共同导致的"幽灵占用"。

  1. Btrfs 的 CoW (Copy-on-Write) 机制
    在 Btrfs 文件系统中,删除文件(rm)并不会物理擦除数据块,只要有"快照(Snapshot)"指向这些数据块,它们就会被永久保留在磁盘上。
  2. Snapper 的静默吞噬
    Ubuntu/OpenSUSE 等发行版默认启用了 Snapper 进行系统备份。它可以针对 apt 操作或时间轴(Timeline)自动创建快照。
  • 元凶发现 :通过 sudo snapper list 发现,系统中积累了数千个快照(Timeline 快照保留了长达一年的历史),这些快照完整锁住了我刚才删除的那几百 GB 数据。
  1. Metadata(元数据)耗尽
    Btrfs 需要独立的 Metadata 空间。当快照过多或碎片化严重时,即便 Data 区域有空位,Metadata 满了也会导致文件系统变为 Read-Only 或无法写入,报 No space left on device

3. 解决方案 (Step-by-Step)

第一步:诊断快照堆积

首先确认是否是 Snapper 在作祟。

bash 复制代码
# 查看快照列表
sudo snapper list

如果看到列表中有几千行,且 Type 包含大量的 timelinenumber (apt),那么恭喜你,找到原因了。

第二步:紧急释放空间(批量删除快照)

注意 :在 Btrfs 下,唯有删除快照才能真正释放 rm 操作后的空间。

可以使用范围删除来快速清理(保留最近几天的即可):

bash 复制代码
# 语法:sudo snapper delete [ID范围]
# 例如删除 ID 从 4000 到 5700 的所有旧快照
sudo snapper delete 4000-5700

执行后,系统需要几分钟时间进行后台清理(Btrfs commit)。稍等片刻再次运行 df -h,你会发现空间瞬间"回来"了。

第三步:防止复发(修改 Snapper 策略)

默认的保留策略过于激进(保留数年),对于开发机来说是灾难。必须修改配置文件。

  1. 编辑配置:
bash 复制代码
sudo nano /etc/snapper/configs/root
  1. 修改以下关键参数(建议值):
bash 复制代码
# 限制 APT 操作的快照保留数量(原值可能是 50)
NUMBER_LIMIT="10"

# 限制时间线快照(最关键!原值 YEARLY="10" 会吃光硬盘)
TIMELINE_LIMIT_DAILY="7"    # 保留最近7天
TIMELINE_LIMIT_WEEKLY="2"   # 保留最近2周
TIMELINE_LIMIT_MONTHLY="1"  # 保留最近1个月
TIMELINE_LIMIT_YEARLY="0"   # 关闭年度保留
  1. 应用更改并触发清理:
bash 复制代码
sudo snapper cleanup number
sudo snapper cleanup timeline

第四步:Btrfs 元数据平衡(进阶维护)

为了防止 Metadata 爆满导致的假死,建议定期执行 Balance 操作。

bash 复制代码
# 检查元数据使用情况
sudo btrfs filesystem usage /

# 平衡数据块(回收利用率低于 5% 的块)
sudo btrfs balance start -dusage=5 /

4. 验证与恢复

完成上述操作后,进行最终验证:

  1. 检查空间
bash 复制代码
df -h
# 此时 / 分区使用率应大幅下降,例如从 100% 降至 40%
  1. 恢复图形界面
    空间释放后,GDM 终于可以写入日志并启动了。
bash 复制代码
sudo systemctl restart gdm

总结 (Conclusion)

在现代 Linux 发行版使用 Btrfs 时,传统的运维经验(看到盘满就 rm -rf)往往是无效的。

  1. 警惕快照 :如果 dfdu 数据对不上,第一时间检查 snapper list
  2. 配置调优 :装机后第一时间修改 /etc/snapper/configs/root,关闭 YEARLY 保留策略。
  3. 正确的删除姿势:大文件删除后,必须配合快照清理,空间才会真正释放。

这次"灵异事件"本质上是先进文件系统特性与默认配置不匹配的结果。希望这篇复盘能帮大家守住宝贵的 SSD 空间!

相关推荐
爱尔兰极光2 小时前
计算机网络--网络层
运维·服务器·计算机网络
2401_841495642 小时前
【自然语言处理】关系性形容词的特征
人工智能·python·自然语言处理·自动识别·特征验证·关系性形容词·语言学规则和计算
Neolnfra2 小时前
Xshell SSH 连接故障排查
运维·服务器·网络·ssh·xshell·运程连接
rebekk2 小时前
Hydra介绍
人工智能·python
我不是小upper2 小时前
从理论到代码:随机森林 + GBDT+LightGBM 融合建模解决回归问题
人工智能·深度学习·算法·随机森林·机器学习·回归
极地星光2 小时前
Ubuntu 16.10 启动时 networking.service 缓慢问题
linux·ubuntu
Roadinforest2 小时前
如何使用 keyd 定制 Caps Lock:拯救你坏掉的 Left Control 键(Linux-Ubuntu)
linux·ubuntu
Faker66363aaa2 小时前
CornerNet-Hourglass104生产线检测与分类-1模型训练与部署
人工智能·分类·数据挖掘
MonkeyKing_sunyuhua2 小时前
ubuntu22.04安装nginx
运维·windows·nginx