4

磁盘管理

·16 分钟

1.3 磁盘管理

写在前面

服务器很卡。

我第一反应是看 CPU 和内存,结果都正常。后来才发现:根目录 96% 爆满

/dev/nvme0n1p2  457G  416G   18G   96% /

只剩 18G 可用,难怪系统卡。

但我不知道是什么占了这么多空间,也不知道该怎么安全地清理。于是我决定系统学一下磁盘管理,顺便记录下这次排查过程。

最终结果:从 96% 清理到 71%,释放了 109GB


df — 看整体使用情况

我之前只会 df -h,知道它能看磁盘使用率,但不知道 df 是什么缩写。

df = Disk Free,查看文件系统级别的空间使用。

⭐ 最常用写法

df -h          # 看所有磁盘使用情况
df -h /        # 只看根目录

其他参数(了解)

df -T          # 显示文件系统类型
df -i          # 查看 inode 使用(小文件太多会爆这个)

💡 记忆df = Disk Free,看"还剩多少"


du — 看目录大小

知道磁盘满了,但不知道是谁占的。这时候需要 du

du = Disk Usage,统计目录/文件的实际大小。

⭐ 最常用写法

# 看单个目录总大小
du -sh /path

# 看根目录下各目录大小(排序)
sudo du -h --max-depth=1 / 2>/dev/null | sort -hr | head -20

命令拆解

sudo du -h --max-depth=1 / 2>/dev/null | sort -hr | head -20
│     │  │      │        │ │          │ │      │  │
│     │  │      │        │ │          │ │      │  └─ 只显示前20行
│     │  │      │        │ │          │ │      └─ reverse,降序
│     │  │      │        │ │          │ └─ 按人类可读数字排序
│     │  │      │        │ │          └─ 管道
│     │  │      │        │ └─ 丢弃权限错误信息
│     │  │      │        └─ 扫描根目录
│     │  │      └─ 只统计1层,不递归展开
│     │  └─ human readable
│     └─ disk usage
└─ 管理员权限

df vs du 的区别

命令看什么类比
df文件系统总体使用看水桶还剩多少容量
du具体目录/文件大小看桶里每样东西多重

两者数值可能不一致!比如有进程占用了已删除的文件,df 会算进去但 du 看不到。

💡 记忆df = Free(剩余),du = Usage(使用)


lsblk — 看磁盘设备

我还用到了 lsblk 来看有哪些硬盘和分区。

lsblk = List Block devices

⭐ 最常用写法

lsblk          # 树形显示所有块设备
lsblk -f       # 显示文件系统类型和 UUID

示例输出:

NAME        SIZE  TYPE  MOUNTPOINT
sda         1.8T  disk  /data2
sdb         1.8T  disk  /data1
nvme0n1   465.8G  disk  
├─nvme0n1p1 512M  part  /boot/efi
├─nvme0n1p2 465G  part  /          ← 根目录在这
└─nvme0n1p3   1M  part  
nvme1n1     1.8T  disk  /data

一眼就能看出:根目录 /nvme0n1p2 上,和 /data 是不同的硬盘。


实战:定位大文件

跑完 du 后,我发现 /root 目录居然有 25GB!正常应该很小。

sudo du -h --max-depth=1 /root | sort -hr

结果找到了元凶:

25G     /root
-rw-r--r--  1 root root  4294967296 12月 25  2019 swapfile     # 4GB
-rw-r--r--  1 root root 21474836480 12月 26  2019 swapfile1    # 20GB

两个 2019年创建的废弃 swap 文件,占了 24GB!

小测验

问:为什么 /root 里会有 swap 文件?

答:推测是 2019 年跑深度学习时内存不够,临时创建的。后来忘了删,一放就是 5 年。


Swap 交换区

既然遇到了 swap 问题,顺便学一下。

什么是 Swap?

当物理内存不够时,系统把不活跃的数据暂时"换出"到磁盘。

┌─────────────────────────────────────────┐
│            物理内存 (RAM)                │
│  程序A │ 程序B │ 程序C │ ... │  ← 快满了 │
└─────────────────────────────────────────┘
                    │
                    ▼ 把不活跃的数据挪到磁盘
┌─────────────────────────────────────────┐
│            Swap 交换区 (磁盘)            │
│       不活跃的数据暂存在这里              │
└─────────────────────────────────────────┘

⭐ 最常用写法

# 查看 swap 状态
swapon --show
free -h

# 关闭某个 swap
sudo swapoff /path/to/swapfile

