100g大小的洋垃圾硬盘?或许没人在意服务器运维
新机器明明有大盘,df 却只看到 100G。记录一次 LVM 扩容排障:从 df 的错觉,到适合深度学习工作站的磁盘布局。
磁盘去哪了:把 Ubuntu 根分区从 100G 扩到 1T#
新机器装好 Ubuntu,CUDA 正常,NVIDIA 驱动正常,nvidia-smi 也正常。
按理说这时候应该开始配环境、拉数据、跑实验。结果还没正式开工,先被一个更朴素的问题拦住了:
df -hbash根分区 / 只有 100G。
这就很怪。机器不是小硬盘,导很有钱不太可能会画时间去淘洋垃圾玩。100G 放系统当然够,也有对应的数据盘但人一多,很快就会变成一个倒计时。
更糟的是,这种问题特别容易被误判成“磁盘不够”。实际上磁盘够,只是系统没有把空间交到你正在用的文件系统手里。
df 看到的不是磁盘大小#
很多人一看到空间问题,本能反应df去抓内鬼,看看谁把checkpoints或者数据集放系统盘上了:
df -hbash我也一样。
但 df 回答的问题很窄:当前已经挂载的文件系统,各自还有多少空间。
它不负责告诉你:
- 物理磁盘到底多大
- 分区有没有覆盖整块盘
- LVM 里还剩多少没分配
- 有没有分区创建了但没有挂载
所以 df -h 只看到 / 是 100G,并不能推出“这台机器只有 100G”。它只能说明:当前挂载到 / 的那个文件系统是 100G。
这句话听起来像绕口令,但排障时很要命。因为 Linux 的存储不是一层,而是一串叠起来的抽象。
从底下往上看,空间卡在哪一层#
我后来不再盯着 df,而是按层往上拆。
第一层是块设备:
lsblk -o NAME,SIZE,FSTYPE,TYPE,MOUNTPOINTSbash这一层只看系统有没有识别到盘。你能看到 /dev/sda、/dev/nvme0n1,以及它们的总容量。这里如果已经只剩 100G,那才是真的没盘。
第二层是分区:
sudo parted /dev/nvme0n1 printbash或者:
sudo fdisk -lbash这里看的是分区表。很常见的一种情况是:磁盘本身有几 T,但某个分区只切了几百 G,后面还有大片 unallocated 空间。那就不是文件系统问题,而是分区没有扩到位。
第三层是 LVM,也是这次真正出问题的地方:
sudo pvs
sudo vgs
sudo lvsbashLVM 会把磁盘空间分成几个概念:
- PV:被 LVM 接管的物理卷
- VG:把一个或多个 PV 合在一起的卷组
- LV:真正拿去格式化、挂载、给系统用的逻辑卷
我的情况就是:大部分空间已经在 VG 里,但只给根分区对应的 LV 分了 100G。
空间没有消失。它只是躺在 VG 的 free extents 里,没有分配给 /。
最后一层才是文件系统和挂载点:
df -h /
mount | grep ' / 'bash只有某个分区或 LV 被格式化、挂载之后,df 才能看到它。也就是说,df 是结果视图,不是全局地图。
为什么新装 Ubuntu 会只给 / 100G#
这不是 Ubuntu 坏,也不是安装器发疯。
在服务器或多用户环境里,默认不给根分区吃完整块盘,其实有一定道理:系统盘、用户数据、服务数据、备份空间都可能要分开管理。LVM 留空还能让管理员后续按需扩容。
问题在于,深度学习工作站不是这种使用方式。
单用户科研机器上,很多东西都会不知不觉长在 / 下面:
/usr/local/cuda/opt/var/lib/docker~/.cache/pip~/.cache/huggingface~/.cache/torch- conda 环境和编译缓存
如果 /home 没有单独挂载,那用户缓存也在根分区里。即使 /home 单独挂了,Docker 和系统级依赖仍然会持续吃 /。
扩容前先确认自己是哪种情况#
不要看到这篇文章就直接复制扩容命令。磁盘问题最怕设备名不一样、层级不一样。
扩容前至少确认两件事。
第一,空间到底在 VG 里,还是还没进分区。
如果 sudo vgs 里能看到大量 VFree,说明空间已经在 LVM 的卷组里,只是还没分给 LV。这个最简单。
如果 vgs 里没空闲,但 parted 能看到磁盘后面有 unallocated 空间,那要先扩分区,再让 PV 识别新增空间。
常见流程类似这样,设备名必须按实际机器改:
sudo growpart /dev/nvme0n1 3
sudo pvresize /dev/nvme0n1p3bash第二,根分区对应的是哪个 LV。
可以用:
lsblk -f
sudo lvs -a -o +devicesbashUbuntu 常见名字可能是:
/dev/mapper/ubuntu--vg-ubuntu--lvtext但这不是标准答案。你的机器可能完全不同。
把 / 从 100G 扩到 1T#
确认空间就在 VG 里之后,真正扩容的命令反而很短:
sudo lvextend -r -l +100%FREE /dev/mapper/ubuntu--vg-ubuntu--lvbash这里有两个参数值得单独说。
-l +100%FREE 表示把当前 VG 里剩余的空闲 extent 全部分给这个 LV。
-r 表示扩完 LV 后顺手扩文件系统。没有它的话,底层逻辑卷变大了,文件系统不一定跟着变大,df -h 可能还是原来的数值。
扩完之后再确认:
df -h /bash这次 / 从 100G 变成了 1T。
到这里问题才算真正解决。
根分区变大,会不会变慢#
扩之前我也犹豫过:把 / 扩到1 T,会不会让系统变慢?
结论是:正常使用下不会。
现代文件系统不是从头扫到尾找文件。以 ext4 为例,它有 block group、extent、目录索引这些机制。性能更受这些因素影响:
- 小文件数量
- 目录组织
- I/O 模式
- 磁盘本身性能
- 是否接近满盘
总容量从 100G 变成 1T,不会让每次访问都线性变慢。
真正拖慢系统的,反而是长期接近满盘。空间太紧时,包解压失败、Docker layer 写一半、pip wheel 缓存损坏、日志刷不进去,错误会变得又碎又难查。
所以对工作站来说,大根分区不是浪费,而是减少环境维护成本。
为什么会发生#
我研二才发现这个问题,稍微想了下大概原因是机器学习人的主线是做实验发paper,这种运维相关的基本上都不会深究。机器基本上能跑就行,然后我看了下其他的三个机器,基本上都是这样,有两台系统甚至安装到了数据盘,然后那个1t的固态根本没用。emmmm 扩容下假装看不见吧,论文都没搞完,搞完再说。