还有空间却建不了文件的原因
一句话总结
存储由块设备 → 分区 → 文件系统 → 挂载四个层次叠加而成。出故障时,首先要做的是判断症状属于哪一层,仅这一步判断就能把候选原因缩小到四分之一。
为什么需要它
df -h 显示还剩 35GB,可一个 touch 却因 No space left on device 而失败。这时很容易得出“监控有问题”的结论,但 df 只是如实报告了块的使用量。这个错误是 errno 28,而内核返回这个值的路径,除了块不足之外还有好几条。
最常见的是 inode 耗尽。每个文件除了数据块之外,还要占用一个存放元数据的 inode。ext4 的 inode 数量在创建文件系统时就已固定,所以一旦积累了大量极小的文件,即使块还有剩余,inode 也会先用光。用 df -i 确认,只要 IUse% 为 100,答案就出来了。inode 数量无法增加,只能删除文件或重新创建文件系统。会话文件、积压的邮件队列和没人清理的临时文件是常见的罪魁祸首。
接下来的几种候选原因也值得了解。已删除但仍被打开的文件——目录项已经消失,所以 du 找不到它,但进程还开着它,块不会被归还。这是 df 和 du 结果对不上的最常见原因。保留块——ext 系列默认会留出一定比例专供 root 使用。挂载遮盖——在已有文件的目录上挂载另一个文件系统后,下面的文件虽然看不见,却仍然占着空间。
此外,诊断之前还有一项值得花 30 秒的确认:写入的真的是那个文件系统吗? 最常见的错误是不带参数运行 df -h,扫一眼列表就凭感觉下结论。直接用 findmnt -T <경로> 询问那个路径实际属于哪个设备,就能立刻发现真正写满的不是 /,而是单独分区 /var 的情况。/tmp 是 tmpfs 的环境也很常见,这里写满时即使与磁盘无关也会出现同样的错误,而且会同等占用物理内存。
工作原理
/etc/fstab 的六个字段。
| 编号 | 字段 | 说明 |
|---|---|---|
| 1 | 设备 | UUID、LABEL 或设备路径 |
| 2 | 挂载点 | 要挂载到的目录 |
| 3 | 文件系统类型 | ext4、xfs、nfs 等 |
| 4 | 选项 | defaults、noatime、nofail 等 |
| 5 | dump | 供备份工具使用,通常为 0 |
| 6 | fsck 顺序 | 根分区为 1,其余为 2,不检查为 0 |
使用 UUID 的原因是设备名并不稳定。/dev/sdb 是内核按发现设备的顺序分配的名称,所以增加一块磁盘或更换控制器后,另一块磁盘可能会拿走这个名称。这样一来,fstab 语法上完好无损,却会挂载错误的设备。UUID 写在文件系统里,无论设备插在哪里都会跟着走。
选项中的 nofail 尤其实用。没有它时,一旦那个设备不存在,启动就会落入紧急模式。外置磁盘或网络存储的条目通常都要加上。
LVM 解决的问题。 分区是在磁盘上划出固定边界的方式,以后想扩大,就要求后面紧邻着空闲空间。LVM 把多个物理卷(PV)收集到名为卷组(VG)的池中,再从池中切出逻辑卷(LV)来使用。因此可以创建横跨多块磁盘的单个卷,也可以在添加磁盘、扩充池之后在线扩展卷。快照也来自这一层。
RAID 级别由需求决定。 RAID 0 只提供性能和容量,完全没有冗余(坏一块磁盘就全部丢失)。RAID 1 是原样复制,很安全,但容量只剩一半。RAID 5 用一份奇偶校验就能承受一块磁盘故障,容量效率也好,但重建期间必须读取其余所有磁盘,此时若再坏第二块就彻底完了。磁盘越大,重建时间越长,这个风险也就越大。RAID 10 对镜像做条带化,换来写入性能和重建安全性,代价是牺牲一半容量。而且任何 RAID 都不是备份。 RAID 是用来承受硬件故障的机制,无法找回被误删的文件。
在现场相遇的样子
在作者遇到的案例中,Avail 是 35GB,却连一个 0 字节的文件都创建不了。按顺序检查,5 分钟就能找出原因——先确定该路径所属的文件系统,用 df -i 查看 inode,查找已删除但仍被打开的文件,再检查保留块和挂载遮盖。把这个顺序背下来很有价值。同样的错误提示可能来自多种原因,只看提示就凭空猜测,每次都会走上不同的岔路。
df 和 du 对不上时,第一个候选原因也总是相同:已被删除但仍被进程占着的文件。最安全的释放方式不是重启服务,而是发送让它重新打开日志文件的信号,其次的手段才是直接清空文件描述符。之所以要遵守这个顺序,是因为重启会把当时的诊断信息全部丢掉。
下一项测验要确认什么
这个实验环境中,mount、umount、mkfs、fdisk、parted、pvcreate、swapon 之类的命令全部被禁用。这是因为容器已被移除内核 capability,无法真正创建或挂载文件系统。所以本模块专注于概念与判断标准。说实话,存储在 LFCS 中必须亲手做才能熟练——因此紧随其后的模块(在真正的 VM 中亲自操作 LVM、mkfs、mount、swap、NFS、autofs 的实验)才是练习的地方。这里先牢牢掌握层次结构、df 与 du 的区别、inode 耗尽的诊断顺序、fstab 各字段的含义和使用 UUID 的原因,以及 LVM 和 RAID 的选择标准,并通过测验检验。