# 启用 swap
sudo swapon /path/to/swapfile

Swap 大小建议

物理内存推荐 Swap
≤ 2GB2 倍内存
2-8GB等于内存
8-64GB4-8GB
> 64GB4GB 或更少

我的服务器有 94GB 内存,保留 2GB swap 就够了,26GB 纯属浪费。

Swappiness 参数

控制系统使用 swap 的倾向(0-100):

# 查看当前值
cat /proc/sys/vm/swappiness

# 临时修改(内存大的机器建议调低)
sudo sysctl vm.swappiness=10

# 永久修改
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf

💡 记忆:swappiness 越高,越爱用 swap。内存大就调低,减少磁盘 IO。


/etc/fstab — 开机自动挂载

清理 swap 文件时,我发现它们被写在了 /etc/fstab 里。如果只删文件不改 fstab,重启会报错。

fstab = File System Table,开机自动挂载配置。

文件格式

<设备>          <挂载点>    <类型>  <选项>      <dump>  <pass>
字段含义
设备UUID=xxx 或 /dev/xxx
挂载点挂载到哪个目录
类型ext4, swap, vfat 等
选项defaults, noatime 等
dump0=不备份(基本没人用)
passfsck 检查顺序(根目录=1,其他=2,0=不检查)

示例

# 系统盘(用 UUID 更稳定)
UUID=346b4f3f-... /           ext4  errors=remount-ro 0 1

# 数据盘
/dev/sdb          /data1      ext4  defaults         0 2

# Swap
/swapfile         none        swap  sw               0 0

⚠️ 修改 fstab 的注意事项

fstab 写错会导致系统无法启动!

# 修改前先备份
sudo cp /etc/fstab /etc/fstab.bak

# 修改后验证(不重启测试)
sudo mount -a

# 如果报错,立刻改回来!

磁盘挂载

既然学到 fstab,顺便整理一下磁盘挂载的完整流程。

挂载流程

新硬盘 → 分区 → 格式化 → 创建挂载点 → 挂载 → 写入 fstab

⭐ 完整步骤

# 1. 查看磁盘
lsblk

# 2. 分区(如果需要)
sudo fdisk /dev/sdb
# n(新建) → p(主分区) → 回车 → 回车 → w(写入)

# 3. 格式化
sudo mkfs.ext4 /dev/sdb1

# 4. 创建挂载点
sudo mkdir -p /data

# 5. 临时挂载
sudo mount /dev/sdb1 /data

# 6. 写入 fstab(永久挂载)
echo '/dev/sdb1  /data  ext4  defaults  0  2' | sudo tee -a /etc/fstab

# 7. 验证
sudo mount -a
df -h

小测验

问:为什么 pass 值用 2 而不是 1?

答:1 只用于根分区(最先检查),其他分区用 2(根分区检查完后再检查),0 表示不检查。


清理实战

回到本章节对应的项目:发现一台服务器的根目录爆满,如何清理呢?

1. 清理废弃 swap 文件(释放 24GB)

# 先检查是否在使用
swapon --show

# 关闭
sudo swapoff /root/swapfile
sudo swapoff /root/swapfile1

# 删除文件
sudo rm /root/swapfile /root/swapfile1

# 编辑 fstab,删除对应行
sudo nano /etc/fstab

2. 清理 apt 缓存

sudo apt clean           # 清理下载的 deb 包
sudo apt autoremove -y   # 删除不需要的依赖

3. 清理系统日志

# 查看日志占用
sudo journalctl --disk-usage

# 只保留 500MB
sudo journalctl --vacuum-size=500M

4. 清理 snap 旧版本(释放 10GB+)

Snap 默认保留旧版本用于回滚,时间长了会堆积。

# 查看旧版本
snap list --all | grep disabled

# 删除单个
sudo snap remove core18 --revision 2959

# 批量删除所有旧版本
sudo snap list --all | awk '/disabled/{print $1, "--revision", $3}' | xargs -n3 sudo snap remove

5. 用户缓存(可选)

du -sh ~/.cache
rm -rf ~/.cache/*    # 通常安全,但某些程序可能需要重建缓存

安全删除的教训

清理过程中我手滑删了一个 72GB 的数据集,本来应该移动到 /data 备份的,还好最后发现是冗余文件...

Linux 的 rm 是真删除!

没有回收站,删了就是删了。恢复很难。

更安全的做法

# 方法1:先移动到"待删除"目录,观察几天
mv ~/some-file /data/to_delete/

# 方法2:用 trash-cli
sudo apt install trash-cli
trash-put ~/some-file    # 进回收站
trash-list               # 查看回收站
trash-restore            # 恢复

💡 经验:删大文件前,先 du -sh 确认大小,再 ls 看看内容。不急的话用 mv 代替 rm


意外收获:重启解决内存问题

清理完磁盘后重启,发现服务器比之前流畅多了。对比:

指标重启前重启后
空闲内存596MB71GB
Swap 使用530MB0
系统负载1.350.09

原来服务器之前跑了 119 天没重启,NoMachine 进程内存泄漏到 10GB...

💡 经验:服务器每 1-3 个月重启一次,清理累积的系统状态。


本节小结

命令速查表

任务命令
查看磁盘使用df -h
查看目录大小du -sh /path
查看一层子目录du -h --max-depth=1 /path | sort -hr
查看块设备lsblk
查看 swapswapon --showfree -h
验证 fstabsudo mount -a
清理 aptsudo apt clean && sudo apt autoremove
清理日志sudo journalctl --vacuum-size=500M
清理 snapsnap list --all | grep disabled

踩过的坑

  1. rm 是真删除,没有回收站,删大文件前要三思
  2. 改 fstab 要谨慎,写错会导致系统无法启动
  3. swap 文件删了要改 fstab,否则重启报错
  4. 服务器太久不重启,会有内存泄漏等问题累积

学到的概念

  1. df vs du:df 看文件系统总体,du 看具体目录大小
  2. Swap:用磁盘临时充当内存,内存大的机器不需要太多
  3. fstab:开机自动挂载配置,格式是 设备 挂载点 类型 选项 dump pass
  4. swappiness:控制系统使用 swap 的倾向,内存大就调低

番外:重启后的一波三折

⚠️ 以下内容与磁盘管理无关,但既然是同一天踩的坑,就一起记录了。

翻车现场

清理完磁盘,我执行了 sudo reboot

然后... ping 不通了

我人不在机房,心态崩了。

第一个坑:重启慢

其实没事。服务器 119 天没重启,开机要做 fsck 磁盘检查,几个 TB 的硬盘检查起来很慢。

💡 经验:重启后 ping 不通,先等 10 分钟,可能只是启动慢。

第二个坑:登录循环

第二天去机房,发现服务器起来了。但输入正确密码后:

黑屏 → 闪一下 → 又回到登录界面

这是经典的 X11 登录循环问题,通常是 .Xauthority 文件出了问题。

修复方法

# 1. 切换到文字终端(TTY)
Ctrl + Alt + F3

# 2. 命令行登录
用户名: username
密码: xxxxxx

# 3. 删除问题文件
rm ~/.Xauthority

# 4. 重启图形界面
sudo systemctl restart gdm
# 或者直接重启
sudo reboot

💡 知识点.Xauthority 是 X11 的认证文件,损坏或权限不对会导致无法进入桌面。删掉后系统会自动重建。

TTY 终端

Ctrl + Alt + F1~F6 可以切换到不同的 TTY(文字终端),F1F7 通常是图形界面。

这是救命技能——图形界面挂了,还能用 TTY 进去修复。

Ctrl + Alt + F1   # 图形界面(Ubuntu 默认)
Ctrl + Alt + F3   # TTY3(文字终端)
Ctrl + Alt + F4   # TTY4
...

顺便:用户管理

修好后我顺便帮自己改了密码,学了几个命令:

# 修改其他用户密码(需要 sudo)
sudo passwd [user]

# 查看谁有 sudo 权限
getent group sudo

# 给用户添加 sudo 权限
sudo usermod -aG sudo [user]

为什么不推荐直接改 /etc/sudoers?

# ❌ 危险操作
sudo nano /etc/sudoers

# ✅ 安全操作(有语法检查)
sudo visudo

visudo 保存时会检查语法,写错了不让保存。直接编辑 sudoers 写错的话,所有人都无法 sudo,只能进 recovery 模式修复。

这一天的完整时间线

发现服务器卡 → df -h 发现 96% 
    → du 定位大文件 → 清理 swap/snap/日志 
    → 释放 109G → 开心地 sudo reboot 
    → 💀 ping 不通 → 去睡觉
    → 第二天去机房 → 登录循环 💀
    → Ctrl+Alt+F3 救命 → 删 .Xauthority 
    → 修复成功 ✅ → 顺便改密码
    → 终于可以继续其它工作了...

💡 总结:debug就是这样,解决一个问题,冒出三个新问题。但每个坑都是学习机会。